Rag*_*son 1 git merge branch git-branch gitlab
我对 git 上的合并有不清楚的理解,我想正确理解。
假设我在 master 分支上有一个文件 F,它已经有 100 个 LOC。我从 master 创建了一个分支 A,并编写了 50 个 LOC,从第 101 行开始到第 150 行。我创建了一个合并请求,将分支 A 合并到 master。因此,如果分支 A 将被合并,那么 master 上的文件 F 将有 150 LOC
假设分支 A 尚未合并到 master,仍在等待。我从 master 创建了一个新的分支 B。我还写了 50 LOC,也是从第 101 行到第 150 行开始(因为分支 A 尚未合并)。我还为分支B创建了一个MR
如果 2 个人审阅 2 份 MR,将会发生什么情况,并且:
他们同时合并2个MR?master会不会有冲突,因为两个分支都想合并到第101行到第150行?
如果分支A先合并,则意味着master已经有150个LOC,但分支B仍然从第101行到第150行开始,因为它是在master还有100个LOC时创建的。B合并的时候会不会也有冲突?或者说 Git 是如何处理这些的?
提前致谢(我不是巨魔,只是想弄清楚一些东西,以防有人要标记这个问题)
我认为需要澄清的是:冲突和合并策略是 git 本身的概念。“合并请求”,OTOH,是 gitlab 的一个概念(其他存储库主机也有类似的概念),但对 git 本身没有任何意义。你的问题最好通过谈论 git 来回答;所以我们只需要知道合并请求是一个工作流程,通过它可以在 git 中启动合并操作。所以让我们把你的问题分成两部分:
顺序合并
简短的回答:可能会发生冲突。
是否会发生冲突取决于合并策略。我的测试表明通常会存在冲突,因为 git 在第 101 - 150 行中看到了替代更改。由于两组更改都是添加的,我猜您可以想象添加两组行时不会发生冲突 - 尽管不清楚它们的顺序你可以让 git 尝试使用union合并驱动程序来做到这一点;请参阅http://kernel.org/pub/software/scm/git/docs/gitattributes.html
您可以告诉 git 通过命令行参数以不同的方式解决合并,但由于这些指示将适用于整个提交 - 而不仅仅是设置此条件的一个文件 - 您通常不希望这样做。.gitattributes如果您可以提前知道该方法何时适合(整个)文件,您可以用来影响 git 合并单个文件的方式。
因此,对于如何改变 的行为有很多选择merge- 在不知道具体所需结果的情况下,这里无法详细说明。但根据我的经验,通常使用默认合并设置并在发生冲突时解决冲突效果很好。
并发合并
在单个存储库中“同时”发生两次合并实际上是不可能的。如果主机提供了某种方法origin来直接在托管 () 存储库上启动合并 - 我实际上不知道有人这样做,但为了争论 - 那么一个合并必须首先完成,另一个合并会看到该合并的结果作为其起点;所以请参阅答案的前一部分。
可能发生的情况是,一个人可以在一个存储库上执行一次合并,另一个人可以在第二个存储库上执行另一次合并,然后当他们都尝试与远程同步时可能会发生冲突。看起来可能是这样的:
(请注意,在整个示例中,我假设真正的合并- 即如果使用该no-ff选项会发生什么。合并图可能会更简单,但如果快进合并是的话,就冲突而言,结果将是相同的允许。)
所以回购协议开始于
B <--(branch_B)
/
x -- x -- O <--(master)
\
A <--(branch_A)
Run Code Online (Sandbox Code Playgroud)
所有提交都包含一个文件。该O文件有 100 行。 A并B在文件末尾添加 50 行新行。
现在,Alice 合并branch_A,Bob 合并branch_B,每个都在其本地存储库中。所以爱丽丝有
B <--(branch_B)
/
x -- x -- O -- MA <--(master)
\ /
A
^-(branch_A)
Run Code Online (Sandbox Code Playgroud)
鲍勃有
v-(branch_B)
B
/ \
x -- x -- O -- MB <--(master)
\
A <--(branch_A)
Run Code Online (Sandbox Code Playgroud)
为了分享他们的工作,他们每个人都会push尝试origin:就像merges 一样,即使他们试图在完全相同的时刻开始推动,一个人也会在另一个人开始之前先完成。
因此,爱丽丝得到了她的推动,并origin进行了更新,看起来就像她的本地人一样。当 Bob 尝试推送时,他会收到错误,因为他master落后于masteron origin(或者,我们可以说,origin/master一旦更新就落后,假设典型的映射)。
所以鲍勃必须pull(或fetch和merge)才能做到push。为了最清楚地说明,我们假设他fetch是。现在他有
v-(branch_B)
B
/ \
x -- x -- O -- MB <--(master)
|\
| MA <--(origin/master)
|/
A <--(branch_A)
Run Code Online (Sandbox Code Playgroud)
为了完成 a 的效果pull,他需要合并origin/master到master- 所以即使这种情况也可以归结为首先涵盖的“顺序合并”场景。事实上,如果您使用快进合并跟踪相同的场景,那么很明显,如果所有操作均由一个用户在一个存储库中完成,则此处所需的“第二次合并”与“第二次合并”完全相同。