git merge --ff/--no-ff/--ff-only 三種選項參數(shù)的區(qū)別解析
前言
git merge
應(yīng)該是開發(fā)者最常用的 git 指令之一,默認(rèn)情況下你直接使用 git merge
命令,沒有附加任何選項命令的話,那么應(yīng)該是交給 git 來判斷使用哪種 merge 模式,實際上 git 默認(rèn)執(zhí)行的指令是 git merge -ff
指令(默認(rèn)值)
對于專業(yè)的開發(fā)者來說,你可能無須每次合并都指定合并模式(如果需要的話還是要指定的),但是你可能需要知道 git 在背后為你默認(rèn)做了什么事情,這樣才能保證你的代碼萬無一失。
先說說什么是 Fast-forward
我們從一個正常開發(fā)流程來看看:
開發(fā)者小王接到需求任務(wù),從 master 分支中創(chuàng)建功能分支,git 指令如下:
git checkout -b feature556 Switched to a new branch 'feature556'
小王在 feature556 分支上完成的功能開發(fā)工作,然后產(chǎn)生1次 commit,
git commit -m 'Create pop up effects' [feature556 6104106] create pop up effects 3 files changed, 75 insertions(+)
我們再更新一下 README 自述文件,讓版本差異更明顯一些
git commit -m `updated md`
這時候我們看看當(dāng)前分支的 git 歷史記錄,輸入 git log --online -all
可以看到全部分支的歷史線:
f2c9c7f (HEAD -> feature556) updated md 6104106 create pop up effects a1ec682 (origin/main, origin/HEAD, main) import dio c5848ff update this readme 8abff90 update this readme
直接看下圖可能會更好理解一些
功能完成后自然要上線,我們把代碼合并,完成上線動作,代碼如下
git checkout master git merge feautre556 Updating a1ec682..38348cc Fast-forward ....... | 2+++ 1 file changed, 2 insertions(+)
如果你注意上面的文字的話,你會發(fā)現(xiàn) git 幫你自動執(zhí)行了 Fast-forward
操作,那么什么是 Fast-forward
?
Fast-forward
是指 Master 合并 Feature 時候發(fā)現(xiàn) Master 當(dāng)前節(jié)點(diǎn)一直和 Feature 的根節(jié)點(diǎn)相同,沒有發(fā)生改變,那么 Master 快速移動頭指針到 Feature 的位置,所以 Fast-forward 并不會發(fā)生真正的合并,只是通過移動指針造成合并的假象,這也體現(xiàn) git 設(shè)計的巧妙之處。合并后的分支指針如下:
通常功能分支(feature556) 合并 master 后會被刪除,通過下圖可以看到,通過 Fast-forward
模式產(chǎn)生的合并可以產(chǎn)生干凈并且線性的歷史記錄:
再說說什么是 non-Fast-forward
剛說了會產(chǎn)生 Fast-forward
的情況,現(xiàn)在再說說什么情況會產(chǎn)生 non-Fast-forward
,通常,當(dāng)合并的分支跟 master 不存在共同祖先節(jié)點(diǎn)的時候,這時候在 merge 的時候 git 默認(rèn)無法使用 Fast-forward
模式,
我們先看看下圖的模型:
可以看到 master 分支已經(jīng)比 feature001 快了2個版本,master 已經(jīng)沒辦法通過移動頭指針來完成 Fast-forward
,所以在 master 合并 feature001 的時候就不得不做出真正的合并,真正的合并會讓 git 多做很多工作,具體合并的動作如下:
- 找出 master 和 feature001 的公共祖先,節(jié)點(diǎn) c1,c6, c3 三個節(jié)點(diǎn)的版本 (如果有沖突需要處理)
- 創(chuàng)建新的節(jié)點(diǎn) c7,并且將三個版本的差異合并到 c7,并且創(chuàng)建 commit
- 將 master 和 HEAD 指針移動到 c7
補(bǔ)充:大家在 git log
看到很多類似:Merge branch 'feature001' into master
的 commit 就是 non-Fast-forward 產(chǎn)生的。
執(zhí)行完以上動作,最終分支流程圖如下:
如何手動設(shè)置合并模式 ?
先簡單介紹一下 git merge
的三個合并參數(shù)模式:
- -ff 自動合并模式:當(dāng)合并的分支為當(dāng)前分支的后代的,那么會自動執(zhí)行
--ff (Fast-forward)
模式,如果不匹配則執(zhí)行--no-ff(non-Fast-forward)
合并模式 - --no-ff 非 Fast-forward 模式:在任何情況下都會創(chuàng)建新的 commit 進(jìn)行多方合并(及時被合并的分支為自己的直接后代)
- --ff-onlu Fast-forward 模式:只會按照
Fast-forward
模式進(jìn)行合并,如果不符合條件(并非當(dāng)前分支的直接后代),則會拒絕合并請求并且推出
以下是關(guān)于 --ff, --no-ff, --ff-only 三種模式的官方說明(使用 git merge --helo 即可查看
):
Specifies how a merge is handled when the merged-in history is already a descendant of the current history. --ff is the default unless merging an annotated (and possibly signed) tag that is not stored in its natural place in the refs/tags/ hierarchy, in which case --no-ff is assumed.
With --ff, when possible resolve the merge as a fast-forward (only update the branch pointer to match the merged branch; do not create a merge commit). When not possible (when the merged-in history is not a descendant of the current history), create a merge commit.
With --no-ff, create a merge commit in all cases, even when the merge could instead be resolved as a fast-forward.
With --ff-only, resolve the merge as a fast-forward when possible. When not possible, refuse to merge and exit with a non-zero status.
總結(jié):
三種 merge 模式?jīng)]有好壞和優(yōu)劣之分,只有根據(jù)你團(tuán)隊的需求和實際情況選擇合適的合并模式才是最優(yōu)解,那么應(yīng)該怎么選擇呢? 我給出以下推薦:
- 如果你是小型團(tuán)隊,并且追求干凈線性 git 歷史記錄,那么我推薦使用
git merge --ff-only
方式保持主線模式開發(fā)是一種不錯的選擇 - 如果你團(tuán)隊不大不小,并且也不追求線性的 git 歷史記錄,要體現(xiàn)相對真實的 merge 記錄,那么默認(rèn)的
git --ff
比較合適 - 如果你是大型團(tuán)隊,并且要嚴(yán)格監(jiān)控每個功能分支的合并情況,那么使用
--no-ff
禁用Fast-forward
是一個不錯的選擇
到此這篇關(guān)于git merge --ff/--no-ff/--ff-only 三種選項參數(shù)的區(qū)別解析的文章就介紹到這了,更多相關(guān)git merge --ff/--no-ff/--ff-only內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
聊聊自學(xué),那些讓你事半功倍的自學(xué)資源(干貨分享)
B站是一個學(xué)習(xí)網(wǎng)站。一入B站深似海,從此游戲是路人。B站雖然視頻資源多,但是內(nèi)容也是五花八門、參差不齊,本文給大家收集了關(guān)于學(xué)習(xí)計算機(jī)編程的視頻,這里有我曾經(jīng)的入門視頻,也有跟朋友交流獲得的,特此篩選了下面這些視頻,分享給大家2021-04-04好玩又實用的查看函數(shù)圖像網(wǎng)站Desmos
這個網(wǎng)站的最大優(yōu)點(diǎn),就是省去了安裝數(shù)學(xué)繪圖軟件或計算軟件的麻煩,只要打開瀏覽器就能使用了??戳私榻B之后,可別忘了把這個好網(wǎng)站加到書簽2021-08-08nasm實現(xiàn)的用vmware運(yùn)行自做的linux啟動盤的引導(dǎo)代碼
這個小的代碼的編寫和運(yùn)行還是能讓自己對系統(tǒng)啟動有一個更深的認(rèn)識,不過有個不懂的就是怎么用ISO鏡像文件啟動,怎么將引導(dǎo)代碼寫入ISO鏡像文件,依然沒有找到很好的方法解決2013-04-04Cordova插件實現(xiàn)JavaScript與Java的通信的詳細(xì)過程
本文將結(jié)合最常用的華為推送服務(wù)Cordova插件,介紹HMS Core用到的JS-Java消息交互方式,講解在JS側(cè)如何調(diào)用Java側(cè)接口,最終實現(xiàn)HMS Core能力,感興趣的朋友一起學(xué)習(xí)下吧2021-06-06Hbuilder連遠(yuǎn)程接服務(wù)器上傳代碼的圖文教程
下面小編就為大家分享一篇Hbuilder連遠(yuǎn)程接服務(wù)器上傳代碼的圖文教程,具有很好的參考價值,一起跟隨小編過來看看吧,希望對大家有所幫助2017-11-11淺談服務(wù)發(fā)現(xiàn)和負(fù)載均衡的來龍去脈
單機(jī)時代,傳統(tǒng)軟件大多是單體/巨石架構(gòu)(Monolithic)。大家往一個代碼倉庫提交CODE,這會導(dǎo)致應(yīng)用膨脹,以及擴(kuò)展受限,無法按需伸縮等諸多問題。單體架構(gòu)怎么解決多人合作的問題?模塊化,按功能拆分,模塊之間定義編程接口(API)。本篇文章帶你詳細(xì)了解。2021-05-05