Trouver quand un fichier a été supprimé dans Git

j'ai un dépôt Git avec n commits.

j'ai un fichier dont j'ai besoin, et qui était dans le dépôt, et que je cherche soudainement et je me dis "Oh! Où voudrais que le fichier d'aller?"

est-ce qu'il y a une (série de) commande(s) Git qui va me dire que" file really_need.txt a été supprimé à la Commission n-13"?

en d'autres termes, sans regarder chaque individu commettre, et sachant que mon git repo a chaque changement de chaque file, puis-je trouver rapidement la dernière propagation qui a ce fichier, pour que je puisse le récupérer?

701
git
demandé sur Mark Amery 2011-07-27 08:23:45

4 réponses

git log -- [file path] affiche les modifications d'un fichier, fonctionne même si le fichier a été supprimé.

git log -1 -- [file path]

voir qui commit supprimé un fichier

752
répondu vogella 2013-09-25 15:07:33

courte réponse:

git log --full-history -- your_file

vous indiquera tous s'engage dans votre pension de l'histoire, y compris la fusion s'engage, qui a touché your_file . La dernière (en haut) est celui qui a supprimé le fichier.

Quelques explications:

le drapeau --full-history ici est important. Sans lui, Git effectue une "simplification de l'histoire" lorsque vous lui demandez le log d'un fichier. Les docs sont légers sur les détails sur la façon dont cela fonctionne exactement et je manque de cran et de courage nécessaire pour essayer de comprendre à partir du code source, mais les git-log docs ont ceci à dire:

mode par Défaut

Simplifie l'histoire, à la simple histoire d'expliquer l'état final de l'arbre. Plus simple parce qu'il Taille quelques branches latérales si le résultat final est le même (c.-à-d. fusionner les branches avec le même contenu)

cela concerne évidemment quand le dossier dont nous voulons l'histoire est supprimé , puisque l'histoire la plus simple expliquant l'état final d'un dossier Supprimé est aucune histoire . Il y a un risque que git log sans --full-history prétendre que le fichier n'a jamais été créé? Malheureusement, oui. Voici une démonstration:

mark@lunchbox:~/example$ git init
Initialised empty Git repository in /home/mark/example/.git/
mark@lunchbox:~/example$ touch foo && git add foo && git commit -m "Added foo"
[master (root-commit) ddff7a7] Added foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
mark@lunchbox:~/example$ git checkout -b newbranch
Switched to a new branch 'newbranch'
mark@lunchbox:~/example$ touch bar && git add bar && git commit -m "Added bar"
[newbranch 7f9299a] Added bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git rm foo && git commit -m "Deleted foo"
rm 'foo'
[master 7740344] Deleted foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 foo
mark@lunchbox:~/example$ git checkout newbranch
Switched to branch 'newbranch'
mark@lunchbox:~/example$ git rm bar && git commit -m "Deleted bar"
rm 'bar'
[newbranch 873ed35] Deleted bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git merge newbranch
Already up-to-date!
Merge made by the 'recursive' strategy.
mark@lunchbox:~/example$ git log -- foo
commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log -- bar
mark@lunchbox:~/example$ git log --full-history -- foo
commit 2463e56a21e8ee529a59b63f2c6fcc9914a2b37c
Merge: 7740344 873ed35
Author: Mark Amery 
Date:   Tue Jan 12 22:51:36 2016 +0000

    Merge branch 'newbranch'

commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log --full-history -- bar
commit 873ed352c5e0f296b26d1582b3b0b2d99e40d37c
Author: Mark Amery 
Date:   Tue Jan 12 22:51:29 2016 +0000

    Deleted bar

commit 7f9299a80cc9114bf9f415e1e9a849f5d02f94ec
Author: Mark Amery 
Date:   Tue Jan 12 22:50:38 2016 +0000

    Added bar

remarquez comment git log -- bar dans le le dump terminal ci-dessus n'a donné aucun résultat; Git "simplifie" l'histoire en une fiction où bar n'a jamais existé. git log --full-history -- bar , d'autre part, nous donne le commit qui a créé bar et de s'engager à ce que effacés.

pour être clair: cette question n'est pas simplement théorique. J'ai seulement regardé dans les docs et découvert le drapeau --full-history parce que git log -- some_file était en panne pour moi dans un véritable dépôt où j'essayais de pister un supprimé fichier vers le bas. La simplification de l'histoire peut parfois être utile quand vous essayez de comprendre comment un fichier existant actuellement est venu à être dans son état actuel, mais quand vous essayez de traquer un fichier suppression il est plus probable de vous tromper en masquant le commit dont vous vous souciez. Utilisez toujours le drapeau --full-history pour ce cas d'utilisation.

169
répondu Mark Amery 2017-11-01 11:59:48

git log mais vous devez préfixer le chemin avec --

par exemple:

dan-mac:test dani$ git log file1.txt
fatal: ambiguous argument 'file1.txt': unknown revision or path not in the working tree.

dan-mac:test dani$ git log -- file1.txt
 commit 0f7c4e1c36e0b39225d10b26f3dea40ad128b976
 Author: Daniel Palacio <danpal@gmail.com>
 Date:   Tue Jul 26 23:32:20 2011 -0500

 foo
81
répondu daniel 2013-09-25 15:09:39

je viens d'ajouter une solution ici (y a-t-il un moyen dans git pour lister tous les fichiers supprimés dans le dépôt?) pour trouver le commet des fichiers supprimés à l'aide d'un regexp:

git log --diff-filter=D --summary | sed -n '/^commit/h;/\/some_dir\//{G;s/\ncommit \(.*\)/ /gp}'

renvoie tout ce qui a été supprimé dans un répertoire nommé some_dir (cascade). N'importe quel sed regexp là où \/some_dir\/ est fera l'affaire.

OSX (merci à @triplee et @keif)

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ /gp' -e }
19
répondu estani 2017-05-23 11:55:11