如何使用`git log --name-status`查看合并提交的变更内容?

7

我希望能够在我的日志中查看每个提交的文件列表和相应的差异状态。对于普通的提交,只需要执行以下命令即可:

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

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

我尝试运行与上面相同的命令,但加上了-m选项:

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

这也不起作用。合并提交显示了一个巨大的文件列表,其中一些我知道实际上在合并过程中没有更改。使用 git diff --name-status MERGE_SHA1^! 实际上可以得到更准确的结果,其中 MERGE_SHA1 是我正在检查的合并提交的字面 SHA1 值。
为什么 log 中的 --name-status 结果与我在 diff 中看到的不同?这里的 -m 选项是否做了我想要的事情?
是否有方法可以让日志命令显示我期望的合并提交的结果?
1个回答

5
答案似乎是“哎呀,不行”,但有一个解决方法可能足够。我有一些测试存储库用于探索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-2cfaa9dcc081d4-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查找非合并。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接