`git log -p path/to/file` 不显示所有更改

`git log -p path/to/file` doesn't show all the changes

我希望它显示对指定文件的所有更改(提交),但它没有这样做。它只显示了其中的一些。我想这与合并有关,但我看不出这里可能出了什么问题。有人可以解释一下吗?

UPD 我能够在测试回购中重现我的特定问题:

#!/usr/bin/env bash
set -eu
rm -rf 1
mkdir 1 && cd 1
git init

mkdir 1
echo m1 > 1/m1 && git add 1/m1 && git commit -m m1

git co -b b1
echo m11 > 1/m1 && git add 1/m1 && git commit -m b11
echo m1 > 1/m1 && git add 1/m1 && git commit -m b12

git checkout master
echo m2 > m2 && git add m2 && git commit -m m2
git merge b1 -m 'merge b1'
git --no-pager log --graph --oneline --decorate --all
git --no-pager log --oneline 1

最后一个命令未列出提交 b11b12

加入 --all 标志? git log --all filePath 默认情况下,日志只从当前分支返回。您可以在命令 git log branch1 branch2 -- filePath 上列出所有分支名称,或者 --all 标志考虑所有可能的分支。

使用git log -m -p。如果您正在寻找跟踪重命名,您可能还想添加 --follow--follow 代码很老套,只适用于某些情况,我不知道如果重命名点出现在合并)。

默认情况下,git log -p 不会显示任何合并提交,即使您要求特定路径也是如此。 -m 标志有效地告诉 git log 将每个合并提交拆分为两个 1 虚拟提交,一个对应每个 parent。然后它显示针对每个 parent 的更改,此时您将看到对指定路径的更改。

(注意:在合并提交上使用 git show 默认情况下会显示组合差异,包括查看特定路径时。组合差异会抑制与 both/all 相比没有更改的文件 parents,所以 -m 在这里也很有用。)

所述,如果您想查看,请添加--all(或--branches--tags、and/or --remotes)所有引用(或所有分支、所有标签等)。

对于特别复杂的情况,请参阅 git for-each-ref,它可以生成 ref-names,您可以过滤然后传递给 git log 命令。


1假设合并只有两个parent——如果有更多,则合并拆分为N有效提交,即 N 这样的虚拟提交。您可以通过其提交 ID 不再是正常的 SHA-1 哈希这一事实来识别每个虚拟提交。相反,它是一对哈希:合并的 ID 后跟特定的 parent。

因此,我基本上或多或少地回答了我的问题,试图在测试回购中重现该问题。在我的例子中,它发生在,比方说,功能分支更改了一个文件,但随后将其恢复到它所在的状态。也就是说,当合并作为一个整体不会对文件进行更改时。但是,不确定为什么会发生这种情况。不过肯定跟history simplification有关系。