答案似乎是“哎呀,不行”,但有一个解决方法可能足够。我有一些测试存储库用于探索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在内部构造了两个新的提交:
cc081d4-vs-2cfaa9d
和
cc081d4-vs-222c4dd
。然后它可以显示差异(和/或绘制图形) - 但它将这些新提交放入图形输出中(取代实际合并的原始单个提交)。
在这些合成提交之后,我们获取父提交,所以我们再次看到相同的单个文件被修改(因为此合并的父级各自只有一个文件被修改,没有合并冲突或任何其他问题)。在我的simple-repo案例中,这两个父级本身立即有一个共同的父级,这使事情变得简单。
总的来说,就像你已经发现的那样(这就是为什么你正在使用
-m
),当git去“显示”合并时,它使用其特殊的“合并差异”规则。这些合并差异模式首先找到在合并提交中与
没有一个父级匹配的文件,然后为这些文件制作差异(每个文件的所有父级版本与该文件的最终提交版本进行比较),并以修改的统一差异形式呈现。使用
-m
将差异分割,以便按照
git diff
希望比较确切的两个树(当你有一个常规的非合并提交时很容易:有父级和提交,这给你两个树)对每个父级执行合并。
正如我们刚刚发现的,这种拆分影响了
git log
。(直到现在我自己也不知道这一点。)因此,解决方法是,不要尝试从
git log
中获取这些内容。最初让合并保持神秘状态,然后逐个使用
git show -m --name-status
来填写它们。(如果需要,您可以使用
--format=
抑制日志消息。)
请注意,您可以使用
git rev-list --merges
查找合并,可以使用
git rev-list --no-merges
查找非合并。