如何获取“git log--name status”来处理合并提交?

如何获取“git log--name status”来处理合并提交?,git,Git,我想在日志中查看每个提交的文件列表和相应的差异状态。要对正常提交执行此操作,只需执行以下操作: $ git log --oneline --graph --name-status 但是,对于合并提交,文件列表为空。我希望看到的是自合并后修改、删除或添加的文件列表(对于相同的第二个父级) 我尝试运行上面相同的命令,但使用-m选项: $ git log --oneline --graph --name-status -m 这也没用。合并提交显示了一个巨大的文件列表,我知道其中一些文件在合并过程中

我想在日志中查看每个提交的文件列表和相应的差异状态。要对正常提交执行此操作,只需执行以下操作:

$ git log --oneline --graph --name-status
但是,对于合并提交,文件列表为空。我希望看到的是自合并后修改、删除或添加的文件列表(对于相同的第二个父级)

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

$ git log --oneline --graph --name-status -m
这也没用。合并提交显示了一个巨大的文件列表,我知道其中一些文件在合并过程中没有改变。实际上,我通过
git diff--name status MERGE_SHA1^得到了更准确的结果
,其中
MERGE\u SHA1
是我正在检查的合并提交的文本SHA1值

为什么
--name status
来自
log
的结果与我在
diff
中看到的不同?这里的
-m
选项是否与我认为的一样

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

答案似乎是“唉,没有”,但有一个解决方法可能就足够了

我有一些测试存储库,用于探索git的一些奇怪的角落,包括清晰简单的分支和合并案例,或特定的更改等。;在本例中,它们有助于揭示
-m
是如何实现的,而这与
git log--graph
是如何实现的交互很差。下面是git日志--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(来自dcfaa9d)
cc081d4(来自222c4dd)
被着色为提交ID。似乎当
git log
(或
git show
)生成差异时,并且,
-m
有效地将合并拆分为尽可能多的结果对和父对,git在内部拆分提交本身

也就是说,在本例中,commit
cc081d4
是一个合并提交,因此git在内部构造了两个新提交:
cc081d4-vs-2cfaa9d
,和
cc081d4-vs-222c4dd
。然后,它可以向您显示差异(和/或绘制图形),但它会将这些新提交放入图形输出中(替换实际合并的原始单个提交)

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

一般来说,正如您已经发现的(这就是为什么要使用
-m
),当git“显示”合并时,它使用其特殊的“组合差异”规则。这些组合的差异模式首先在合并提交中查找不匹配父级的文件,然后对这些文件进行差异(每个文件的所有父级版本,与该文件的最终提交版本)并使用修改后的统一差异形式呈现它们。使用
-m
将差异拆分,以便针对每个父级进行合并,就像
git diff
更喜欢精确比较两棵树一样(当您有一个正常的、非合并的提交时很容易:有父级和提交,这给了您两棵树)

正如我们刚刚发现的,这种拆分会影响git日志。(我自己直到现在才知道这一点。)因此,解决办法是,不要试图从
git log
中获取这些。最初让合并保持神秘,然后返回并用
git show-m--name status
一次填写一个。(如果愿意,您也可以使用
--format=
抑制日志消息)

请注意,您可以找到带有
git rev list的合并--merges
(以及带有
git rev list的非合并--no merges