git merge 与 git rebase的区别

34次阅读

共计 1649 个字符,预计需要花费 5 分钟才能阅读完成。

前言
其实这个问题困扰我有一段时间,相信也有人和我一样有这个困扰,网上已有很多这种解释了,但是要么就是无图,要么就是解释的很乱,没太看懂,经过自己对 git 的使用,加上向同事请教,算是理解了这个问题,所以写下来分享一下,我尽量详细说明
merge 与 rebase 的区别
假设我们有如下图一所示仓库,该仓库有 master 和 develop 两个分支,且 develop 是在(3.added merge.txt file)commit 处从 master 拉出来的分支。

merge
假设现在 HEAD 在(6.added hello.txt file)处,也就是在 master 分支最近的一次提交处,此时执行 git merge develop, 结果如下图所示。

工作原理就是:git 会自动根据两个分支的共同祖先即 (3.added merge.txt file) 这个 commit 和两个分支的最新提交即 (6.added hello.txt file) 和 (5.added test.txt file) 进行一个三方合并,然后将合并中修改的内容生成一个新的 commit,即图二的 (7.Merge branch‘develop’)。这是 merge 的效果,简单来说就合并两个分支并生成一个新的提交。
rebase
那 rebase 是这么工作的呢?假设初始状态也是图一所显示的。两个分支一个 master,一个 develop,此时 HEAD 在(6.added hello.txt file)处,现在执行 git rebase develop, 结果如下图三所示。
可以看见 develop 分支分出来分叉不见了,下面来解释一下它的工作原理:在执行 git rebase develop 之前,HEAD 在(6.added hello.txt file)处,当执行 rebase 操作时,git 会从两个分支的共同祖先 (3.added merge.txt file) 开始提取 当前分支(此时是 master 分支)上的修改,即(6.added hello.txt file)这个 commit,再将 master 分支指向 目标分支的最新提交(此时是 develop 分支)即(5.added test.txt file)处,然后将刚刚提取的修改应用到这个最新提交后面。如果提取的修改有多个,那 git 将依次应用到最新的提交后面,如下两图所示,图四为初始状态,图五为执行 rebase 后的状态。

简单来说,git rebase 提取操作有点像 git cherry-pick 一样,执行 rebase 后依次将当前的提交 cherry-pick 到目标分支上,然后将在原始分支上的已提取的 commit 删除。
merge OR rebase
那什么时候用 merge,什么时候用 rebase 呢?再举个例子:初始状态如下图六所示:和之前一样的是,develop 分支也是在 (3.added merge.txt file) 处从 master 分支拉取 develop 分支。不一样的是两个分支各个 commit 的时间不同,之前 develop 分支的 4 和 5commit 在 master 分支 3 之后 6 之前,现在是 develop 分支的 4 提交早于 master 分支的 5 提交,develop 分支的 6 提交晚于 master 的 5 提交早于 master 的 7 提交。
在上图情况下,在 master 分支的 7commit 处,执行 git merge develop,结果如下图七所示:
执行 git rebase develop,结果如下图八所示:

可以看出 merge 结果能够体现出时间线,但是 rebase 会打乱时间线。
而 rebase 看起来简洁,但是 merge 看起来不太简洁。
最终结果是都把代码合起来了,所以具体怎么使用这两个命令看项目需要。

还有一点说明的是,在项目中经常使用 git pull 来拉取代码,git pull 相当于是 git fetch + git merge,如果此时运行 git pull -r,也就是 git pull –rebase,相当于 git fetch + git rebase
最后推荐一些 git 可视化工具,我用的是 gitkraken,这些工具功能基本一样,看个人喜欢好使用

正文完
 0