Git合并 - 合并的分支会发生什么?

4

我有一个关于Git合并的问题。假设我在我的存储库(本地和远程)中有两个分支:主分支和测试分支。而当我在测试分支上工作时,主分支被其他人更新了。在终端中,我输入:

git checkout master
git pull origin master

这会将最近添加的内容更新到我的主分支上吗?然后,我完成了测试分支中正在进行的工作。
如果我进入终端并输入:

git checkout master
git merge test
git push origin master

这将我的测试分支合并到主分支,然后将更改推送到GitHub,对吗(假设没有冲突)?我的问题是:测试分支会发生什么?它保持与合并之前相同的状态吗?还是测试和主分支都变成了相同的状态?我现在应该这样做来更新测试分支吗?
git checkout test
git pull origin master
git push origin test

提前感谢。


2
git checkout test git merge master...翻译为:除非您将主分支合并到测试分支,否则它将保持不变。 - n00dl3
如果我在将测试分支合并到主分支时出现冲突,那么当我将新的主分支合并到测试分支时,是否也会出现冲突? - Tirafesi
1个回答

12

如果我去终端并写入:

git checkout master
git merge test
git push origin master
这将把我的测试分支合并到主分支,然后将更改推送到 Github,对吧(假设没有冲突)?我的问题是:测试分支会发生什么?

完全不会有影响。

请记住,分支的名称只是单个提交的名称。为了画图方便,我喜欢用圆形的o节点来表示提交本身,或者在需要讨论特定提交时使用大写字母,它们之间用线连接:

...--o--o--o--o      <-- master
         \       
          o--o--o    <-- test
每个提交记录都“指向”其父提交记录——因此,如果我们给这些提交记录每个都命名为一个字母,并画出所有中间的箭头,我们就得到了:

每个提交记录都“指向”其父提交记录——因此,如果我们给这些提交记录每个都命名为一个字母,并画出所有中间的箭头,我们就得到了:

...<-A<-B<-C<-D      <-- master
         \
          E<-F<-G    <-- test
分支名mastertest实际上包含了这两个分支末端的原始哈希ID。也就是说,如果你检查文件.git/refs/heads/master1,你会在其中找到一个像a139fc7...这样的40个字符的哈希值。

实际上,master指向提交D,而test指向G。提交D指向提交CC又指向B,以此类推;而提交G则指向FF又指向EE再指向B(由于某些良好的绘制箭头字体只能在某些机器上使用,因此在此处使用纯文本绘制箭头过于复杂)。

当你位于某个分支并做出一个新的提交时,Git创建此提交的方式是:将其父提交设置为当前分支的末端,并且一旦新提交安全地存储在仓库中,就会重写分支的名称文件,使分支名指向新的末端。新的ID不会去到其他任何地方,因此其他分支的名称不会以任何方式更改。

合并提交有两个父提交,因此当你运行git merge test并且它运行成功时,你将得到以下结果:

...--o--o--o--o---o  <-- master
         \       /
          o--o--o    <-- test
注意,test 一点都没有移动,但是master 移动了—— 新的合并提交指向两个不同的早期提交:旧的分支顶部 master 和 (不变的)test 顶部。

1不能保证这个文件将来会存在,或者停留在这个位置或者保持这种格式,但现在,在今天的Git版本中,通过2.10,通常会有这个文件。


在这种情况下,最好的方法是什么?删除测试分支,然后创建一个新的分支?还是将主分支的更改也合并到测试分支中? - Tirafesi
这取决于您对test想要做什么(继续做、不再做或停止做)。如果您的test名称不在远程上(如果您从未推送它并且没有首先从那里获取它,因此没有origin/test可以用来与其他人协调),则决定完全由您自己做出。否则,请与其他用户进行协商,以确定您所有人都更喜欢什么。 - torek
@torek 所以,假设测试分支是本地的(从未被推送),在合并后,当您推送更改时,测试分支也会被推送,以维护2个父节点的引用?如果我删除它会发生什么? - Johnny Beltran
1
如果你不指定分支名称,那么默认使用的是当前分支。所以,如果你运行git checkout master; git merge test; git push,那么你现在运行的是git push origin master,因为你的当前分支master。这样你就要求origin将他们的master设置为与你的master相同。你的master标识了你刚刚创建的合并提交,因此这将创建或更新他们的master,假设他们没有拒绝你的请求。 - torek
1
@JohnnyBeltran:嗯,有些人 建议使用这种直线形式的变基技巧。其他人则坚持始终使用合并并保留它们。我认为应该使用最适合你和你的团队的方法 :-) - torek
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接