概述
把一个分支中的修改整合到另一个分支的办法有两种:merge 和 rebase(译注:rebase 的翻译暂定为“衍合”,大家知道就可以了。)。在本章我们会学习什么是衍合,如何使用衍合,为什么衍合操作如此富有魅力,以及我们应该在什么情况下使用衍合。
同时,比如要要合并多个 commit,就可以用 git rebase -i head~2。
1 | git merge // 合并分支 |
git merge
使用 git merge 合并 master1 和 dev1 分支
1 | git checkout master1 |
如上图所示:
最新的快照 c2 和 c3,还有它们共同的祖先 c1 进行三方合并,合并的结果会产生以下新的 c5,同时太还会对你的 master1 分支上的合并线条产生不好的结果。
git rebase
我们现在使用 git rebase 来合并 master1 和 dev1 分支
1 | git checkout dev1 |
如上图所示:
它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支 dev1)后续的历次提交对象(这里只有一个 C3),生成一系列文件补丁,然后以基底分支(也就是主干分支 master1)最后一个提交对象(C2)为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象(C3’),从而改写 dev1 的提交历史,使它成为 master1 分支的直接下游.
把 C3 里产生的改变到 C2 上重演一遍。
现在回到 master1 分支,进行一次快进合并.
git rebase [startpoint][endpoint] –onto [branchName]
当我们想从 master1 分支上复制 b、c、d 节点复制到 dev1 分支上,如下图所示:
master1 分支:
1 | commit 302d0381120b55518924d0fa5d91aeb651e7d4fd (HEAD -> master1) |
dev1 分支:
1 | commit 1225ea20d48bd16fbcfe1465e84f06292c52fe42 (HEAD -> dev1) |
我们使用命令的形式为:
1 | git rebase [startpoint] [endpoint] --onto [branchName] |
其中,[startpoint][endpoint]仍然和上一个命令一样指定了一个编辑区间(前开后闭),–onto 的意思是要将该指定的提交复制到哪个分支上。
所以,在找到 b(7343021a9f5a65c6042bf62589ca02bd7bb95e7f)和 c(d422a0cb01609f9007b5acf8771428d04ef5d963)的提交 hash 后,我们运行以下命令:
1 | git rebase 0d00c05dc^ 302d0381 --onto dev1 |
如果有冲突解决冲突就解决冲突,如果没有就跳过这一步:
1 | git add . |
当前 HEAD 处于游离状态
,实际上,此时所有分支的状态应该是这样:
![git rebase [startpoint][endpoint] –onto [branchName]](../images/git/1-7.png
所以,虽然此时HEAD
所指向的内容正是我们所需要的,但是dev1
分支是没有任何变化的,git 只是将b-c-d
部分的提交内容复制一份粘贴到了dev1
所指向的提交后面,我们需要做的就是将dev1
所指向的提交 id 设置为当前 HEAD 所指向的提交 id 就可以了,即:
1 | git checkout dev1 |
这时候就完成了。git rebase [startpoint] [endpoint] --onto [branchName]
还有一种用法。
参考 >https://blog.csdn.net/endlu/article/details/51605861
git cherry-pick
如果只是复制某一两个提交到其他分支,建议使用更简单的命令:git cherry-pick
1 | git checkout '你的分支' |
git rebase -i [startpoint][endpoint] // 合并多个 commit
其中-i 的意思是–interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint][endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支 HEAD 所指向的 commit(注:该区间指定的是一个前开后闭的区间)。
在查看到了 log 日志后,我们运行以下命令:
未完待续。