Найти, когда файл был удален в Git - PullRequest
833 голосов
/ 27 июля 2011

У меня есть Git-репозиторий с n коммитами.

У меня есть файл, который мне нужен, и он раньше находился в репозитории, и который я вдруг ищу и думаю: «О! Где этоfile go? "

Существует ли (серия) команда (-ы) Git, которая сообщит мне, что" файл Действительно_needed.txt был удален при коммите n-13 "?

Другими словами, не просматривая каждый отдельный коммит и не зная, что в моем репозитории Git содержатся все изменения каждого файла, могу ли я быстро найти последний коммит, в котором был этот файл, и получить его обратно?

Ответы [ 6 ]

904 голосов
/ 19 мая 2013

git log --full-history -- [file path] показывает изменения файла, работают, даже если файл был удален.

Пример:

git log --full-history  -- myfile

Если вы хотите видеть только последний коммит, который удалил файл, используйте -1, например, git log --full-history -1 -- [file path]

См. Какой коммит удалил файл

201 голосов
/ 13 января 2016

Краткий ответ:

git log --full-history -- your_file

покажет вам все коммитов в истории вашего репо, включая коммиты слияний, которые коснулись your_file.Последний (верхний) - тот, который удалил файл.

Некоторое объяснение:

Флаг --full-history здесь важен.Без этого Git выполняет «упрощение истории», когда вы запрашиваете лог файла.В документах нет подробных сведений о том, как именно это работает, и мне не хватает смелости и смелости, необходимых для того, чтобы попытаться выяснить это из исходного кода, но в документации git-log есть что сказать:*

Режим по умолчанию

Упрощает историю до самой простой истории, объясняющей конечное состояние дерева.Проще всего, потому что он удаляет некоторые боковые ветви, если конечный результат один и тот же (то есть объединение ветвей с одинаковым содержимым)*, поскольку простейшая история, объясняющая конечное состояние удаленного файла, - без истории .Есть ли риск, что git log без --full-history просто заявит, что файл никогда не создавался?К сожалению, да.Вот демонстрация:

mark@lunchbox:~/example$ <b><i>git init</i></b>
Initialised empty Git repository in /home/mark/example/.git/
mark@lunchbox:~/example$ <b><i>touch foo && git add foo && git commit -m "Added foo"</i></b>
[master (root-commit) ddff7a7] Added foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
mark@lunchbox:~/example$ <b><i>git checkout -b newbranch</i></b>
Switched to a new branch 'newbranch'
mark@lunchbox:~/example$ <b><i>touch bar && git add bar && git commit -m "Added bar"</i></b>
[newbranch 7f9299a] Added bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar
mark@lunchbox:~/example$ <b><i>git checkout master</i></b>
Switched to branch 'master'
mark@lunchbox:~/example$ <b><i>git rm foo && git commit -m "Deleted foo"</i></b>
rm 'foo'
[master 7740344] Deleted foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 foo
mark@lunchbox:~/example$ <b><i>git checkout newbranch</i></b>
Switched to branch 'newbranch'
mark@lunchbox:~/example$ <b><i>git rm bar && git commit -m "Deleted bar"</i></b>
rm 'bar'
[newbranch 873ed35] Deleted bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 bar
mark@lunchbox:~/example$ <b><i>git checkout master</i></b>
Switched to branch 'master'
mark@lunchbox:~/example$ <b><i>git merge newbranch</i></b>
Already up-to-date!
Merge made by the 'recursive' strategy.
mark@lunchbox:~/example$ <b><i>git log -- foo</i></b>
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$ <b><i>git log -- bar</i></b>
mark@lunchbox:~/example$ <b><i>git log --full-history -- foo</i></b>
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$ <b><i>git log --full-history -- bar</i></b>
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

Обратите внимание, что git log -- bar в приведенном выше дампе терминала приводит к буквальному отсутствию вывода;Git «упрощает» историю до вымысла, где bar никогда не существовало.git log --full-history -- bar, с другой стороны, дает нам коммит, который создал bar, и коммит, который его удалил.

Для ясности: эта проблема не просто теоретическая.Я только просмотрел документы и обнаружил флаг --full-history, потому что git log -- some_file не удался для меня в реальном хранилище, где я пытался отследить удаленный файл.Упрощение истории иногда может быть полезно, когда вы пытаетесь понять, как существующий в настоящее время файл *1040* оказался в его текущем состоянии, но при попытке отследить файл delete это большеСкорее всего, он вас обманет, скрыв сделанный вами коммит.Всегда используйте флаг --full-history для этого варианта использования.

81 голосов
/ 27 июля 2011

Журнал Git, но вы должны префикс пути к --

Например:

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
24 голосов
/ 23 октября 2012

Я только что добавил решение здесь (есть ли способ в git перечислить все удаленные файлы в хранилище?) для поиска коммитов удаленных файлов с помощью регулярного выражения:

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

Возвращает все удаленное в каталоге с именем some_dir (каскадный).Подойдет любое регулярное выражение sed, где \/some_dir\/.

OSX (благодаря @triplee и @keif)

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
1 голос
/ 09 мая 2019

Вы можете найти последний коммит, который удалил файл следующим образом:

git rev-list -n 1 HEAD -- [file_path]

Более подробная информация доступна здесь

0 голосов
/ 05 апреля 2019

Это работает для меня на OSX:

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e ‘}’
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...