我从master创建了分支A.完成后我创建了拉取请求掌握。当A的工作正在审查中时,我开始处理基于分支A的任务,所以从分支A我创建了分支B.然后我将分支B合并到A并且想要将B合并到主人,但是冲突出现了。在这种情况下,避免冲突的最佳做法是什么?在A的拉取请求之前,两个分支都是本地的。
[编辑]
在分支A和B中编辑了同一行,那么为什么它不会自动合并?
答案 0 :(得分:2)
Git (这里需要强调,因为你可能使用的不仅仅是Git本身)并没有一个"基础分支"的概念。
当您使用GitHub或Bitbucket上的网络界面来创建"拉取请求时,它是 Web界面,它选择上游'用于建议拉取请求的分支名称。 Git本身并不知道你会发出拉取请求。 1 所有Git都知道并关心提交,通常是通过哈希ID。
运行git merge
时,你选择两个提交,通常是两个分支提示。您可以通过git checkout
选择一个,通常为git checkout <somebranch>
。该提交将成为您的当前提交。这是Git调用 local 或--ours
的提交;我通常称它为 L 为左,本地或--ours
。 (请注意,如果您不在git checkout
之前运行git merge
,那么您现在检查的内容仍然您当前的提交,因此您选择 作为 L 提交。)
然后运行git merge <name-or-hash-id>
。 Git将名称(如果您给它一个)转换为提交哈希ID。这是您选择其他提交的方式,Git有时会将其命名为远程或其他或--theirs
提交,并且我会调用 R
Git使用 L 和 R 提交哈希ID以及存储库中的所有其他提交来查找合并base 提交哈希ID。简而言之,这个合并基础提交是&#34;最近的&#34;承诺两个分支一起回来&#34;。 Git将在此处找到的提交取决于现有提交图的拓扑结构。
如果Git能够自己进行合并,Git会生成一个包含合并结果的新提交。新提交有两个父项,而不只是一个:第一个父项是您运行git merge
时 L 的提交,第二个是 R 的提交。新提交在当前分支上进行,因此当前分支名称(您已检出的分支名称)现在指向新的合并提交。
您在上面绘制的图表很难解释:我无法从您的绘图中看出哪些提交可以从哪个分支提示提交,或者就此而言,哪些提交首先是分支提示。特别是你已经绘制了两个似乎是合并提交的提交,但我不知道早期(祖先)提交是左侧还是右侧。此外,您的文字描述了一个合并,而不是两个。假设先前提交是向左 - 那个时间从左到右流动,就像在这里 - 我在这里是如何在文本中绘制大部分图:
o--o o--o <-- branch-B
/ \ /
| __---o <-- branch-A
|/
...--o <-- master
但请注意,此图只有一个合并提交,在这种情况下是名称branch-A
指向的提交。名称branch-B
指向顶行的最右侧提交。
在此特定示例中,branch-B
包含图表中提取的每个提交,而branch-A
包含除最近两次提交之外的所有提交,master
包含只有底线上的提交加上导致该点的任何早期提交。提示branch-B
(提交 L )和提示master
(提交 R )的合并基础将是提示提交master
,即提交 R 本身。因此,在分支git merge
上运行branch-B
将选择它作为合并基础。合并将是微不足道的(但事实上被拒绝),因为不存在合并冲突。 2 因此,显然不是你在做什么,显然不是正确的图形。 / p>
如果没有正确的图表,就无法说出Git选择的合并基础。但是如果你确实遇到了合并冲突,那是因为当比较合并基础提交到提交 L 时,Git看到一个更改某个文件的某一行,然后比较合并基础提交提交 R ,Git看到对相同文件的相同行的不同的更改。 Git无法在这两个更改之间进行选择,因此它在合并冲突时停止,使文件的工作树版本应用了两个更改。现在由您来解决此冲突(以及任何其他冲突),git add
正确的合并结果,并运行git merge --continue
以完成合并;或运行git merge --abort
以停止合并,并将事情恢复到Git尝试合并之前的状态。
1 虽然它们是相关的,但不要将这些外部提供的Web界面与git request-pull
命令行命令混淆。那个是内置到Git中,但它需要你而不是Git,选择<start>
提交。当GitHub为您做出选择时,他们正在使用Git本身无法获得的信息。具体来说,GitHub知道 - 已经记录了自己,在一个位置它有效地保密了Git - 当你点击GitHub&#34; fork&#34;按钮。他们(GitHub)也控制该上游项目的Git存储库,因此他们可以查看它并选择<start>
。但他们这样做; Git没有。
2 请记住,在计算合并基础提交后,Git有效运行:
git diff --find-renames <base> L # see what we did on --ours
git diff --find-renames <base> R # see what they did on --theirs
然后尝试将这两组变化合并为一个大的&#34;每个人的变化,因为基地&#34;更改集,并将组合更改应用于<base>
提交中的任何内容。我们刚刚声称<base>
和 R 是相同的提交,因此这里一定不会有任何更改。这种合并的结果将完全匹配commit L 。事实上,Git会说&#34;已经是最新的&#34;并且拒绝做任何事情,对于这种情况。