git rebase、git merge --no-ff和git merge --Fast-forward 区别

  • 前提条件:
    存在两个本地分支:
master --> origin/master
dev --> origin/dev

1. git rebase

  • 执行流程
git checkout dev
vim README.md
git commit README.md -m "Test 1"
git push
git checkout master
vim README.md
git commit README.md -m "Test 2"
git push
git rebase origin/dev

git log查看的效果如图红色圈里的部分:

image.png

可以看到,git rebase就是把origin/dev分支的提交有机合并到本地master分支,并没有产生合并记录。
这时候我再执行git pull
发现git log里面有多了一个分叉,如下图:
image.png

这是因为git pull = git fetch+git merge,这里会将远程master分支,即origin/master与本地master合并,因此会产生一个合并记录。产生分叉是因为合并的时候两个Test 2提交记录来自不同的上游

2. git merge (--Fast-forward 是默认参数)

在上面的基础上继续执行:

git checkout dev
vim  README.md
git commit README.md -m "Test 3"
git push
git checkout master
git merge origin/dev
image.png

可以看到这次合并记录,顺着分叉可以看到Test 3的提交记录,由于Test 3 的提交是来自Test 1的下游,所以Test 3是指向Test1。
我又重复了以上的操作,发现 Test 4的合并分叉,Test4是上游也是指向了Test 3。
Test 5亦然。

这是否说明每次git merge (--Fast-forward) 都是有迹可循,不会丢失合并记录呢?

不是的。下面我们看往下的操作:
我先创建一个本地test分支

git checkout -b test

这时候本地的test分支和master分支都是从同一个head出来的,即:


image.png

这时候,我在继续以下操作:

vim  README.md
git commit README.md -m "Test 6"
git checkout master
git merge test

发现:


image.png

对,没错,丢失了这次合并操作,只是单纯的把提交合并过来了。

我接着又切到test分支重复着进行了以上操作,发现,Test 7的合并同样没有merge记录。
因此可以断言,假如两个分支来自同一个上游,那么用git merge (--Fast-forward)会丢失这次合并记录。

3. git merge --no-ff

接下来我再进行以下操作:

git checkout test 
vim  README.md
git commit README.md -m "Test 8"
git checkout master
git merge --no-ff test

这次结果如下:


image.png

好了,加上--no-ff就不会丢失本次合并操作记录啦。

4. 结论

  • git rebase是将被合并的的分支(我这里指origin/dev)的提交有机结合到当前分支(我这里是master),成为一条提交记录的时间线,这里没有合并记录,也没有分叉。
  • git merge (--Fast-forward) 则是合并的时候,如果被合并的两个分支来自同一个上游,那么合并操作会不留痕,这个有可能会让查问题不好查;
  • git merge --no-ff 会让合并强行留痕。

你可能感兴趣的:(git rebase、git merge --no-ff和git merge --Fast-forward 区别)