挑选工作后,git如何合并?
假设我们有一个master
分支。
然后我们创build一个新的newbranch
git checkout -b newbranch
并提交两个新的提交到新newbranch
: commit1和commit2
然后我们切换到主人并cherry-pick
git checkout master git cherry-pick hash_of_commit1
看着gitk
我们看到commit1和它的cherry-pick版本有不同的哈希,所以在技术上它们是两个不同的提交。
最后我们把newbranch
合并到master
:
git merge newbranch
并且看到这两个不同哈希的提交没有问题合并,尽pipe它们暗示着同样的修改应该应用两次,所以其中一个应该失败。
git是否真的在合并的时候对提交的内容做了一个明智的分析,并决定不应该改变两次,或者这些提交被内部标记为链接在一起?
简短的回答
别担心,Git会处理它。
长答案
不像例如SVN 1 ,Git不以delta格式存储提交,而是基于快照 2,3 。 虽然SVN会天真地尝试将每个合并的提交作为补丁应用(并且出于您描述的确切原因而失败),但Git通常能够处理这种情况。
合并时,Git将尝试将两个HEAD提交的快照合并到一个新的快照中。 如果代码或文件的一部分在两个快照中是相同的(即,因为提交已经被挑选出来),Git将不会触及它。
来源
1 Subversion中的Skip-Deltas
2个 Git基础
3 Git对象模型
合并之后,你可能会有两次历史上的挑剔的承诺。
解决scheme,以防止这个我引用文章 ,build议分支与重复(樱桃采摘)提交使用rebase之前合并:
git樱桃挑选后git merge:避免重复的提交
想象一下,我们有主分支和一个分支b:
o---X <-- master \ b1---b2---b3---b4 <-- b
现在我们迫切需要master中的提交b1和b3,而不是b中的其余提交。 所以我们要做的就是签出master分支并挑选提交b1和b3:
$ git checkout master $ git cherry-pick “b1's SHA” $ git cherry-pick “b3's SHA”
结果将是:
o---X---b1'---b3' <-- master \ b1---b2---b3---b4 <-- b
假设我们对master进行了另一次提交,我们得到:
o---X---b1'---b3'---Y <-- master \ b1---b2---b3---b4 <-- b
如果我们现在将分支b合并到master中:
$ git merge b
我们会得到以下内容:
o---X---b1'---b3'---Y--- M <-- master \ / b1----b2----b3----b4 <-- b
这意味着b1和b3引入的变化会在历史中出现两次。 为了避免这种情况,我们可以改变而不是合并:
$ git rebase master b
这将产生:
o---X---b1'---b3'---Y <-- master \ b2---b4 <-- b
最后:
$ git checkout master $ git merge b
给我们:
o---X---b1'---b3'---Y---b2---b4 <-- master, b