Git rebase和merge的表现

时间:2021-08-09 20:34:52

 前边讲过git的一大优势就是分支管理,分支管理离不开合并,前边已经讲过了merge的合并以及冲突解决,今天咱们就来讲讲rebase。

先来看看merge合并的过程:

本地仓库有个develop分支,我以develop分支为源,新建一个fromdevelop分支(分支名取名根据自己实际情况,我是为了方便大家区分),然后我这两个分支各自修改并commit。如下develop分支commit两次修改

zxdeMacBook-Pro:hswallpager zs$ git log
commit 35a4231eb23a50729a4cc2ebe80e207c39710506
Author: zhangshun <hbzhangshun@126.com>
Date: Mon Feb 27 10:03:35 2017 +0800

develop branch second commit

commit 9506e73ca5a0223e7cc5af2e5ce9d702b0c696d8
Author: zhangshun <hbzhangshun@126.com>
Date: Mon Feb 27 10:02:38 2017 +0800

develop branch first commit

如下是fromdevelop分支两次修改:

zxdeMacBook-Pro:hswallpager zs$ git log
commit 6deb95d875165a57a512ddc8229e16db30b583ab
Author: zhangshun <hbzhangshun@126.com>
Date: Mon Feb 27 10:15:41 2017 +0800

fromdevelop branch second commit

commit e831462e2c8e0ffa6803aba7e9de237c129de8bc
Author: zhangshun <hbzhangshun@126.com>
Date: Mon Feb 27 10:13:05 2017 +0800

fromdevelop branch first commit


然后我们使用merge合并到develop分支:

zxdeMacBook-Pro:hswallpager zs$ git checkout develop
Switched to branch 'develop'
zxdeMacBook-Pro:hswallpager zs$ git merge fromdevelop
Auto-merging app/src/main/java/Activity.java
CONFLICT (content): Merge conflict in app/src/main/java/Activity.java
Automatic merge failed; fix conflicts and then commit the result.
zxdeMacBook-Pro:hswallpager zs$ git add .
zxdeMacBook-Pro:hswallpager zs$ git commit -m "merge 合并方式"
[develop 59a35b2] merge 合并方式
zxdeMacBook-Pro:hswallpager zs$ git log --graph --pretty=oneline
* 59a35b2dd146cbf1964e36879672912fd1a57fc0 merge 合并方式
|\
| * 6deb95d875165a57a512ddc8229e16db30b583ab fromdevelop branch second commit
| * e831462e2c8e0ffa6803aba7e9de237c129de8bc fromdevelop branch first commit
* | 35a4231eb23a50729a4cc2ebe80e207c39710506 develop branch second commit
* | 9506e73ca5a0223e7cc5af2e5ce9d702b0c696d8 develop branch first commit
|/


注意看上图的合并后的分支结构图,因为我们使用merge合并,我们fromdevelop的所有commit都已经加到了mster的分支log里。然后我们修改最后继续回到mster主线,产生冲突,然后解决冲突后生成一个新的commit记录及message为"merge 合并方式"。

接下来我们看看reabse合并方式:

同样我以develop为源,创建develop-02分支,同样每个都增加两个commit,修改后查看分支流图:

zxdeMacBook-Pro:hswallpager zs$ git log --graph --pretty=oneline
* 1976db2eafe93ca1e374cdd87ee708220f42a991 develop branch second commit rebase
* b5dcd26e42c715831ca24810d3080fd25dd92346 develop branch first commit rebase
* 4ebdf8f35ec97c73bb7050530b7093e0c16a0280 fromdevelop-02 branch second commit
* 6d4f50ae6c73ee4603052ca0cf334c069f34c1c1 fromdevelop-02 branch first commit
* 59a35b2dd146cbf1964e36879672912fd1a57fc0 merge 合并方式
|\
| * 6deb95d875165a57a512ddc8229e16db30b583ab fromdevelop branch second commit
| * e831462e2c8e0ffa6803aba7e9de237c129de8bc fromdevelop branch first commit
* | 35a4231eb23a50729a4cc2ebe80e207c39710506 develop branch second commit
* | 9506e73ca5a0223e7cc5af2e5ce9d702b0c696d8 develop branch first commit
|/


重点看上边最新的四条commit,是否已经看出区别,此时合并的流是相当干净的commit history,是线性的,而且修改冲突后,执行git add和git rebase --continue,不会有新的commit。


rebase和merge的差别主要是:

  • rebase更清晰,因为commit历史是线性的,但commit不一定按日期先后排,而是当前分支的commit总在后面。也就是上图的develop分支的commit在最后边显示。
  • merge之后commit历史变得比较复杂,并且一定程度上反映了各个分支的信息,而且 commit按日期排序的。
上述讲了git merge和git rebase在commit history上的表现。另外在解决冲突上的表现也略有不同,在rebase的过程中,也会遇到conflict,这时候,git会停止rebase,并提示先解决冲突,让后git add 到索引区,这时候跟merge不同,你无需在执行git commit而是执行git rebase  --continue,这样的话,git会继续apply余下的补丁。如果放弃rebase,只需要执行git rebase --abort。