问题描述
git merge 合并操作,是不是必须合并分支尖端(tip of branch),能否合并任意的两个提交commit?比如,存在分支hotfix和分支master,结构如下:
/A+--+B+----+C hotfix /
init---->D +--->E +--->F+---->G master
问题1:我想合并thotfix分支中途的某个提交,比如B到当前分支 master上。可以吗?因为从命令的参数解释上看,可以使用commit,而不是必须使用分支名 branchName。
问题2:如果还存在一个分支topic(图中没画出来),当前分支是master,我希望合并hotfix和topic分支,但不合并到当前分支master,同时不切换分支,要求保持当前分支仍然是master,是否可以做到?因为从命令的参数来看,可以接受多个 commits,manual中说,多个commit合并构成了一个章鱼合并,我就在想多个commits合并,是不是必须合并到当前分支。于是就有了这个问题。
问题解答
回答1:使用cherry-pick挑选你要的提交
回答2:首先,你这张图画得貌似有点儿问题,看不出来这两个 branch 是从 哪儿分离的。你应该使用 git cherry-pick 命令,而不是 merge。只能猜一下,是不是这样?
A - B - C hotfix /init - D - E - F - G master
后面的回答都基于这个猜测。如果和你的不同,请评论指出。
问题一:简单来说,最好用 cherry-pick。首先你要知道,git merge <hash> 和 git cherry-pick <hash> 是不同的。。如果你要在这里用 git merge B,那就会得到这样的结果:
A - B - C hotfix / init-D-E-F-G-G’ master
但如果你是 git cherry-pick B,就会得到这样的结果:
A - B - Chotfix /init - D - E - F - G - B’ master
merge 有它的优点,因为每一次 merge 其实都是创建一个新的 'merge commit',而且会 '保留历史',所以是一个 'non-destructive'(非破坏性)的过程。当然,cherry-pick 也有它的缺点,首先是创建一个新的 hash,这可能会导致多人协作的混乱。比如有人已经在 G 后面又加了 HJKL,那至少他还要 rebase 一下。另外,这个 B’ 也不会像 merge 那样保留自己的历史记录。因此,确切的说,这个 B’ 更像是一个 patch。(请参考 git format-patch https://git-scm.com/docs/git-...
我个人比较喜欢 cherry-pick 和 rebase 这样的命令,不太喜欢 merge,最主要是因为历史线简洁很多。虽然这两个命令比 merge 破坏性稍强,但稍微熟悉一点儿 git,知道每一步在做什么以及可能造成什么影响就好。
问题二:感觉是不行的。merge 不像 rebase 那样有类似于 --onto 这样的参数。还是切换过去再 merge 吧。
你后面说到章鱼合并,你说的是 --strategy=octopus 么?不太确定这个 strategy 和你要问的有什么联系。。因为多个 branch 的 merge 默认 strategy 就是 octopus。。不用去专门设置。。。顺便,对于单个 HEAD 的 merge,默认 strategy 是 recursive。
对于你说的多个 commits 合并,请详细描述一下你的需求。或者画个图补充一下