鉴于两个分支已经分歧,并且需要将一个分支(而不是所有内容)的特定提交引入另一个分支,git cherry pick正是如此。
经过一段时间后,需要完全合并这两个分支。 git将如何知道它已经过去曾经提交过的提交,以便它不会重新引入它?
答案 0 :(得分:28)
avoiding duplicate commit中提到的“tonio's answer”文章说:
想象一下,我们有主分支和分支b:
o---X <-- master
\
b1---b2---b3---b4 <-- b
现在我们迫切需要master中的提交b1和b3,而不是b中的剩余提交。所以我们做的是检查主分支和樱桃选择提交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
(在this thread之后)
OP在评论中添加:
但似乎我还不太明白rebase是如何工作的......我的意思是即使在变调之后,樱桃选择的提交仍然不会出现吗?
没有。 git commit
man page明确提到:
如果上游分支已包含您所做的更改(例如,因为您邮寄了上游应用的补丁),则会跳过该提交。<登记/> 例如,在以下历史记录中运行git rebase master(其中A'和A引入相同的更改集,但具有不同的提交者信息):
A---B---C topic
/
D---E---A'---F master
将导致:
B'---C' topic
/
D---E---A'---F master
您可以使用git cherry master
检测主设备上是否已存在提交(如果您在topic
分支上)。
答案 1 :(得分:16)
您可能想要阅读
Git Cherry-pick vs Merge Workflow在merge和cherry-pick之间进行了很好的比较,特别是那个cherry-pick不存储父ID,因此不知道它已经提交了过去挑选的樱桃,以便它不会重新引入它。
和
http://davitenio.wordpress.com/2008/09/27/git-merge-after-git-cherry-pick-avoiding-duplicate-commits/关于如何使用rebase
避免重复提交。