git merge 和 git rebase 是使用率很是高的兩條指令 本文對git merge的平常使用場景作一個梳理,git rebase請看 Git自學成才——rebase完整版html
假設我有一個開發分支dev,有一個主幹分支mastergit
關於哪一個分支合併到哪一個分支,不少人會有混淆和困惑。其實,你須要往哪一個分支上面合併,就要切換到哪一個分支bash
好比,如今要 把dev分支merge到master分支spa
首先,保證兩個分支都是最新的狀態3d
切換到master分支,執行merge操做指針
git checkout master
git merge dev
複製代碼
git merge
命令用於合併指定分支到當前分支code
上面是最基本的git merge,git merge默認採用快進(fast-forward)的方式,產生相似以下的logcdn
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
複製代碼
何爲 快進(Fast-forward)?htm
在合併的時候,你應該注意到了"快進(fast-forward)"這個詞。 因爲當前master分支所指向的提交是你當前提交的直接上游,因此 Git 只是簡單的將指針向前移動。 換句話說,當你試圖合併兩個分支時,若是順着一個分支走下去可以到達另外一個分支,那麼 Git 在合併二者的時候,只會簡單的將指針向前推動(指針右移),由於這種狀況下的合併操做沒有須要解決的分歧——這就叫作 「快進(fast-forward)」。blog
若是merge的時候沒有衝突, 沒有新的commit節點產生,只是移動分支的指針,來實現merge
若是merge的時候有衝突, 產生相似以下的log
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
複製代碼
須要手動解決衝突,而後執行add,再commit
git add index.html
git commit -m "conflict fixed Your message..."
複製代碼
基本知識瞭解完,來看一下實戰中的三種操做
不少公司或者組織會大量使用分支,他們不喜歡在master分支看到錯綜複雜的merge節點,因此他們的要求是無節點的merge(看起來全部的commit都是一條直線),這樣的視覺效果清晰可讀性很強。
實現無節點merge,實際上是用到merge指令的默認特性——快進(Fast-forward),由於快進方式的merge不會產生節點,只會移動分支的HEAD指針。
問題是,快進的特性是在沒有衝突的狀況下產生,而執行merge大機率的狀況會有不少衝突。這裏搭配rebase變基操做更加合適,具體的rebase操做請看 Git自學成才——rebase完整版
完成rebase操做以後,在master分支上執行
git merge dev
...
Fast-forward
...
複製代碼
你會在SourceTree裏看看master分支已經包含了dev分支的commit,而且是 一條直線
另一些狀況,被要求全部的merge操做必需要保留節點
若是merge有衝突,手動解決完衝突後,add 衝突的文件,再commit,這樣已經產生了一個merge節點。
若是要求強制產生merge節點,使用 --no-ff
參數告訴merge,咱們不須要快進(no-ff : no fast forward)
git merge --no-ff -m "merged dev" dev
複製代碼
這樣會產生一個 「merged dev」 的commit節點
在某些狀況下,須要咱們的merge只產生一個commit節點
這時,咱們須要壓扁參數squash(能夠理解爲壓縮提交),squash和no-ff很是相似,區別是不會保留對合入分支的引用。也就是說,squash把dev分支的代碼壓縮在一塊兒,在master分支只提交一次。
git merge --squash dev
git commit –m "squash dev"
複製代碼
這樣的操做會在你的master分支上只產生一個"squash dev"節點(包含了dev分支上的多個commit內容)
以上三種merge方式基本涵蓋了平常實戰的場景,一圖以蔽之
更多內容請參考官方手冊 Git 分支 - 分支的新建與合併 git-merge