把一个分支中的修改整合到另一个分支的办法有两种:merge和rebase,
当开发进程分叉到两个不同的分支,又各自提交了更新。
最容易的整合分支的方法是merge, 它会把两个分支最新的快照以及两者的共同祖先进行三方合并,合并的结果是产生一个新的提交对象。
其实还有另外一个选择,可以在一个分支里发生的变化补丁在另一个分支重新打一遍,这种操作叫做衍合,
rebase的作用就是把在一个分支里提交的改变放到另一个分支里重放一遍。
$ git checkout experiment $ git rebase master
它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支experiment)后续的历次提交对象,生成一系列文件补丁,然后以基线分支(也就是主干分支master)最后一个提交对象为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象,从而改写experiment的提交历史,使它成为master分支的直接下游。
衍合最后生成的快照,其实和普通的三方合并的快照内容一模一样。虽然最后整合得到的结果没有任何区别,
但是衍合能产生一个更为整洁的提交历史。如果观察一个衍合过的分支的历史记录,看起来会更清楚:仿佛所有修改都是在一跟线上先后进行的,尽管实际上他们原本是同时并行发生的。
一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁,比如某些项目你不是维护者,但是想帮点忙的话,最好使用衍合:先在自己的一个分支里进行开发,当准备向主项目提交补丁的时候,根据最新的origin/master进行一次衍合操作然后再提交,这样维护者就不需要做任何工作(实际上是把解决分支补丁同最新主干代码之间冲突的责任,转化为由提交补丁的人来解决),维护者只需要根据你提供的仓库地址进行一次快进合并,或者直接采纳你提交的补丁。
======== 衍合的风险=========
一旦分支的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
进行衍合的时候,实际上抛弃了一些显存的提交对象而创造了一些类似但不同的新的提交对象,
如果你把原来分支中的提交对象发布出去,并且其他人更新下载后在其基础上开展工作,而稍后你又用git rebase
抛弃这些提交对象,把新的重演后的提交对象发布出去的话,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容的时候,提交历史就会变得一团糟。
https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E8%A1%8D%E5%90%88
/workspace/xxx-xx-cms:the-channel-sort$ git push origin the-channel-sort To [email protected]:xxx-xxx-cms/xxx-xx-cms.git ! [rejected] the-channel-sort -> the-channel-sort (non-fast-forward) error: failed to push some refs to ‘[email protected]:xxx-xxx-cms/xxx-xx-cms.git‘ To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. ‘git pull‘) before pushing again. See the ‘Note about fast-forwards‘ section of ‘git push --help‘ for details. /workspace/xxx-xx-cms:the-channel-sort$ git fetch remote: Counting objects: 13, done. remote: Compressing objects: 100% (13/13), done. remote: Total 13 (delta 9), reused 0 (delta 0) Unpacking objects: 100% (13/13), done. From bitbucket.org:xxx-xxx-xxx/xxx-xx-cms * [new branch] production-deployment -> origin/production-deployment * [new branch] staging -> origin/staging /workspace/xxx-xx-cms:the-channel-sort$ git rebase origin/the-channel-sort First, rewinding head to replay your work on top of it... Applying: 重构代码 /workspace/xxx-xx-cms:the-channel-sort$ gitg /workspace/xxx-xx-cms:the-channel-sort$ git push Counting objects: 35, done. Delta compression using up to 4 threads. Compressing objects: 100% (18/18), done. Writing objects: 100% (18/18), 2.29 KiB, done. Total 18 (delta 14), reused 0 (delta 0) remote: remote: View pull request for the-channel-sort => master: remote: https://bitbucket.org/xxx-xxx-cms/xxx-xx-cms/pull-requests/21?t=1 remote: To [email protected]:xxx-xxx-cms/xxx-xx-cms.git 841dda2..95cdf0d the-channel-sort -> the-channel-sort