接下来你决定将server分支中的修改也整合进来。使用git rebase [basebranch] [topicbranch]命令可以直接将特性分支(即本例中的server)变基到目标分支(即master)上。这样做能省去你先切换到
server 分支,再对其执行变基命令的多个步骤。
结果如下:
最后我们进行快速合并以及删除server,client分支。 $ git checkout master $ git merge server $ git branch -d client $ git branch -d client
最终的提交历史:
奇妙的变基也并非完美无缺,要用它得遵守一条准则:不要对在你的仓库外有副本的分支执行变基。否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你
先简单说说这个意思,试想,A团队在本地进行了一次三方合并,然后push到远程服务器,B团队发现仓库有更改,通过git pull将新的提交拉到本地进行合并。可不久,A团队想对发到远程服务器的版本做做变基,把上次的三方合并修改成了变基,再次push到远程服务器。B团队发送远程服务器版本又更新,而且自己上一次pull下来的一些提交不见了(rebase丢弃掉了),只好再次进行合并,但发现没有,A团队两次推送没有更改最后的提交内容,也就是说B团队合并了两次相同的提交(历史混乱,B团队尴尬),不仅如此,A团队是想清理掉一些提交历史的,但B团队还保留那些历史,等B团队push到远程服务器时,A团队看到自己rebase去掉的历史又出现了(A团队尴尬)。
这样说不太容易理解,下面通过图形进行描述。
克隆一个仓库,然后在它的基础上进行了一些开发
别人提交了一次合并,你抓取别人的提交,合并到自己的开发分支
有人推送了经过变基的提交,并丢弃了你的本地开发所基于的一些提交
你将相同的内容(C6,C4')合并了两次
此时如果你执行git log命令,你会发现有两个提交的作者、日期、日志居然是一样的,这会令人感到混乱。此外,如果你将这一堆又推送到服务器上,你实际上是将那些已经被变基抛弃的提交又找了回来,这会令人感到更加混乱。 很明显对方并不想在提交历史中看到C4和C6,因为之前就是他把这两个提交通过变基丢弃的。
解决办法:用变基解决变基,执行git rebase teamone/master,Git将会
检查哪些提交是我们的分支上独有的(C2,C3,C4,C6,C7)
检查其中哪些提交不是合并操作的结果(C2,C3,C4)
检查哪些提交在对方覆盖更新时并没有被纳入目标分支(只有 C2 和 C3,因为 C4 其实就是 C4')
把查到的这些提交应用在 teamone/master 上面
当然这个办法有一个前提,那就是C4'和C4要几乎一样,否则变基无法识别。还有一个缓解疼痛的方法,同git pull --rebase替换git pull,这个方法不会产生新的提交,也是变基。当然,最好的办法还是那条准则:不要对在你的仓库外有副本的分支执行变基!
6.6 合并冲突当然在合并的过程中,可能会出现合并冲突的。合并冲突时,git merge命令会显示是在哪个文件产生的冲突,我们来通过例子来试一试。
$ git checkout master #接着上面的git rebase Switched to branch 'master' Your branch is ahead of 'origin/master' by 4 commits. (use "git push" to publish your local commits) $ git merge testing Updating ce53a90..972909a Fast-forward README | 1 + 1 file changed, 1 insertion(+) $ git branch -d testing Deleted branch testing (was 972909a). $ git checkout -b newtesting Switched to a new branch 'newtesting' $ echo "print("newtesting")" >> README $ git commit -am "Newtesting commit" warning: LF will be replaced by CRLF in README. The file will have its original line endings in your working directory. [newtesting 1aaf545] Newtesting commit 1 file changed, 1 insertion(+) $ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 5 commits. (use "git push" to publish your local commits) $ echo "print("master")" >> README $ git commit -am "master commit" warning: LF will be replaced by CRLF in README. The file will have its original line endings in your working directory. [master 3883017] master commit 1 file changed, 1 insertion(+) $ git merge newtesting Auto-merging README CONFLICT (content): Merge conflict in README Automatic merge failed; fix conflicts and then commit the result.