我有一个包含n个提交的Git存储库。
我有一个我需要的文件,它曾经在存储库中,我突然寻找并想“哦!那个文件去哪儿了?”
是否有一系列Git命令会告诉我“提交n-13时删除了文件really_needed.txt”?
换言之,如果不查看每个单独的提交,并且知道我的Git repo对每个文件都有更改,那么我能快速找到包含该文件的最后一个提交吗?
我有一个包含n个提交的Git存储库。
我有一个我需要的文件,它曾经在存储库中,我突然寻找并想“哦!那个文件去哪儿了?”
是否有一系列Git命令会告诉我“提交n-13时删除了文件really_needed.txt”?
换言之,如果不查看每个单独的提交,并且知道我的Git repo对每个文件都有更改,那么我能快速找到包含该文件的最后一个提交吗?
当前回答
我刚刚在这里添加了一个解决方案(在git中有没有方法列出存储库中的所有已删除文件?),用于通过使用正则表达式查找已删除文件的提交:
git log --diff-filter=D --summary | sed -n '/^commit/h;/\/some_dir\//{G;s/\ncommit \(.*\)/ \1/gp}'
这将返回名为some_dir(级联)的目录中删除的所有内容。其中\/some_dir\/is的任何sed正则表达式都可以。
OSX(感谢@triple和@keif)
git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
其他回答
这对我有用:
git-log--**/Myfile.cs
如果包含--完整历史记录开关,它将显示许多与文件无关的更改。不知道为什么。
您可以找到删除文件的最后一次提交,如下所示:
git rev-list -n 1 HEAD -- [file_path]
此处提供更多信息
简短回答:
git log --full-history -- your_file
将显示repo历史记录中的所有提交,包括涉及文件的合并提交。最后一个(顶部)是删除文件的那个。
一些解释:
这里的--完整历史标记很重要。如果没有它,当你向Git索要文件日志时,Git会执行“历史简化”。文档中没有详细说明这是如何工作的,我缺乏从源代码中找出答案所需的勇气和勇气,但git日志文档有很多话要说:
默认模式将历史简化为解释树的最终状态的最简单历史。最简单,因为如果最终结果相同(即合并具有相同内容的分支),它会修剪一些边分支
这显然与我们想要的历史记录的文件何时被删除有关,因为解释被删除文件的最终状态的最简单的历史记录是没有历史记录的。没有完整历史记录的git日志是否会简单地声称从未创建过文件?不幸的是,是的。下面是一个演示:
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
注意上面终端转储中的git-log-bar是如何导致实际上没有输出的;Git正在将历史“简化”成一部从未有过酒吧的小说。另一方面,gitlog--fullhistory-bar提供了创建bar的提交和删除它的提交。
要明确的是:这个问题不仅仅是理论问题。我只查看了文档,发现了--完整的历史记录标志,因为git-log--some_file在一个真实的存储库中失败了,当时我正试图跟踪一个已删除的文件。当您试图了解当前存在的文件如何处于当前状态时,简化历史记录有时可能会有所帮助,但当您试图追踪文件删除时,隐藏您关心的提交更可能会使您陷入困境。对于这个用例,始终使用--full-history标志。
Try:
git log --stat | grep file
要显示更改文件的提交(即使文件已删除),请运行以下命令:
git log --full-history -- [file path]
如果只想查看删除文件的最后一次提交,请在上面的命令之外使用-1:
git log --full-history -1 -- [file path]
另请参阅我的文章:哪个提交删除了文件。