merge 提交的 git 显示

标签 git merge show

当我进行 merge 提交并运行 git show #commit 时,它只显示提交日志,而不是实际更改的差异,例如

commit c0f50178901e09a1237f7b9d9173ec5d1c4936c
Merge: ed234b ded051
Author: abc
Date:   Mon Nov 21 15:56:33 2016 -0800

    Merge branch 'abc'

我知道真正的提交是在 merge 日志中,但我想保存输入,有没有办法在一个中显示差异?

最佳答案

TL;DR:使用 git show -m c05f017git show --first-parent c05f017 ,或者 git diff c05f017^ c05f017 .

你的问题有一个基本错误:提交不是差异;提交是快照。这似乎是一种没有区别的区别——对于某些提交来说,确实如此。但是对于 merge 提交,它不是。
git show (或 git log -p )将提交显示为差异,这是通过将提交的快照与其他内容进行比较来实现的。 git diff命令做同样的事情:它将一个提交与另一个提交进行比较。 (或者它可以将提交与工作树、索引的内容或其他一些组合进行比较。)
对于普通提交,比较什么是显而易见的:将这次提交的快照与前一个(即父)提交的快照进行比较。这就是git show确实(还有 git log -p):它运行一个 git diff从父提交到这次提交。
但是, merge 提交不只有一个父提交。他们有两个父级。1 这就是让他们首先“merge 提交”的原因: merge 提交的定义是至少有两个父级的提交。

1一个 merge 提交可以有三个或更多的父级。这些被称为“ Octopus merge ”。不过,他们并没有做任何特别的事情,主要是为了炫耀。 :-) 你可以在这里忽略它们。

当有两个 parent 时,应该选择哪一个 git show比较?
什么 git log -p默认情况下选择做的是根本不比较。你可以通过添加各种标志来让它显示一些东西(见下文)。
什么 git show默认情况下选择做的比较复杂。由于有两个 parent ,git show首先与“第一个父级”进行比较,2 然后与第二个父级进行比较。那么——这部分很关键——它结合两个差异 ,产生所谓的“组合差异”。
在下一节中,让我注意一个棘手但非常有用的 Git 语法。如果你有一个像 c05f017 这样的提交 ID , 您可以添加脱字符或“帽子”字符 ^之后,命名父提交。您可以选择添加另一个数字来选择哪个父级。对于常规(非 merge )提交只有一个,所以 c05f017^是 parent 。对于 merge 提交,c05f017^c05f017^1两者都表示第一个父级,而 c05f017^2表示第二个 parent 。

2我把它放在引号中是因为第一个父级的想法在 Git 中特别重要,我们稍后会看到。换句话说,Git 最关心哪个父级在前,而其余的只是“其余”。

组合差异
组合差异格式在 the documentation 中描述。 ,但首先描述一个关键位 here ,以使其特别晦涩:3

Note that combined diff lists only files which were modified from all parents.


也就是说,假设 M 是一个 merge 提交,并且比较 M^1 与 M 表示文件 mainline.txtcommon.txt都被改变了。进一步假设比较 M^2 和 M 表示文件 sidebranch.txtcommon.txt都被改变了。 merge 后的差异将仅显示 common.txt , 跳过两者 mainline.txtsidebranch.txt因为这两个文件仅从一个父文件(每个文件)修改。 (即使这样,Git 也可能只显示 common.txt 的一些差异。)

3我花了很长时间才在文档中找到这个,因为我一直在看其他部分。

拆分差异-m选项——m 在这里可能代表 merge ——告诉 Git 实际上“拆分” merge 。也就是说,与其尝试将针对每个父级的差异组合成一个大的组合差异,只需显示针对每个父级的差异,一次一个差异。
这有时就是你想要的。当它不是你想要的时,你可以运行你自己的显式 git diff只是与两个 parent 之一(或见下文)不同。
你应该反对哪个家长?
通常,正确答案是“第一个 parent ”。
“第一个父级”概念的关键是,当 Git 进行 merge 提交时,它始终将您当时所在的分支记录为第一个父级。另一个分支成为第二个父级。
也就是说,如果您在 develop然后你 merge topic :
$ git checkout develop
$ git merge topic
Git 将在您当前的分支 develop 上进行一个新的提交——一个 merge 提交,有两个父节点。 . merge 提交的第一个父项将是 develop 提示的提交。就在刚才。第二个父项将是(仍然)是 topic 提示的提交。 .
由于您通常关心 merge 带来的内容,因此与第一个父级进行比较会给您带来这一点。所以通常这就是你想要的。为此,git show允许您运行 git show --first-parent .这“拆分”了提交,然后 git show仅与第一个父级不同。 (这与 git show -m 有点不同,后者将提交拆分两次:第一个拆分与第一个父项进行比较,第二个拆分与第二个父项进行比较。)
同样,您可以运行 git log -p --first-parent在这里,--first-parent flag 有一个更重要的作用:日志操作根本不查看任何侧分支的提交,只查看主(第一父)行上的提交。请注意,如果您的 Git 早于 2.31,您仍然需要 -m标志也是如此(当使用 git log 时,也就是说; git show 默认为 --cc ,因此不需要 -m ,所有这些都在 Git 2.31 中清除了)。

关于 merge 提交的 git 显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40986518/

相关文章:

json - 将数组映射到没有公共(public)字段的对象

jQuery 查找/是 (':visible' )问题

javascript - Jquery 隐藏显示无法正常工作

javascript - 在 WordPress 自定义模板中使用 Jquery .click() 实现选项卡

git - 为什么 "git branch"在我的新 BitBucket 克隆中没有显示任何内容?

git - Git 中的最大文件大小和最大存储库大小?

Git Svn 获取更多修订

git - 微服务:众多微服务的源代码如何 stash ?

php - 从字符串生成数组

visual-studio - VS 2012 的 TFS 默认合并工具的命令行参数是什么?