Git合併分支命令參數詳解:git merge --ff

今天研究了一下git merge命令經常使用參數,並分別用簡單的例子實驗了一下,整理以下:git

輸入命令git merge -h能夠查看相關參數:工具

--ff  快速合併,這個是默認的參數。若是合併過程出現衝突,Git會顯示出衝突並等待手動解決spa

--ff-only  只有能快速合併的狀況才合併。若是合併過程出現衝突,Git會自動abort這次merge對象

--no-ff  不使用快速合併。會生成一次新的提交記錄,這個記錄只是標識在這裏進行了一次merge操做(目前還沒想到應用場景)ip

--squash  壓縮合並。將待合併的分支的內容壓縮成一個新的提交合並進來it

接下來分別模擬幾種應用場景來舉例說明,C表明一次提交,合併時都是將dev分支合併到master。ast

第一種狀況:master分支切出dev分支後沒有新的提交,也就是說只有dev分支有更新,能夠快速合併的狀況:cli

eg:master:C1 ← C2date

           ↑blob

  dev:       C3 ← C4

  1.執行:git merge --ff dev

  master:C1 ← C2 ← C3 ← C4

  dev:C1 ← C2 ← C3 ←C4

  結果:查看git log時master分支會看到dev分支上的全部提交,此時master和dev是同樣的

  2.執行:git merge --ff-only dev

  結果同上。

  3.執行:git merge --no-ff dev

  git會提示讓你輸入這次合併的信息,而後生成一個特殊的commit。

  master:C1 ← C2 ← C3 ← C4 ← C5 (Merge branch 'dev')

  dev:C1 ← C2 ← C3 ←C4

  結果:master分支會比dev分支多一條提交記錄,也就是剛纔輸入犯人合併信息

  4.執行:git merge --squash dev

  master:C1 ← C2 ← C5 (Merge branch 'dev')

  dev:C1 ← C2 ← C3 ←C4

  結果:這裏的C5實際上是C3和C4的合併,若是隻想合併dev的內容可是不須要它的提交記錄就能夠用這個參數

第二種狀況,切出後master和dev分支均有更新,這種狀況是最多見的。這裏爲了演示衝突,在C4和C5分別對一個文件進行了修改。

eg:master:C1 ← C2 ← C4

           ↑

  dev:       C3 ← C5

  1.執行:git merge --ff dev

  這時Git會告訴你產生了衝突並列出衝突的文件,查看文件時會列出具體衝突內容,這時要先解決衝突(若是使用Intellij Idea或Eclipse等工具,能夠直接選擇use ours/theirs,ours表明被合併分支即master,theirs表明合併分支即dev),而後將這些修改的部分提交,再執行merge操做。

  master:C1 ← C2 ← C3 ← C5 ← C4 ← C6 (解決衝突的那次提交)

  dev:C1 ← C2 ← C3 ←C5

  那麼問題來了,Git是如何知道兩個文件有衝突呢?

  這裏先說下結論,有時間再補一篇文章單獨說明說明。

  你們都知道在Git裏每一個文件都是一個blob對象,這裏先無論合併時怎麼找到同一個文件在兩個分支上的blob(其實若是文件沒有更新,在兩個分支上是指向同一個blob),假設如今已經到了比較階段了,Git會拿兩個文件來逐行進行對比,可是斷定是否修改是經過相鄰行來肯定的。也就是說文件a的第三行修改了,Git是經過第2行和第4行的對比來斷定的,不信的能夠先本身作實驗驗證。因爲篇幅緣由,這裏再也不贅述。

  2.執行:git merge --ff-only dev

  這時Git會檢測到產生了衝突,因此提示:Not possible to fast-forward, aborting.    即取消此次merge操做。

  3.執行:git merge --no-ff dev

  結果同1,不過這裏在解決了衝突執行commit操做後不用再進行merge操做了。若是再執行merge操做,它會提示:Already up-to-date.

  4.執行:git merge --squash dev

  master:C1 ← C2 ← C4 ← C6 (解決衝突的那次提交)

  dev:C1 ← C2 ← C3 ←C5

  這裏解決了衝突並提交以後也不用再執行merge操做了。若是再執行merge操做會有兩種狀況:

  a.剛纔解決衝突時選用了master分支的修改,那麼仍是會提示有衝突須要解決。

  b.剛纔解決衝突時選用了dev分支的修改,那麼會提示Already up-to-date。

  對比發現,使用--squash參數時,若是有衝突,解決完衝突後只要兩個分支不徹底同樣,再執行git merge --squash時仍是會進行merge。但--no-ff就不會。

相關文章
相關標籤/搜索