使用以下其中一项:
git show -m c05f017
git show --first-parent c05f017
git diff c05f017^ c05f017
您的问题存在一个根本性错误:提交不是差异;而是提交。提交是快照。这看起来似乎是一个没有区别的区别——对于某些提交来说,它is。但对于合并提交来说,它是not.
When git show
(or git log -p
) 显示提交as一个差异,它是这样做的将提交的快照与其他内容进行比较. The git diff
命令执行相同的操作:它将一个提交与另一个提交进行比较。 (或者它可以比较对工作树的提交,或与索引的内容,或其他一些组合。)
对于普通提交,比较什么是显而易见的:comparethis将快照提交到previous(即父级)提交的快照。所以这就是git show
确实(并且git log -p
太):它运行一个git diff
从父提交到此提交。
Merge commits don't have just one parent commit, though. They have two parents.1 This is what makes them "merge commits" in the first place: the definition of a merge commit is a commit with at least two parents.
1A merge commit can have three or more parents. These are called "octopus merges". They don't do anything special, though, and are mainly for showing off. :-) You can ignore them here.
当有两个父母时,哪一个应该git show
比较?
What git log -p
默认选择做的是根本不进行比较。您可以通过添加各种标志使其显示一些内容(见下文)。
What git show
chooses to do by default is more complicated. Since there are two parents, git show
first compares against the "first parent",2 then compares against the second parent. Then—this part is quite crucial—it combines the two diffs, producing a so-called "combined diff".
在下一节中,我将介绍一些棘手但非常有用的 Git 语法。如果您有一个提交 ID,例如c05f017
,您可以添加插入符号或“帽子”字符^
之后,命名一个父提交。您可以选择添加另一个号码来选择which父母。对于常规(非合并)提交只有一次,所以c05f017^
is the父母。对于合并提交,c05f017^
and c05f017^1
两者的意思都是第一个父母, while c05f017^2
means 第二个父母.
2I put this in quotes because the first parent idea is especially important in Git, as we will see in a moment. In other words, Git cares most about which parent is first, while the rest are just "the rest".
组合差异
The combined diff format is described in the documentation, but a key bit is first described here, so as to make it especially obscure:3
注意组合差异仅列出所有父级修改的文件。
也就是说,假设M是合并提交,并且比较M^1 vs M说文件mainline.txt
and common.txt
都被改变了。进一步假设 diffM^2 and M说那个文件sidebranch.txt
and common.txt
都被改变了。合并后的差异将显示only common.txt
,同时跳过mainline.txt
and sidebranch.txt
因为这两个文件仅修改自one父母(每个)。 (即便如此,Git 也可能只显示一些差异common.txt
.)
3It took me a long time to find this in the documentation, as I kept looking at the other section.
拆分差异
The -m
option—m可能代表merge这里——告诉 Git 实际上“分割”合并。也就是说,不要尝试将每个父级的差异组合成一个大的组合差异,而只需显示针对每个父级的差异each父级,一次一个差异。
有时这就是您想要的。当这不是你想要的时,你可以运行你自己的显式git diff
只是与两个父母之一进行比较(或见下文)。
你应该反对哪位家长?
通常,正确答案是“第一任父母”。
“第一个父级”概念的关键是,当 Git 进行合并提交时,它总是将您当时所在的分支记录为第一个父级。另一个分支成为第二个父分支。
也就是说,如果你在develop
然后你合并topic
:
$ git checkout develop
$ git merge topic
Git 将进行一次新的提交——a合并提交,有两个父母 - 在您当前的分支机构,develop
. The first合并提交的父级将是最顶端的提交develop
刚才。这second父级将是(仍然)是尖端的提交topic
.
由于您通常关心合并带来的内容,因此与第一个父级进行比较就会得到这一点。所以通常这就是你想要的。为此原因,git show
允许你运行git show --first-parent
。 “分割”提交然后git show
仅与第一个父级不同。 (这与git show -m
,它将提交拆分两次:第一次拆分与第一个父级进行比较,第二次拆分与第二个父级进行比较。)
同样,你可以运行git log -p --first-parent
在这里,--first-parent
flag还有一个更重要的作用:日志操作不看any侧分支的提交,仅限于主(第一个父)行上的提交。请注意,如果您的 Git 版本早于 2.31,您仍然需要-m
也标记(当使用git log
, 那是;git show
默认为--cc
因此不需要-m
,所有这些都在 Git 2.31 中得到了清理)。