git显示合并提交

时间:2016-12-06 01:51:04

标签: git merge show

当我有一个合并提交并运行git show #commit时,它只显示提交日志,而不是实际更改的差异,比如

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

    Merge branch 'abc'

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

3 个答案:

答案 0 :(得分:63)

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

你的问题中存在一个根本性错误:提交不是差异;提交是快照。这似乎是一种没有区别的区别 - 对于某些提交,。但对于合并提交,它的不是

git show(或git log -p)将提交显示为差异时,通过比较提交的快照来实现git diff命令执行相同的操作:它将一个提交与另一个提交进行比较。 (或者它可以将提交与工作树,或索引的内容或其他一些组合进行比较。)

对于普通提交,它很明显要比较什么:将提交的快照与之前的(即父级)提交进行比较&# 39;快照。这就是git show所做的事情(以及git log -p):它从父提交运行git diff到此提交。

但是,合并提交并不只有一个父提交。他们有两个父母。 1 这就是他们"合并提交"首先:合并提交的定义是一个至少有两个父级的提交。

1 合并提交可以有三个或更多父母。这些被称为"章鱼合并"。但是,他们没有做任何特别的事情,而且主要是为了炫耀。 :-)你可以在这里忽略它们。

当有两个父母时,哪一个应该git show比较?

默认情况下git log -p选择做的是根本不进行比较。你可以通过添加各种标志来显示它(见下文)。

默认情况下git show选择做的事情比较复杂。由于有两个父母,git show首先与"第一个父母", 2 进行比较,然后与第二个父母进行比较。然后 - 这部分非常重要 - 它结合了两个差异,产生了一个所谓的"组合差异"。

在下一节中,让我注意一个棘手但非常有用的Git语法。如果您有c05f017之类的提交ID,则可以添加插入符号或" hat"之后的字符^,以命名父提交。您可以选择添加其他数字以选择哪个父级。对于常规(非合并)提交,只有一个,因此c05f017^ 父级。对于合并提交,c05f017^c05f017^1都表示第一个父,而c05f017^2表示第二个父

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

组合差异

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

  

请注意,组合差异仅列出从所有父级修改过的文件。

也就是说,假设 M 是合并提交,并且差异 M ^ 1 vs M 表示文件mainline.txt和{ {1}}都被改变了。进一步假设差异 M ^ 2 M 表示文件common.txtsidebranch.txt都已更改。组合差异将仅显示 common.txt ,同时跳过common.txtmainline.txt,因为这两个文件仅从一个父级修改(每)。 (即便如此,Git可能只显示sidebranch.txt的一些差异。)

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

拆分差异

common.txt选项 - m 可能代表 merge - 告诉Git实际上" split"合并。也就是说,不是试图将每个父对象的差异组合成一个大的组合差异,而是只显示每个父对象的差异,一次一个差异。

这有时是你想要的。当它不是您想要的时候,您可以运行您自己的显式-m来区分两个父母之一(或参见下文)。

你应该反对哪一个父母?

通常,正确的答案是"第一个父母"。

"第一个父母的关键"值得注意的是,当Git进行合并提交时,它总是会记录您当时的分支,作为第一个父级。另一个分支成为第二个分支。

也就是说,如果您在git diff上并且合并develop

topic

Git将在您当前的分支$ git checkout develop $ git merge topic 上创建一个新的提交 - 一个合并提交,其中包含两个父级。合并提交的第一个父级将是刚才develop的提示。 第二个父级将是(仍然)develop的提示。

由于您通常关注合并带来的内容,因此与第一位家长进行比较会给您提供。通常这就是你想要的。因此,topic允许您运行git show。那"分裂"提交然后git show --first-parent仅针对第一个父级进行区分。 (这与git show略有不同,后者将提交拆分两次:第一次拆分与第一次父级进行比较,第二次拆分与第二次父级进行比较。)

同样,您可以运行git show -m ...但是您仍然必须添加git log -p --first-parent才能将更改视为修补程序,因为默认情况下-m会跳过完全显示差异合并。 (在内部,跳过因为合并操作会覆盖拆分使其像非合并一样的方式。)这里,git log标志具有更重要的影响:日志操作不会看到< em>任何的侧支承提交,只提供主(第一 - 父)行的提交。

答案 1 :(得分:0)

作为mentioned here,这些解决方案涉及显示组合的差异,例如:

git diff --cc $M $M^1 $M^2 $(git merge-base $M^1 $M^2)

但是:“ diff --cc”的输出未显示原始路径 合并涉及的重命名
Git 2.22(2019年第一季度)中的一个新选项将原始树中的路径添加到输出中。

git diff --cc --combined-all-paths $M $M^1 $M^2 $(git merge-base $M^1 $M^2)
  

logdiff-tree:添加--combined-all-paths选项

     

合并的合并差异格式将仅列出一个文件名,即使   重命名或复制检测处于活动状态。

     

例如,使用原始格式,可能会看到:

::100644 100644 100644 fabadb8 cc95eb0 4866510 MM describe.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM   bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR   phooey.c
     

这不会让我们知道bar.sh的原始名称是   第一父,并且不让我们知道两个原始名称   phooey.c的父母中的任何一个。

     

相比之下,对于非合并提交,原始格式的确提供原始文件名(以及重新引导的重命名分数)。
  为了还为合并提交提供原始文件名,请添加一个--combined-all-paths选项(必须与-c--cc一起使用,并且仅在重命名或复制检测处于活动状态时才有用)这样我们就可以在以下情况下打印制表符分隔的文件名   涉及重命名。

     

这会将上面的输出转换为:

::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c  desc.c  desc.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM   foo.sh  bar.sh  bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR   fooey.c fuey.c  phooey.c
     

此外,以补丁格式,这将更改from / to标头,以便我们为每个父级分配一个,而不是只有一个“ from”标头。   例如,代替拥有

--- a/phooey.c
+++ b/phooey.c
     

我们将会看到

--- a/fooey.c
--- a/fuey.c
+++ b/phooey.c

答案 2 :(得分:0)

git show -c c0f501 将向其两个父项显示提交 c0f501combined diff,如合并期间由 git diff 打印。

这比 git show -m 提供了更好的概览。

但是,它只显示相对于双亲(或至少两个双亲进行章鱼合并)更改的文件中的更改。例如。当文件 f1f2 在第一个父级上更改,而 f2f3 在第二个父级上更改时,只会显示来自 f2 的更改通过这个命令。 f1f3 中的更改将显示。 因此,要获得完整的概述,在使用 git show -m 之前或之后使用 git show -c 仍然有意义。

章鱼合并的 git show -c 示例输出,在两个文件中进行了更改,对于多个父文件,只有其中一个文件发生了更改:

commit 3a9f99582921495f7c25e682d4af36d3407983f9 (HEAD -> master)
Merge: 33fb507 91c772b edf2d9c
Author: Foo Bar <foobar@example.net>
Date:   Mon Mar 22 15:56:37 2021 +0100

    Merge branches 'b1' and 'b2'

diff --combined b
index 4658c0c,a305e3c,2788b76..9c7beb1
--- a/b
+++ b/b
@@@@ -1,5 -1,5 -1,5 +1,7 @@@@
   1
   2
+ +a
   3
 ++b
   4
++ c

相比之下,git show -m 给出了以下冗长但完整的输出:

git show -m 3a9f99582921495f7c25e682d4af36d3407983f9
commit 3a9f99582921495f7c25e682d4af36d3407983f9 (from 33fb5076fbbcc2d82aa0b877c959b8e4cc4f7b74)
Merge: 33fb507 91c772b edf2d9c
Author: Foo Bar <foobar@example.net>
Date:   Mon Mar 22 15:56:37 2021 +0100

    Merge branches 'b1' and 'b2'

diff --git a/a b/a
index 94ebaf9..775aea6 100644
--- a/a
+++ b/a
@@ -1,4 +1,5 @@
 1
+a
 2
 3
 4
diff --git a/b b/b
index 4658c0c..9c7beb1 100644
--- a/b
+++ b/b
@@ -1,5 +1,7 @@
 1
 2
+a
 3
 b
 4
+c

commit 3a9f99582921495f7c25e682d4af36d3407983f9 (from 91c772b2c57ff9b4791b57712c26aefbd0c7e730)
Merge: 33fb507 91c772b edf2d9c
Author: Foo Bar <foobar@example.net>
Date:   Mon Mar 22 15:56:37 2021 +0100

    Merge branches 'b1' and 'b2'

diff --git a/b b/b
index a305e3c..9c7beb1 100644
--- a/b
+++ b/b
@@ -2,4 +2,6 @@
 2
 a
 3
+b
 4
+c

commit 3a9f99582921495f7c25e682d4af36d3407983f9 (from edf2d9c9a255a709875988278a4eda6f7072196e)
Merge: 33fb507 91c772b edf2d9c
Author: Foo Bar <foobar@example.net>
Date:   Mon Mar 22 15:56:37 2021 +0100

    Merge branches 'b1' and 'b2'

diff --git a/a b/a
index 94ebaf9..775aea6 100644
--- a/a
+++ b/a
@@ -1,4 +1,5 @@
 1
+a
 2
 3
 4
diff --git a/b b/b
index 2788b76..9c7beb1 100644
--- a/b
+++ b/b
@@ -1,5 +1,7 @@
 1
 2
+a
 3
+b
 4
 c