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

voi*_*ter 6 git

我想在我的日志中查看每个提交的文件列表和相应的差异状态。要为正常提交执行此操作,它很简单:

$ git log --oneline --graph --name-status
Run Code Online (Sandbox Code Playgroud)

但是,对于合并提交,文件列表是空白的。我希望看到的是自之前的合并以来修改、删除或添加的文件列表(对于同一个第二个父项)。

我尝试运行上面相同的命令,但有以下-m选项:

$ git log --oneline --graph --name-status -m
Run Code Online (Sandbox Code Playgroud)

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

为什么--name-status结果与log我看到的不同diff-m这里的选项是我认为的吗?

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

tor*_*rek 5

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

\n\n

我保留了一些测试存储库,用于探索 git 的一些奇怪的角落,其中包含干净简单的分支和合并案例,或特定更改等;在这种情况下,它们有助于揭示如何-m实施,而这与如何git log --graph实施的相互作用很差。这是来自的片段git log --oneline --graph

\n\n
*   cc081d4 Merge branch \'branch\'\n|\\  \n| * 222c4dd add clobber-reg example\n* | dcfaa9d test some python logging package items\n|/  \n* fb45c22 Revert "edit file foo"\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

颜色突出显示在这里丢失了,但它提供了额外的线索:cc081d4 (from dcfaa9d)cc081d4 (from 222c4dd)被着色为提交 ID。似乎当git log(or git show) 生成差异,并且-m强制将合并拆分为与父级一样多的结果与父级对时,git 在内部拆分提交本身。

\n\n

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

\n\n

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

\n\n

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

\n\n

正如我们刚刚发现的,这种分裂会影响git log. (直到现在我自己才知道这一点。)因此,解决方法是,不要尝试将这些内容从git log. 一开始让合并保持神秘,然后返回并使用一次一个地填充它们git show -m --name-status。(如果您愿意,您也可以使用 抑制日志消息--format=。)

\n\n

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

\n