git 合并冲突:哪个提交是共同祖先?

sto*_*tic 5 git git-merge-conflict

我想知道 git 合并冲突解决期间“共同祖先”提交的身份。

换句话说:我想知道我在git merge.

希望有一个命令可以告诉我这些信息吗?

为什么我想知道

  • 我(不幸的是)正在做一个非常复杂的合并,有很多冲突。
  • 我希望能够可视化这两个更改路径 (BASE -> LOCALBASE -> REMOTE),以便为我提供更多有关这两组更改如何发生、谁进行、何时、在哪些分支上进行等的背景信息。

有用的(?)相关信息

  • 回想一下,对于任何特定的冲突文件,都有

    • 一个 BASE 版本 ( git show :1:<path>),来自共同祖先提交(其身份是我问题的答案)
    • LOCAL(我所在的分支:)git show :2:<path>版本和
    • REMOTE(我正在合并的分支:)git show :3:<path>版本
  • 我知道我可以通过使用获取 BASE 文件本身的 SHA 哈希值,git ls-files -u它给出的输出如下

$ git ls-files -u | grep "<path>"
100644 <SHA of BASE file> 1 <path>
100644 <SHA of LOCAL file> 2 <path>
100644 <SHA of REMOTE file> 3 <path>
Run Code Online (Sandbox Code Playgroud)
  • 我正在使用git mergetoolgvimdiff3查看冲突。该工具显示每个冲突文件(带有"<<<"">>>""|||"冲突标记,以及其他三个文件供参考:LOCAL、BASE 和 REMOTE。一切都非常好。

  • 我的 BASE 文件有时包含冲突标记(!),如下所示:

<<<<<<<<< Temporary merge branch 1
<snip>
||||||||| merged common ancestors
=========
<snip>
>>>>>>>>> Temporary merge branch 2
Run Code Online (Sandbox Code Playgroud)

When there is more than one common ancestor that can be used for 3-way merge, it creates a merged tree of the common ancestors and uses that as the reference tree for the 3-way merge.

  • 我想我看到的是“共同祖先”是多个提交的合并混合体。尽管如此,合并后的混合体一定是以某种方式生成的,必须有 SHA,并且必须有我想知道其身份的父母。

tor*_*rek 3

这个很棘手,而且有点令人讨厌。你在这里完全正确:

我想我看到的是“共同祖先”是多个提交的合并混合体。尽管如此,合并后的混合体一定是以某种方式生成的,必须有 SHA,并且必须有我想知道其身份的父母。

正如LeGEC 所说,当 Git 因合并冲突而停止时,您确实可以同时使用HEAD和。MERGE_HEAD

您可以使用以下命令找到合并基数(复数)的哈希 ID:

git merge-base --all HEAD MERGE_HEAD
Run Code Online (Sandbox Code Playgroud)

由于您使用的是合并递归,Git 所做的是:

  • 选择两个合并基地。
  • 跑向git merge-recursive他们。(这本身可能会找到两个以上的合并基础;如果是这样,请参阅此过程。)
  • 提交结果。这是现在的合并基础。(此提交有一个哈希 ID。)
  • 如果有两个以上的碱基,则选择下一个合并碱基,并将其与 merge-base-so-far 合并;这是现在新的 merge-base-so-far。
  • 重复此操作,直到所有合并碱基都用完。

此过程的最终输出是提交哈希 ID。 此哈希 ID 不会在任何地方保存或显示。当然, 您可以获取此过程的所有输入。git merge-base --all

通常,当合并出现冲突时,Git 会停止并让您修复它们。但是,当合并合并基础产生冲突时,Git 会继续提交冲突的合并基础。不是很好。(我并不是说它不好只是说它不好:它变得非常混乱。我认为,新的 merge-ort 并没有做到这一点,但我还没有准确地理解它的作用。)这些冲突标记确实是你所看到的。

Git 这里提供的工具并不能完全胜任这项工作,但是使用git merge-base --all,您至少可以检查每个输入。