Git Rebase
git rebase
,就像从字面意思上理解的那样,它是把当前的修改记录重新找个分支做 base。原理是把
当前的修改记录做成 patch,然后在新 base 分支上 replay 一遍。这样做的好处是,在 merge 分支的
时候,比如要把 experiment 分支的修改 merge 到 master 分支上,相比于直接使用 git merge
命令,
使用 git rebase
之后再 merge 可以产生更加清晰的提交记录。下面我们来举例说明。
experiment
+----+
| C4 |
/ +----+
v
+----+ +----+ +----+ +----+
| C0 | <- | C1 | <- | C2 | <- | C3 |
+----+ +----+ +----+ +----+
master
如上图所示,当前 experiment 分支和 master 分支有共同的祖先 C2,现在我们想将 experiment 合到 master 分支,
我们有两种方法。第一种方法,是直接使用 git merge
命令:
$ git checkout master
$ git merge experiment
merge 完之后,会产生一条新的提交记录 C5
,如下图所示:
experiment
+----+
| C4 | <--
/ +----+ \
v \
+----+ +----+ +----+ +----+ +----+
| C0 | <- | C1 | <- | C2 | <- | C3 | <- | C5 |
+----+ +----+ +----+ +----+ +----+
master
第二种方法,我们可以先在分支 experiment 上用 git rebase
,然后再用 git merge
:
$ git checkout experiment
$ git rebase master
这样之后分支情况就变成了这样:
experiment
+----+ +----+ +----+ +----+ +----+
| C0 | <- | C1 | <- | C2 | <- | C3 | <- | C4'|
+----+ +----+ +----+ +----+ +----+
master
可以看到,之前分叉的 C4 已经移到 C3 后面,两个分支变成了一个,就好像 之前的分叉情况没有发生过一样。然后,我们再切换到 master 分支进行 merge:
$ git checkout master
$ git merge experiment
最后的结果如下:
experiment
+----+ +----+ +----+ +----+ +----+
| C0 | <- | C1 | <- | C2 | <- | C3 | <- | C4'|
+----+ +----+ +----+ +----+ +----+
master
这两种方法最后的代码是相同的,只是合并后的提交记录有所不同。 是在生产环境中,我们可以根据实际情况来进行选择使用哪种方法。
另外,如果在向开源社区提 patch 的时候,我们推荐使用第二种 rebase 的方法,因为从上述结果可以看到,rebase 之后的分支是线性的,所有可能 的冲突已经在你这边解决了,因此 maintainer 可以快速的进行 merge 操作。
以上。