我开始通过使用git hub for Mac获得git hub的支持。我注意到merge branches选项允许你将一些分支,A合并到一些分支,B。你也可以用另一种方式,将分支B合并到一些分支A.有什么区别?我从git hub文档中找到了this,但它没有解释我想知道的内容。
答案 0 :(得分:2)
值得添加的是,git的分支标签不会存储在提交中。
在进入休息之前,让我们在内部记下提交的内容。它是一个描述(以复杂的方式)整个工作树 1 的存储版本的条目,以及:
"父母承诺"你是如何遵循一个分支的历史。 "定期"提交具有单个父级,即从中派生新工作树的先前提交。 "合并"提交至少有两个父母,一个" root"提交没有父母:它的树是从零开始的。
Git有很多方法可以命名任何单独的提交。 "真名"是SHA-1哈希,从问题中的图像中的9e17c4e
开始。该名称永远不会改变,事实上,它是对提交的全部内容的加密强校验和。 2
但是,这些SHA-1值很难打字(如果我需要,我会尝试剪切和粘贴)。所以通常有另一种方式来引用提交。 Git提供"分支"和"标记"命名作为给他们一个有意义的名字的方式。 git branch
和git tag
命令可以创建一个新的"引用名称"对于现有提交。分支只是存储在refs/heads/
中的引用(例如refs/heads/master
),而标记是存储在refs/tags/
中的引用。 (通过将这些引用存储在这样的目录层次结构中,git还允许在将来发明新类型的引用。实际上,refs/notes/commits
已经使用了git notes
,当然还有& #34;远程分支"存储在refs/remotes/
。)
"分支"之间的主要(用户级)差异和#34;标签"是一个标记假定是永久性的,而一个分支是假定移动。 refs/heads/
中的分支 - 引用 - 当您在分支上时添加新提交时,会自动移动 <#34;&#34;。如果你告诉git进入分支B
,然后向分支B
添加新的提交,git进行新的提交,然后将分支标签移动到新的承诺。如果您愿意,可以将分支标签视为一种粘滞便笺,即git剥离并放置分支的新端/尖端。
这正是Cupcake illustrates。如果你在分行B
&#34;&#34;并且你git merge A
,合并将一个新的提交 3 添加到B-specific,一个&#34; merge commit&#34;,有两个父提交。然后,因为你在&#34; on&#34;在分支中,git将分支标签移动到新的提交。现在,名称B
引用合并提交及其两个父项。
同样,如果您在分支A
和git merge B
上,则合并会添加新提交。它几乎完全相同的提交 - 事实上,它具有完全相同的树,当然还有相同的作者和提交者。如果你以某种方式设法做到这一点 - 在一个平行的宇宙中,也许: - ) - 在同一时间,它甚至有相同的时间戳。但还有另外一个区别。 虽然新提交将具有相同的两个父项,但它们将按其他顺序排列。当然,git将移动分支标签,但此时标签为A
而非比B
。
父母的命令很重要。也许不是很多,而且对于普通的&#34;提交,只有一个父母,首先没有什么可订购的。但是它们会影响SHA-1校验和,它们也会影响父级遍历&#34;。当通过这个父提交链向后追踪一个分支时,git具有&#34;第一个父级&#34;的概念,并且各种命令采用标志--first-parent
来限制父级跟随。
请记住,分支标签实际上只标记一个,单个,提交:分支顶端的一个。一组提交&#34; on&#34;通过跟随父母,根据需要动态导出该分支。在合并提交中,有多个父级,分支可以包含所有其父级 - 同时跟随所有父级 - 或者,对于简单情况,只需第一个家长。通过这种方式,您可以找到分支机构上的内容&#34;合并前#34;带来&#34;其他一些分支上的所有内容。
所以,这是为什么(以及 时)合并中的订单:当您想要查看&#34时;在分支机构&#34; &#34;前&#34;合并,你可以假设只有第一个父母才能得到你。
(虽然有一些皱纹。特别是,&#34;快进&#34;合并不会创建合并提交,它只是拉动分支标签&#34;转发&#34;。 ,由于分支标签完全是在密码校验和系统之外,任何人都可以随时重新标记任何分支,并且git repo中没有记录。在&#中有记录34; reflog&#34;,但是reflog条目会随着时间的推移而过期,并且可以被清除:它们意味着如果你不小心摔倒在地,帮助你解决问题,而不是为了防止你偷偷摸摸和混乱但是这已经太久了,我还没有达到我的脚注......)
1 从技术上讲,提交树会记录分段索引的内容。这就是为什么你git add
和git rm
的事情,把它们放在舞台上#34;并按照您喜欢的方式排列树,然后才git commit
分段索引。
2 &#34;内容&#34;涉及到各部分的SHA-1校验和,因此这部分是校验和的校验和。我不是密码学家,但据我所知,这通常会降低加密强度。但是,它并不是为了安全。这些校验和是使git工作所必需的。如果两个不同的底层git对象(文件又名&#34; blob&#34;,树,注释标签和提交)总和相同,git将会中断。
3 这假设一个非常重要的&#34;合并不会导致&#34;快进&#34;。合并&#34;功能分支时会发生简单的合并。回到主要分支&#34;主分支没有工作:
A--B master
\
C--D--E feature
如果你只是git checkout master
然后git merge feature
,git会注意到master
是&#34;直接祖先&#34; feature
的{{1}},因为它可以从提交E
(feature
引用的提交)开始,然后向后工作并达到提交B
(您提及的那个) #39;在&#34; on&#34;当你在分公司大师的时候#34;)。在这种情况下,git merge feature
只会将标签剥离提交B
并将其粘贴到提交E
上。
强迫&#34;真实&#34;合并,你仍然git checkout master
以便进入分支master
,然后使用git merge --no-ff feature
,与两个父母一起创建一个新的合并提交M
:
A--B---------M master
\ /
C--D--E feature
&#34;第一&#34;现在,您可以通过编写master^
或master~1
来命名父级,即提交B
。 &#34;第二&#34;现在,您可以通过编写master^2
或feature
来命名父级,即提交E
。请注意,master~2
引用提交A
:代字号在第一个父代之后。 (您可以使用稍微笨拙的D
或master^2^
命名提交master^2~1
,依此类推。有关指定修订的更多方法,请参阅git rev-parse的文档。)< / p>
答案 1 :(得分:0)
如果将分支A合并到B中,则只有B的分支更新为新的子提交,而如果将分支B合并到A中,则只有A的分支更新为新的子提交。
这是图表形式的样子,从未合并的分支开始:
---o---o A
\
o B
现在让我们将分支A合并到B(带git merge A
):
---o---o A
\ \
o---o B
查看B如何更新为新的子提交,而A保持不变?
现在让我们看看如果我们通过将B合并为A(使用git merge B
)来反过来会发生什么:
---o---o
\ \
o---o A
B
在这种情况下,A已更新为新的子提交,而B保持不变。从这里开始,您还可以将A合并到B中,这将使B快进以与A进行相同的提交:
---o---o
\ \
o---o A, B
使用^
修订说明符时,合并的顺序也可能会影响哪个父提交被认为是第1次到第2次:
head^
和head^1
都指代子提交的第一个父级。head^2
指的是子提交的第二个父级。但是,就提交图而言,合并的顺序没有区别,您仍然会得到一个指向两个父项的子提交。
答案 2 :(得分:0)
有区别。如果将A合并到B中,A将保持不变,B现在将从分支A进行更改。