分支合并-rebase

merge会使得log错综复杂,但是会保留时间线

rebase会保持log为一条线,但是最后log上的节点不是最原始commit的节点,不保留时间线。当前分支的节点会被复制到rebase 分支的节点后面,然后将原始的commit节点删除。

 

假设现在本地仓库中有两个分支:master分支和branch1分支,提交历史用图来表示如下 

1. git merge

现在要合并dev_test1到dev分支,如果使用merge,命令如下:(dev是父分支、dev_test1是子分支或者dev是源端分支、dev_test1是相对应的本地分支,这两种场景都是这样)

git checkout dev
git merge dev_test1

执行完上述两行命令之后,查看log,会产生如下结果:

$  git log --oneline --graph -4
*   2b22529 Merge branch 'dev_test1'
|\  
| * 39b3ec9 add file ttt.txt dev_test1
* | d0ff983 modify myTest.txt 1 dev
|/  
* 0d5f874 modify myTest.txt

此时dev上提交历史如下:

可以看到,日志就出现了两个分支,而且查看详细日志会发现log节点会根据时间自动排序,这样会产生两个问题:其一为log特别复杂,各种合并节点、分支线等等;其二为某分支合并过来的日志会被按时间分散,很难再master上查找某个分支的完整提交日志。

 

2. git rebase

如果使用rebase,【git rebase A B 代表寻找到A和B的共同祖先,然后将这段期间B的提交加到A的后面。通常B被省略,代表当前分支】

2.1 场景1(dev为父分支,dev_test1是基于dev的子分支),先拉取dev到dev_test1

$ git checkout dev_test1
$ git rebase dev
First, rewinding head to replay your work on top of it...
Applying: add file ttt.txt

此时再查看log:

$ git log --graph --oneline -4
* bbd022c (HEAD -> dev_test1) add file ttt.txt
* d0ff983 (origin/dev, dev) modify myTest.txt 1
* 0d5f874 (origin/dev_test1) modify myTest.txt
* 6ea82bf modify myTest.txt

确认之后,执行git push推送至远端。此时dev_test1上的日志就是一条线了,本分支的节点被重新创建新增到rebase的那个分支节点后。

之后在切回dev分支,执行rebase dev_test1

$ git checkout dev
$ git rebase dev_test1
$ git log --oneline --graph -4
* bbd022c (HEAD -> dev, origin/dev_test1, dev_test1) add file ttt.txt
* d0ff983 (origin/dev) modify myTest.txt 1
* 0d5f874 modify myTest.txt
* 6ea82bf modify myTest.txt

可以看到,在dev_test1执行git rebase后的节点bbd022c,现在是跟在dev分支节点后的,这样就保证了子分支的节点会出现在父分支的后面。如果直接在dev分支执行git rebase dev_test1,此时dev_test1上的节点会跑到dev前边去,不大合理

2.2 场景2,dev与origin dev间执行rebase。

我切了一个origin/dev对应的本地分支dev

$ git checkout dev

然后再本地有一条修改,可以看到远端dev的位置在bbd022c节点上

$ git log --oneline -4
9aec5ac (HEAD -> dev) modigy myTest.txt
bbd022c (origin/dev,origin/dev_test1, dev_test1) add file ttt.txt
d0ff983 modify myTest.txt 1
0d5f874 modify myTest.txt

而此时其他人往远端分支push了一条记录,我们现在想要提交修改到远端。首先把远端的变化fetch到,注意一定要用fetch,不能使用git pull(因为它=git fetch+git merge,或者使用git pull -r也可以,它=git fetch + git rebase),这样的话就执行了merge,本地分支的log就出现了两条线)

$ git fetch
$ git log --oneline -4
bbd022c (HEAD -> dev, origin/dev_test1, dev_test1) add file ttt.txt
d0ff983 modify myTest.txt 1
0d5f874 modify myTest.txt
6ea82bf modify myTest.txt

查看日志,可以看到现在远端的 origin/dev已经不再bbd002c节点上了,此时我们执行rebase

$ git rebase origin/dev
First, rewinding head to replay your work on top of it...
Applying: modigy myTest.txt

$ git log --oneline -4
7d2c7c5 (HEAD -> dev) modigy myTest.txt
8c1a80f (origin/dev) modify ttt.txt
bbd022c (origin/dev_test1, dev_test1) add file ttt.txt

查看日志发现,此时origin/dev的最新节点为8c1a80f,而我们自己修改的节点为7d2c7c5,然后再git push,提交到远端

$ git push

$ git log --oneline --graph -4
* 7d2c7c5 (HEAD -> dev, origin/dev) modigy myTest.txt
* 8c1a80f modify ttt.txt
* bbd022c (origin/dev_test1, dev_test1) add file ttt.txt
* d0ff983 modify myTest.txt 1

可以看到现在log就只有一条线了。

但是你虽然将这一条线push到了远端,那其他人怎么同步你的修改呢?也是一样的,执行git rebase

$ git rebase origin/dev
First, rewinding head to replay your work on top of it...
Fast-forwarded dev to origin/dev.

$ git log --oneline --graph -4
* 7d2c7c5 (HEAD -> dev, origin/dev) modigy myTest.txt
* 8c1a80f modify ttt.txt
* bbd022c (origin/dev_test1) add file ttt.txt
* d0ff983 modify myTest.txt 1

刚刚提交那条记录的人,直接执行git rebase之后,本地分支和远端分支就在同一个节点上了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值