github上上傳了版本庫https://github.com/ChuckGitMerge 包括merge和rebase
沒時間畫圖,貌似也不太會用畫圖工具,先寫了一個文字版本的
更新:2015年08月11日,使用了git for windows自帶的git gui作為圖片說明
動畫效果
https://devblogs.microsoft.com/devops/pull-requests-with-rebase/
一、Fast Forward,No Fast Forward 和 Squash的對比
1.fast forward
假設從master分支有三個節點C1,C2,C3
從C3切出develop分支,並在develop分支上開發了C4,C5
現在切回master分支,將develop分支合並到master。默認使用fast forward,master分支會直接指向C5。master分支的節點為C1,C2,C3,C4,C5
develop分支和master分支,看起來是完全一樣的
2.no fast forward
假設從master分支有三個節點C1,C2,C3
從C3切出develop分支,並在develop分支上開發了C4,C5
現在切回master分支,將develop分支合並到master。如果使用no fast forward,在master分支上會生成一個新的commit為C6。master分支的節點為C1,C2,C3,C4,C5,C6
3.squash(第一種)
第一種squash,develop分支切出之后,master分支沒有新的提交
假設從master分支有三個節點C1,C2,C3
從C3切出develop分支,並在develop分支上開發了C4,C5
下面的圖的情況和fast forward以及no fast forward處理之前是一樣的
現在切回master分支,將develop分支合並到master。
如果使用聚合的方式進行合並的話,那么git會將develop分支上所有的commit壓縮成一個新的commit為C6直接合並到master分支。
最后master分支上的節點為C1,C2,C3,C6
從版本庫的分支歷史記錄,是無法看出develop合並到master分支上的記錄的。這是squash和其他合並方式的最主要的區別。
並且master和develop還保持着相互獨立
二、Three Way Merge和Squash的對比
1.three way merge
假設從master分支有三個節點C1,C2,C3
從C3切出develop分支,並在develop分支上開發了C4,C5
master分支在C3的基礎上開發了C6,C7這樣進行合並的話,是無法fast forward的。
合並方式:1.找到master分支的最新節點C7
2.找到develop分支的最新節點C5
3.找到master分支和develop分支的共同祖先節點C3
4.對C3,C5,C7進行三方合並,最后生成新的commitC8
2.squash(第二種)
第二種squash,develop分支切出之后,master分支也有了新的提交
假設從master分支有三個節點C1,C2,C3
從C3切出develop分支,並在develop分支上開發了C4,C5
master分支在C3的基礎上開發了C6,C7這樣進行合並的話
下面的圖的情況和three way merge處理之前是一樣的
合並方式,直接把develop上的2個結點的變化提取出來,然后直接應用在master分支上。
從版本庫的分支歷史記錄,是無法看出develop合並到master分支上的記錄的。這是squash和其他合並方式的最主要的區別。
並且master和develop還保持着相互獨立
參考資料
http://www.open-open.com/lib/view/open1328069889514.html git詳解之三 git分支
http://ariya.ofilabs.com/2013/09/fast-forward-git-merge.html Fast-Forward Git Merge
http://stackoverflow.com/questions/2850369/why-does-git-fast-forward-merges-by-default