Afficher l'historique des modifications d'un fichier à l'aide du contrôle de version Git


3091

Comment puis-je voir l'historique des modifications d'un fichier individuel dans Git, les détails complets avec ce qui a changé?

Je suis allé jusqu'à:

git log -- [filename]

qui me montre l'historique de validation du fichier, mais comment puis-je obtenir le contenu de chacune des modifications de fichier?

J'essaie de faire la transition de MS SourceSafe et qui était un simple right-clickshow history.


41
Le lien ci-dessus n'est plus valide. Ce lien fonctionne aujourd'hui: Git Community Book
chris

1
Le lien ci-dessus (publié par Chris) n'est plus valide. Ce lien fonctionne aujourd'hui: git-scm.com/book/en/v2
Cog

Réponses:


2369

Pour cela, j'utiliserais:

gitk [filename]

ou pour suivre les noms de fichiers passés

gitk --follow [filename]

28
Mais j'ai même plutôt un outil qui combine ce qui précède avec 'git blame' me permettant de parcourir la source d'un fichier au fur et à mesure qu'il change dans le temps ...
Egon Willighagen

26
Malheureusement, cela ne suit pas l'historique du fichier renommé.
Dan Moulding du

146
Je cherchais également l'historique des fichiers précédemment renommés et j'ai trouvé ce fil en premier. La solution consiste à utiliser "git log --follow <filename>" comme Phil l'a souligné ici .
Florian Gutmann

115
L'auteur recherchait un outil en ligne de commande. Bien que gitk soit livré avec GIT, ce n'est ni une application en ligne de commande ni une interface graphique particulièrement bonne.
mikemaccana

72
Cherchait-il un outil en ligne de commande? "clic droit -> afficher l'historique" ne signifie certainement pas cela.
hdgarrood

2236

Vous pouvez utiliser

git log -p filename

pour laisser git générer les correctifs pour chaque entrée de journal.

Voir

git help log

pour plus d'options - il peut en fait faire beaucoup de belles choses :) Pour obtenir juste le diff pour un commit spécifique, vous pouvez

git show HEAD 

ou toute autre révision par identifiant. Ou utiliser

gitk

pour parcourir visuellement les modifications.


8
git show HEAD affiche tous les fichiers, savez-vous comment suivre un fichier individuel (comme Richard le demandait)?
Jonas Byström

5
vous utilisez: git show <revision> - nom de fichier, qui montrera les différences pour cette révision, au cas où il en existe une.
Marcos Oliveira

4
--stat est également utile. Vous pouvez l'utiliser avec -p.
Raffi Khatchadourian

5
C'est bien. gitk ne se comporte pas bien lors de la spécification de chemins qui n'existent plus. J'ai utilisé git log -p - path.
Paulo Casaretto

6
De plus, gitk semble avoir été construit par le monstre boogie. Il s'agit d'une excellente réponse et mieux adaptée à la question d'origine.
ghayes

1499

git log --follow -p -- path-to-file

Cela montrera tout l' historique du fichier (y compris l'historique au-delà des renommages et avec des différences pour chaque changement).

En d'autres termes, si le fichier nommé bara déjà été nommé foo, alors git log -p bar(sans l' --followoption) n'affichera que l'historique du fichier jusqu'au moment où il a été renommé - il n'affichera pas l'historique du fichier lorsqu'il était appelé foo. L'utilisation git log --follow -p baraffichera l'historique complet du fichier, y compris toutes les modifications apportées au fichier lorsqu'il était connu sous le nom foo. L' -poption garantit que les différences sont incluses pour chaque modification.


18
--stat est également utile. Vous pouvez l'utiliser avec -p.
Raffi Khatchadourian

23
Je suis d'accord que c'est la VRAIE réponse. (1.) --followgarantit que vous voyez les renommages de fichiers (2.) -pgarantit que vous voyez comment le fichier est modifié (3.) il s'agit uniquement de la ligne de commande.
Trevor Boyd Smith

3
@NHDaly J'ai remarqué que l'a --été ajouté, mais je ne sais pas pourquoi cela le rend meilleur? Qu'est-ce que ça fait?
Benjohn

40
@Benjohn L' --option indique à Git qu'elle a atteint la fin des options et que tout ce qui suit --doit être traité comme un argument. Car git logcela ne fait de différence que si vous avez un nom de chemin commençant par un tiret . Supposons que vous vouliez connaître l'historique d'un fichier qui porte le nom malheureux "--suivre":git log --follow -p -- --follow
Dan Moulding

10
@Benjohn: Normalement, le --est utile car il peut également se prémunir contre tous les revisionnoms qui correspondent au nom de fichier que vous avez entré, ce qui peut en fait être effrayant. Par exemple: si vous aviez à la fois une branche et un fichier nommé foo, git log -p fooafficherait l'historique du journal git jusqu'à foo, pas l'historique du fichier foo . Mais @DanMoulding a raison de dire que puisque la --followcommande ne prend qu'un seul nom de fichier comme argument, cela est moins nécessaire car il ne peut pas être un revision. Je viens de l'apprendre. Peut-être avez-vous eu raison de l'omettre de votre réponse alors; Je ne suis pas sûr.
NHDaly

172

Si vous préférez rester basé sur du texte, vous pouvez utiliser tig .

Installation rapide:

  • apt-get :# apt-get install tig
  • Homebrew (OS X) :$ brew install tig

Utilisez-le pour afficher l'historique sur un seul fichier: tig [filename]
ou parcourez l'historique détaillé du référentiel:tig

Similaire à gitkmais basé sur du texte. Prend en charge les couleurs dans le terminal!


23
Excellent outil basé sur du texte, excellente réponse. J'ai paniqué quand j'ai vu les dépendances pour l'installation de gitk sur mon serveur sans tête. Souhaiterait encore voter A +++
Tom McKenzie

Vous pouvez également consulter des fichiers spécifiques avec tig, c'esttig -- path/to/specific/file
gloriphobia

110

git whatchanged -p filenameest également équivalent à git log -p filenamedans ce cas.

Vous pouvez également voir quand une ligne de code spécifique à l'intérieur d'un fichier a été modifiée avec git blame filename. Cela affichera un court ID de validation, l'auteur, l'horodatage et une ligne de code complète pour chaque ligne du fichier. Ceci est très utile après avoir trouvé un bogue et vous voulez savoir quand il a été introduit (ou qui en est la faute).


4
+1, mais filenamen'est pas facultatif dans la commande git blame filename.
rockXrock

7
"Les nouveaux utilisateurs sont encouragés à utiliser git-log à la place. (...) La commande est conservée principalement pour des raisons historiques;"
ciastek

105

Utilisateurs de SourceTree

Si vous utilisez SourceTree pour visualiser votre référentiel (c'est gratuit et assez bon), vous pouvez cliquer avec le bouton droit sur un fichier et sélectionner Journal sélectionné

entrez la description de l'image ici

L'affichage (ci-dessous) est beaucoup plus convivial que gitk et la plupart des autres options répertoriées. Malheureusement (pour le moment), il n'y a pas de moyen facile de lancer cette vue à partir de la ligne de commande - CLI de SourceTree ouvre actuellement juste repos

entrez la description de l'image ici


1
J'aime particulièrement l'option "Suivre les fichiers renommés", qui permet de voir si un fichier a été renommé ou déplacé.
Chris

mais à moins que je ne me trompe (merci de me le faire savoir!), on ne peut comparer que deux versions à la fois dans le gui? Y a-t-il des clients qui ont une interface élégante pour différencier plusieurs versions différentes à la fois? Peut-être avec une vue de zoom arrière comme dans Sublime Text? Ce serait vraiment utile je pense.
Sam Lewallen

@SamLewallen Si je comprends bien, vous voulez comparer trois commits différents? Cela ressemble à une fusion à trois voies (la mienne, la vôtre, la base) - généralement cette stratégie est utilisée pour résoudre les conflits de fusion sans comparer nécessairement trois commits arbitraires. Il existe de nombreux outils qui prennent en charge les fusions tripartites stackoverflow.com/questions/10998728/… mais l'astuce consiste à alimenter ces outils les révisions spécifiques gitready.com/intermediate/2009/02/27/…
Mark Fox

Merci Mark Fox, c'est ce que je veux dire. Connaissez-vous des applications qui feront cela?
Sam Lewallen

1
@ MarnenLaibow-Koser Je ne me souviens pas pourquoi j'ai besoin du SHA à ce moment-là. Ahaha.
AechoLiu

63

Pour afficher la révision et l'auteur de la dernière modification de chaque ligne d'un fichier:

git blame filename

ou si vous souhaitez utiliser la puissante interface graphique de blâme:

git gui blame filename

49

Résumé des autres réponses après les avoir lues et joué un peu:

La commande habituelle en ligne de commande serait

git log --follow --all -p dir/file.c

Mais vous pouvez également utiliser gitk (gui) ou tig (text-ui) pour donner des façons beaucoup plus lisibles par l'homme de le voir.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

Sous debian / ubuntu, la commande d'installation de ces jolis outils est comme prévu:

sudo apt-get install gitk tig

Et j'utilise actuellement:

alias gdf='gitk --follow --all -p'

afin que je puisse simplement taper gdf dirpour obtenir une histoire ciblée de tout dans le sous-répertoire dir.


2
Je pense que c'est une excellente réponse. Peut-être que vous n'êtes pas également voté parce que vous répondez à d'autres moyens (à mon humble avis) pour voir les changements, c'est-à-dire via gitk et tig en plus de git.
PopcornKing

Juste pour ajouter à la réponse. Localisez le chemin (dans l'espace git, jusqu'à ce qu'il existe encore dans le référentiel). Utilisez ensuite la commande indiquée ci-dessus "git log --follow --all -p <chemin_dossier / chemin_fichier>". Il se peut que le dossier filde / ait été supprimé sur l'historique, localisez donc le chemin maximum qui existe toujours et essayez de récupérer son historique. travaux !
parasrish

2
--allest pour toutes les branches, le reste est expliqué dans la réponse de @ Dan
cregox

1
Oh mec, après tant de temps à chercher une bonne solution pour suivre un fichier au-delà des renommages, enfin, je l'ai trouvé ici. Fonctionne comme un charme! Merci!
xZero

25

Ajoutez cet alias à votre .gitconfig:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

Et utilisez la commande comme ceci:

> git lg
> git lg -- filename

La sortie sera presque exactement la même que la sortie gitk. Prendre plaisir.


Après avoir exécuté ce raccourci lg, j'ai dit (et je cite) "Beautiful!". Cependant, notez que le "\ n" après "--graph" est une erreur.
jmbeck

3
Peut également être utilisé git lg -p filename- il renvoie une belle différence de fichier recherché.
Egel

22

Dernièrement, j'ai découvert tig et trouvé cela très utile. Il y a des cas où je souhaiterais qu'il fasse A ou B mais la plupart du temps c'est plutôt soigné.

Pour votre cas, c'est tig <filename>peut-être ce que vous recherchez.

http://jonas.nitro.dk/tig/


sur centos yum install tig
zzapper

18

Vous pouvez utiliser vscode avec GitLens , c'est un outil très puissant. Après avoir installé GitLens, allez dans l'onglet GitLens, sélectionnez FILE HISTORYet vous pouvez le parcourir.

entrez la description de l'image ici


15

J'ai écrit git-playback dans ce but précis

pip install git-playback
git playback [filename]

Cela a l'avantage d'afficher les résultats dans la ligne de commande (comme git log -p) tout en vous permettant de parcourir chaque validation à l'aide des touches fléchées (comme gitk).


13

Ou:

gitx -- <path/to/filename>

si vous utilisez gitx


1
Pour une raison quelconque, mon gitx s'ouvre en blanc.
IgorGanapolsky

@IgorGanapolsky vous devez vous assurer que vous êtes à la racine de votre dépôt git
zdsbs

10

Vous pouvez également essayer ceci qui répertorie les validations qui ont modifié une partie spécifique d'un fichier (implémenté dans Git 1.8.4).

Le résultat renvoyé serait la liste des validations qui ont modifié cette partie particulière. Commande:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

où upperLimit est le start_line_number et lowerLimit est le end_line_number du fichier.

Plus de détails sur https://www.techpurohit.com/list-some-useful-git-commands


9

Si vous souhaitez voir l'historique complet d'un fichier, y compris sur toutes les autres branches, utilisez:

gitk --all <filename>

7

Avec les excellentes extensions Git , vous allez à un point de l'historique où le fichier existait toujours (s'il a été supprimé, sinon allez simplement à HEAD), passez à l' File treeonglet, faites un clic droit sur le fichier et choisissez File history.

Par défaut, il suit le fichier à travers les renommages, et l' Blameonglet permet de voir le nom à une révision donnée.

Il a quelques problèmes mineurs, comme apparaître fatal: Not a valid object namedans l' Viewonglet lorsque vous cliquez sur la révision de suppression, mais je peux vivre avec ça. :-)


Il convient de noter qu'il s'agit uniquement de Windows.
Evan Hahn

3
@EvanHahn n'est pas précis, via mono on peut utiliser GitExtension également sous Linux, nous l'utilisons sur ubuntu et assez content avec. voir git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat

7

Si vous utilisez l'interface graphique git (sous Windows) dans le menu Référentiel, vous pouvez utiliser "Visualiser l'historique du maître". Mettez en surbrillance un commit dans le volet supérieur et un fichier en bas à droite et vous verrez le diff pour ce commit en bas à gauche.


Comment cela répond-il à la question?
jmbeck

3
Eh bien, OP n'a pas spécifié de ligne de commande, et en passant de SourceSafe (qui est une interface graphique), il semblait pertinent de souligner que vous pouviez faire à peu près la même chose que vous pouvez faire dans VSS dans l'interface graphique Git sur Windows.
cori

6

SmartGit :

  1. Dans le menu, permet d'afficher les fichiers inchangés: Afficher / Afficher les fichiers inchangés
  2. Faites un clic droit sur le fichier et sélectionnez «Journal» ou appuyez sur «Ctrl-L»

4

La réponse que je cherchais qui n'était pas dans ce fil est de voir les changements dans les fichiers que j'avais mis en scène pour la validation. c'est à dire

git diff --cached

1
Si vous souhaitez inclure des modifications locales (non mises en scène), je cours souvent git diff origin/masterpour montrer les différences complètes entre votre branche locale et la branche principale (qui peut être mise à jour à distance via git fetch)
ghayes

4

Si vous utilisez TortoiseGit, vous devriez pouvoir faire un clic droit sur le fichier et faire TortoiseGit --> Show Log. Dans la fenêtre qui apparaît, assurez-vous:

  • L' Show Whole Projectoption ' ' n'est pas cochée.

  • ' All Branches' est cochée.


TortoiseGit (et Eclipse Git également) manque en quelque sorte les révisions du fichier sélectionné, ne comptez pas dessus!
Noam Manos

@NoamManos, je n'ai pas rencontré ce problème, je ne peux donc pas vérifier si votre déclaration est correcte.
user3885927

Mon erreur, cela ne se produit que dans Eclipse, mais dans TortoiseGit vous pouvez voir toutes les révisions d'un fichier si vous décochez "afficher tous les projets" + cocher "toutes les branches" (au cas où le fichier a été validé sur une autre branche, avant qu'il ne soit fusionné avec le principal) branche). Je mettrai à jour votre réponse.
Noam Manos,

3

git diff -U <filename> vous donner un diff unifié.

Il doit être coloré en rouge et vert. Si ce n'est pas le cas, lancez: d' git config color.ui autoabord.


2

Si vous utilisez eclipse avec le plugin git, il a une excellente vue de comparaison avec l'historique. Faites un clic droit sur le fichier et sélectionnez "comparer avec" => "historique"


Cependant, cela ne vous permettra pas de trouver un fichier supprimé.
avgvstvs

La comparaison de deux versions d'un fichier est différente de la visualisation de l'historique des modifications d'un fichier
golimar

0

Je suis probablement sur la position de l'OP lorsque cela a commencé, à la recherche de quelque chose de simple qui me permettrait d'utiliser git difftool avec vimdiff pour examiner les modifications apportées aux fichiers de mon référentiel à partir d'un commit spécifique. Je n'étais pas trop satisfait des réponses que je trouvais, alors j'ai jeté ce script git inc remental rep orter (gitincrep) ensemble et cela m'a été utile:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Appelé sans argument, cela commencera au début de l'historique du dépôt, sinon il commencera avec le hachage de validation abrégé que vous fournissez et passera au présent - vous pouvez Ctrl-C à tout moment pour quitter. Tout argument après le premier limitera les rapports de différence pour inclure uniquement les fichiers répertoriés parmi ces arguments (ce qui, je pense, est ce que l'OP voulait, et je le recommanderais pour tous les projets, sauf les plus petits). Si vous vérifiez les modifications apportées à des fichiers spécifiques et souhaitez commencer depuis le début, vous devrez fournir une chaîne vide pour arg1. Si vous n'êtes pas un utilisateur de vim, vous pouvez remplacer vimdiff par votre outil de diff préféré.

Le comportement consiste à afficher les commentaires de validation lorsque des modifications pertinentes sont trouvées et à commencer à proposer des exécutions vimdiff pour chaque fichier modifié (c'est le comportement de git difftool , mais cela fonctionne ici).

Cette approche est probablement assez naïve, mais en examinant de nombreuses solutions ici et dans un article connexe, beaucoup impliquaient l'installation de nouveaux outils sur un système où je n'ai pas d'accès administrateur, avec des interfaces qui avaient leur propre courbe d'apprentissage. Le script ci-dessus a fait ce que je voulais sans traiter de tout cela. J'examinerai les nombreuses excellentes suggestions ici lorsque j'ai besoin de quelque chose de plus sophistiqué - mais je pense que cela répond directement au PO.


0

J'ai trouvé une solution très simple pour retrouver rapidement l'historique du fichier.

  1. Faites un changement aléatoire dans le fichier
  2. Il apparaîtra comme des changements non validés sur votre arbre source
  3. Faites un clic droit sur le fichier et sélectionnez 'Journal sélectionné'

entrez la description de l'image ici

Cela montrerait l'histoire de tous les commits.


D'où vient cette interface graphique?
colidyre

Interface utilisateur Sourcetree. Merci
savvyBrar
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.