Git中的交叉合并是如何产生的?

Git中的交叉合并是如何产生的?,git,git-merge,least-common-ancestor,Git,Git Merge,Least Common Ancestor,我一直在浏览“git合并库”手册页,我不明白多个合并库是如何发展的。具体来说,我被挂在手册页中的以下插图上: When the history involves criss-cross merges, there can be more than one best common ancestor for two commits. For example, with this topology: ---1---o---A \ / X / \ ---2-

我一直在浏览“git合并库”手册页,我不明白多个合并库是如何发展的。具体来说,我被挂在手册页中的以下插图上:

When the history involves criss-cross merges, there can be more than one best common
ancestor for two commits. For example, with this topology:
  ---1---o---A
      \ /
       X
      / \
  ---2---o---o---B
both 1 and 2 are merge-bases of A and B. Neither one is better than the other (both
are best merge bases). When the --all option is not given, it is unspecified which
best one is output.
我就是不明白怎么会造成这样的局面。我曾尝试使用测试存储库在分支之间重新创建这种交叉合并情况,但我无法复制它。在所有情况下,我总是以A和B都指向的1个合并提交结束(而不是如图所示的A和B指向独立的合并提交)

有人能说明这种情况是如何发生的吗? 这是常见情况还是错误情况

我就是不明白怎么会造成这样的局面。我曾尝试使用测试存储库在分支之间重新创建这种交叉合并情况,但我无法复制它。在所有情况下,我总是以A和B都指向的1个合并提交结束(而不是如图所示的A和B指向独立的合并提交)

有人能说明这种情况是如何发生的吗

交叉融合可能以不同的方式出现。举个例子,当您有两个分支引用指向同一个合并提交(其中一个分支正在签出)并且您运行
git commit--amend
。下面的玩具示例就是这样做的:

#把事情安排好
cd~/桌面
mkdir十字交叉
交叉光盘
初始化
#作出初步承诺
printf“bar\n”>README.md
git add README.md
git提交-m“添加自述”
#在文件顶部添加一行并提交
sed-i''1s/^/foo\n/'README.md
git commit-am“添加foo行”
#创建并签出指向初始提交的分支
git签出-b其他主控^
#在文件底部添加一行并提交
printf“baz\n”>>README.md
git commit-am“添加baz行”
#执行合并并使两个分支都指向此合并提交
git合并主机
切换到主分支
git合并其他
在这个阶段,
git log--graph--oneline--decoration--all
的输出是

*   30b9175 (HEAD, master, other) Merge branch 'master' into other
|\  
| * f318ead add foo line
* | 31875d9 add baz line
|/  
* 8b313a0 add README
现在修改上一次提交(有关更多详细信息,请参阅):

git提交——修改
之后,
git log--graph--oneline--decoration--all的输出将是

*   69bbcbe (HEAD, master) Amended merge commit
|\  
| | *   30b9175 (other) Merge branch 'master' into other
| | |\  
| |/ /  
|/| /   
| |/    
| * f318ead add foo line
* | 31875d9 add baz line
|/  
* 8b313a0 add README
好了:历史现在包含了纵横交错的融合

这是常见情况还是错误情况


如上所述,可能出现这种情况。这可能是不可取的,但不应将其视为“错误状态”。

当其他开发人员从您处获取提交时,会发生这种情况,您从他们处获取提交,然后在两人都获取后,您将彼此的分支合并到自己的分支中。这是可能发生的,它不是一个错误状态。

下面是一系列提交,它们将生成交叉合并。比涉及
--amend
的步骤更多,但只使用基本步骤。运行此脚本以查看是否确实得到了交叉合并

#/垃圾箱/垃圾箱
#初始化
git init。
echo date>file.txt;git add file.txt
git提交-m“初始提交”
#做树枝
吉特分行A;吉特分行B
#换衣服
git签出A
echo date>fileA.txt;git add fileA.txt
git commit-m“沿分支A第一次提交”
#在B中进行更改;为以后添加标签
git签出B
echo date>fileB.txt;git add fileB.txt
git commit-m“沿分支B的第一次提交”
git标签“tag-B”
#将A合并到B(仍在B上)
git merge——不编辑;git标签“M”
#在父级为M的B上添加另一个提交
echo date>fileB2.txt;git add fileB2.txt
git commit-m“沿B进行第二次提交”
#切换到A并添加提交;注意
#M不是这个commit的祖先
git签出A
echo date>fileA2.txt;git add fileA2.txt
git commit-m“沿A进行第二次提交”
echo“最好的共同祖先(十字交叉前):”
#应该只有一个
git合并基--全部为A B
#合并标记为“tag-B”的提交
#变成一个纵横交错的集合
git合并--无编辑标记-B
echo“最普通的祖先(纵横交错后):”
#应该是两个
git合并基--全部为A B

当历史涉及交叉合并时,两次提交可以有多个最佳共同祖先。例如,使用此拓扑:

---1---o---A
    \ /
     X
    / \
---2---o---o---B

上面的内容来自,我猜它忘记了添加箭头

让我们看看下面的图片,很明显如何创造一个纵横交错的局面。当分支A需要来自分支B的一些代码时,它从分支B合并;当分支B需要来自分支A的代码时,它会从分支A合并;在这里,我们遇到了纵横交错的情况

更容易看出,分支A和分支B共享祖先1和祖先2


谢谢你的例子,这正是我要找的东西!这个问题现在对我来说越来越清楚了。@MACS是的,你是对的<代码>--缺少所有
。我会修改我的答案。谢谢你的回复。我想我必须设置一个示例repo来测试您的场景,这样我才能看到它的展开。如果没有问题,我们可能从同一台服务器获取,而不是从其他服务器获取:与“”相关的概念。另请参阅此相关内容:。感谢您的详细回复。我试试看