- 前提條件:
存在兩個本地分支:
master --> origin/master
dev --> origin/dev
1. git rebase
- 執(zhí)行流程
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分支,并沒有產(chǎn)生合并記錄。
這時候我再執(zhí)行
git pull發(fā)現(xiàn)git log里面有多了一個分叉,如下圖:

image.png
這是因為git pull = git fetch+git merge,這里會將遠程master分支,即origin/master與本地master合并,因此會產(chǎn)生一個合并記錄。產(chǎn)生分叉是因為合并的時候兩個Test 2提交記錄來自不同的上游
2. git merge (--Fast-forward 是默認參數(shù))
在上面的基礎上繼續(xù)執(zhí)行:
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。
我又重復了以上的操作,發(fā)現(xiàn) Test 4的合并分叉,Test4是上游也是指向了Test 3。
Test 5亦然。
這是否說明每次git merge (--Fast-forward) 都是有跡可循,不會丟失合并記錄呢?
不是的。下面我們看往下的操作:
我先創(chuàng)建一個本地test分支
git checkout -b test
這時候本地的test分支和master分支都是從同一個head出來的,即:

image.png
這時候,我在繼續(xù)以下操作:
vim README.md
git commit README.md -m "Test 6"
git checkout master
git merge test
發(fā)現(xiàn):

image.png
對,沒錯,丟失了這次合并操作,只是單純的把提交合并過來了。
我接著又切到test分支重復著進行了以上操作,發(fā)現(xiàn),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 會讓合并強行留痕。