如何让`git log --name-status`与合并提交一起使用?

时间:2016-03-03 19:03:20

标签: git

我希望在日志中看到每个提交的文件列表和相应的差异状态。要对正常提交执行此操作,它就像:

一样简单
$ git log --oneline --graph --name-status

但是,对于合并提交,文件列表为空。我期望看到的是自合并之前修改,删除或添加的文件列表(对于相同的第二个父级)。

我尝试使用上面的相同命令,但使用-m选项:

$ git log --oneline --graph --name-status -m

这也没有用。合并提交显示了一个巨大的文件列表,其中一些我知道的事实在合并期间没有改变。实际上,我使用git diff --name-status MERGE_SHA1^!获得了更准确的结果,其中MERGE_SHA1是我正在检查的合并提交的文字SHA1值。

为什么来自--name-status的{​​{1}}结果与我在log中看到的结果不同?这里的diff选项是否符合我的想法?

有没有办法让log命令显示我期望的合并提交的结果?

1 个答案:

答案 0 :(得分:4)

答案似乎是"唉,不是",但有一种解决方法可能就足够了。

我有一些测试存储库,我一直在探索git的一些奇怪的角落,包括分支和合并的简单或简单的更改,等等。在这种情况下,它们有助于揭示-m的实施方式,与git log --graph的实施方式交互不畅。这是git log --oneline --graph的代码段:

*   cc081d4 Merge branch 'branch'
|\  
| * 222c4dd add clobber-reg example
* | dcfaa9d test some python logging package items
|/  
* fb45c22 Revert "edit file foo"

-m --name-status添加相同的内容:

*   cc081d4 (from dcfaa9d) Merge branch 'branch'
|\  
| | A   clob.c
| | cc081d4 (from 222c4dd) Merge branch 'branch'
| | A   logtest.py
| * 222c4dd add clobber-reg example
| | A   clob.c
* | dcfaa9d test some python logging package items
|/  
|   A   logtest.py
* fb45c22 Revert "edit file foo"

此处丢失了颜色突出显示,但它提供了额外的线索:cc081d4 (from dcfaa9d)cc081d4 (from 222c4dd)被着色为提交ID。似乎当git log(或git show)生成差异时,-m有效将合并分割成与父母一样多的结果与父对,git内部分裂提交本身。

也就是说,在这种情况下,提交cc081d4是一个合并提交,因此git在内部构造两个 new 提交:cc081d4-vs-2cfaa9dcc081d4-vs-222c4dd 。然后它可以显示diff(和/或绘制图形) - 但它会将这些新提交放入图形输出中(替换作为实际合并的原始单个提交)。

在这些综合提交之后,我们得到了父提交,因此我们再次看到相同的单个文件被修改(因为这个合并的父节点只有一个文件被修改,没有合并冲突或任何东西)。在我的简单回购案例中,两个父母自己立即拥有一个共同的父母,这使事情变得简单。

一般情况下,正如您已经发现的那样(这就是您使用-m的原因),当git进入" show"合并,它使用其特殊的"组合差异"规则。这些组合差异模式首先在合并提交中查找匹配既不父文件的文件,然后为这些文件制作差异(所有父文件和每个文件的版本,以及该文件的最终提交版本)并使用修改后的统一差异形式呈现它们。使用-m拆分差异,以便您以git diff更喜欢比较两个树的方式对每个父项进行合并(当您进行正常的非合并提交时很容易) :那里有父母和提交,并且给你两棵树。)

正如我们刚刚发现的那样,这种分裂会影响git log。 (直到现在我自己都不知道。)所以,解决方法是,不要试图从git log中解决这些问题。最初让合并变得神秘,然后返回并用git show -m --name-status一次填充它们。 (如果您愿意,也可以使用--format=来抑制日志消息。)

请注意,您可以找到与git rev-list --merges的合并(并查找与git rev-list --no-merges的非合并)。