为什么git log可能不显示移动文件的历史记录,我该怎么办?

113

我使用git mv重命名了一些文件,然后使用git stash进行了暂存,查看了一下HEAD(没有更改),接着使用git stash pop重新获取了全部内容。我的移动操作在提交列表中消失了,所以我再次使用git rm重新执行了它们,并且提交信息显示git已经识别到这是一个重命名操作。所以我就没再管它了。

但是现在,在提交后,我无法访问已移动文件的历史记录!以下是有关该提交的git输出:

~/projects% git log --summary
commit de6e9fa2179ae17ec35a5c368d246f19da27f93a
Author: brone
Date:   Wed Dec 8 22:37:54 2010 +0000

    Moved R_DebugUI into runtime

 delete mode 100644 test/R_DebugUI_iOS.h
 delete mode 100644 test/R_DebugUI_iOS.m
 create mode 100644 system/runtime/src/R_DebugUI_iOS.h
 create mode 100644 system/runtime/src/R_DebugUI_iOS.m

 <<snip older commits>>
 ~/projects%

我现在正在尝试获取其中一个移动文件的历史记录,以便查看旧版本,但是我没有得到什么非常有用的东西:

~/projects/system/runtime/src% git log --follow --find-copies-harder -M -C R_DebugUI_iOS.m
commit de6e9fa2179ae17ec35a5c368d246f19da27f93a
Author: brone
Date:   Wed Dec 8 22:37:54 2010 +0000

    Moved R_DebugUI into runtime
~/projects/system/runtime/src% 

我也尝试过不带-M-C--find-copies-harder,但都没有成功。

我可以获取它在旧位置的历史记录,但这个历史记录在它被从旧位置删除时停止:

~/projects% git log --summary --follow --find-copies-harder -M -C -- test/R_DebugUI_iOS.m
commit de6e9fa2179ae17ec35a5c368d246f19da27f93a
Author: brone
Date:   Wed Dec 8 22:37:54 2010 +0000

    Moved R_DebugUI into runtime

 delete mode 100644 test/R_DebugUI_iOS.m

commit 32a22d53c27e260714f759ecb3d3864e38b2e87f
Author: brone
Date:   Tue Dec 7 23:52:51 2010 +0000

    Can set debug UI's alpha.

<<snip older commits>>
~/projects%

这次我还不完全卡住了,但我不想一直这么做。(我预计将有相当数量的文件至少会移动一次。)

我是否做错了什么?旧文件副本和新文件副本相似度达到了98.8%(166行中只有2行发生变化)。我理解Git应该能够在这种情况下跟踪文件,因为它推断重命名操作而不是显式存储它们,并且这些文件非常相似,我认为它应该将它们视为相同的文件。

我有什么办法可以解决这个问题吗?


猜测:如果在/projects/而不是/projects/system/runtime/src内执行该命令,是否有效? - Douglas
不,我得到了相同的结果。(一般来说,Git 对于让你在任何文件夹中都可以自由操作似乎非常擅长...) - please delete me
这给了我一个想法,我更新了问题并附上了我的发现。感谢您的评论! - please delete me
我正在使用"tortoiseGit 1.5.8.0"和"1.7.3.1.msysgit.0"在mswindows上。当我在资源管理器中重命名+提交文件时,我在我的GUI中看到"状态=重命名"。我不太了解git如何在命令行中执行此操作以回答"如何执行此操作",但是tortoiseGit为我做了一些事情,这正如您所期望的那样起作用。 - k3b
3
这是一个相似的问题吗?https://dev59.com/4XE95IYBdhLWcg3wbtXO(翻译说明:将英文原文中的“dupe”翻译成了“相似的问题”,将“move/rename files”翻译成了“移动/重命名文件”,并对句子进行了简化。) - cregox
5个回答

162

7
如果你收到了“fatal: ambiguous argument 'file.txt': unknown revision or path not in the working tree” 的错误提示,尝试使用命令git log --follow -- file.txt。 - nealmcb

30

好的,我确实可以用git log -M --summary命令查看我的重命名记录。


如果你只是查看某个给定文件的历史记录,即使用文件参数,那么git log -M --summary不会提供任何重命名信息。 - vinc17
对我来说不起作用,但是--follow可以。--follow还会显示文件移动/重命名之前的先前修订版本。 - Alexander Samoylov

21

回答自己的问题,因为我已经成功缓解了我的担忧,即使我没有完全解决我的问题。(尽管git log --follow对我仍然不起作用。)

首先,重命名提交的--summary日志包括带有文件旧名称的delete行。因此,如果很容易发现它的旧名称,您可以从那里找到它的旧名称并使用git log

如果它是某个大型提交的一部分,因此有点难以发现——这种情况是我担心的其中之一——则可以在第一个重命名修订版上使用带有文件新名称的git blame -C。假定行仍来自原始文件!因此,git应该找到它们的来源,并显示旧文件名(以及一个提交哈希值)。然后,您可以使用git log继续跟踪。

因此,如果您对文件作为单元的历史记录有兴趣(出于任何原因),则似乎可以相对简单地完成。虽然我觉得git更喜欢您正确使用它。


6
我认为您需要使用-M选项才能显示重命名,而非删除/添加。 - Adrian Cornish
1
刚遇到了同样的问题,注意到你的工作目录会影响 git log --follow . 的执行结果。如果工作目录是新位置,则该命令无法正常工作;而如果从旧位置和新位置的共同父目录中执行 git log --follow path/to/new/dir,则可以正常工作。 - akraf
1
--follow 参数确实有效,但您需要执行以下操作:git log --follow -- ./path/to/file - jaques-sam
我刚遇到了一个问题,即git -log filename.cs在文件移动提交时停止(当前目录设置为文件所在的文件夹)。 然而,VS历史窗口显示了整个文件更改日志。 我还可以看到该文件已被Github桌面移动。 但是,git log -10 --follow filename.cs也显示了移动提交之前的日志。 - oleksa

13
git log --follow ./path/to/file

我相信这就是你在寻找的。


5
五年前的答案中有这个信息。 - dotancohen

2

如已提到:

git log --follow ./file

正在运作。

如果您觉得它有用并且不想每次在git log中键入它,请设置此配置选项:

git config log.follow true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接