【Git零基础教程】(6)Rebase

来源:互联网 发布:java软件设计大赛 编辑:程序博客网 时间:2024/05/16 15:49

Rebase的作用与之前提到的merge相似。它的作用是将一个分支的commits加到另一个分支上去。

比如我们有:
这里写图片描述

如果使用merge,结果如下图所示:
这里写图片描述

而如果使用rebase:

git  checkout  experimentgit  rebase  master

则结果如下图所示:
这里写图片描述

C4的改动内容会在C3上进行重做,产生C4’,而C4会被“删除”(C4与C4’的hash值并不同)
这时候我们可以使用

git  checkout  mastergit  merge  experiment

让master合并experiment,但此时从图中我们可以看出experiment已经“包含”master,所以实际上并不会合并发生,而是进行“fast-forward”,也就是让master直接指向C4’就行了。结果如下图:
这里写图片描述

我们再看一个复杂的例子:
这里写图片描述

假设我们此时想把client分支的C8、C9两个commits加到master分支中,我们可以:

git  rebase  --onto  master  server  client

它的意思是,把client分支中有的,server分支中没有的(即C8、C9),加到master上去。结果如下图:
这里写图片描述

然后再按上文进行一个“fast-forward”,让master指向C9’:

git  checkout  mastergit  merge  client

这里如果我们使用

git  checkout  mastergit  merge  client

会将C3的内容也加到master上去,而且结构图会显得比较复杂。

然后假如我们又想把server的内容也整合到master,可以使用:

git  rebase  master  server

这里相当于

git  checkout  servergit  rebase master

就可以将server也加上去了
这里写图片描述

然后进行“fast-forward”

git  checkout  mastergit  merge  server

最后进行清理,删除这两个已经无用的分支:

git  branch  -d  clientgit  branch  -d  server

你也可以指定<from_branch>而不使用默认参数HEAD(即当前所在的位置)
git rebase <to_branch> <from_branch>

如果要指定更详细的范围,比如下图中,想把C8、C9 rebase到master上:

这里写图片描述

可以使用git rebase --onto master server client
它的意思是将server..client rebase到 master (注:server..client在Git中的意思是client中含有的而server中不含有的那些commits,即C8、C9)


The Perils of Rebasing

使用rebase需要遵守一条准则:
不要rebase在你的本地仓库以外也存在着的commits。
换句话说,如果你将要rebase的commits曾经被你push到某个其他人也可能会使用的服务器上时,就不该使用rebase。

比如下图,假设在某服务器teamone上有人push了C4、C5、C6,你将它们pull到本地与本地的master(C2、C3,此时还没push到服务器上)合并成了C7后,如图:
这里写图片描述

这时候,该人删除了C6,改用rebase将C4 rebase到C5上,并且push到team1服务器上。在他的视角看来,这样做更干净了:
这里写图片描述

然而,当你pull服务器上的内容后,本地仓库变成了这样:

这里写图片描述
因为C4、C6早已存在你的本地仓库了。这时候结构变得相当混乱,很容易让人误解。虽然并不会让本地数据产生错乱。
因此,最好遵守该准则:
不要rebase在你的本地仓库以外也存在着的commits。

如果已经发生了这种情况,那么可以用

git  fetchgit  rebase  teamone/master

git pull --rebase

git会自动分析,并帮你整理成这样:
这里写图片描述

最后总结一下,git merge和 git rebase各有各的优势,你应该根据你想要让commit history看起来如何来选择使用哪个,并且如果用rebase的话不要忘了那条准则。

原创粉丝点击