iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
1
Software Development

用樂高玩轉 GIT 版本控制系列 第 13

Day 13 - 你的就是我的 再談 git merge

上一篇的內容中,提到了 Merge 其實就是在合併的點上,把與本身不一樣的地方,實作一次,做成動畫大概類似底下的圖示:

Merge 動畫概念圖

而如果自己完全還沒有任何變更,只有預計要合併的來源分支有變動呢?

一、舉例來說,有一個儲存庫,有一個 fruit.html 檔案,內容只有一行文字,目前只有 master 分支,在這位置建立了 apple 及 banana 分支,而此之後,只有在 banana 分支上,有針對 fruit.html 進行編寫動作,這時候如果在 apple 分支上(HEAD 指向 apple 分支),那 GIT 會怎麼動作?

如下圖,是原始的線圖:

只有 banana 分支有變更

執行指令:git merge banana:

執行 git merge banana 指令

當執行完 Merge 的動作,可以發現,底下出現「fast-forward」的提示字,且現在 apple 和 banana 的分支,在同一個 commit (67a5aa1) 上。

apple 和 banana 的分支,在同一個 commit

為什麼會這樣呢?原本昨天提到的合併點呢?

大家還記得,在 Day 08 的時候,提到 GIT 的分支,只是一個 可移動的標籤 ,而面對自己都還沒有進行任何變更的情境下,要 merge 其他已經有變更的分支,怎麼做最快?對於可移動標籤的概念,搭配合併只是把來源分支跟自己不一樣的地方再做一次的概念來說,我們只要把目前分支的標籤,直接移動到預計合併的來源分支上,就完成了合併動作。

再舉一個例子,老師出作業給學生,大雄寫好了作業,技安(胖虎)什麼都沒有寫,請問技安(胖虎)要怎麼做可以最快擁有大雄的作業?借大雄的來,抄一次?還是把大雄的便自己的?以技安(胖虎)的個性,大家可能都知道,把大雄的作業直接變成自己的,會是最快的途徑。

GIT 執行 Merge ,在所在的分支沒變更,只有預計要合併的分支有變更時,只要把自己的分支標籤,移動到預計要變更的那個分支對應的 commit HASH,就等同於完成了合併動作,而且還省了一個 HASH Code。動畫的概念,就如下圖:

merge ff 概念圖

在 GIT 上,這樣的合併動作,稱為 fast-forward,也會簡稱「ff」, ff 對於 git merge 一般而言,是預設的,也就是當 GIT 判斷到只有 merge 的對象有變更,預設會使用 fast-forward 的機制。

如果不要 fast-forward 呢?

有些情境,執行「抄一次」的 commit HASH 紀錄很重要,想留存,就是不想佔別人便宜,那該怎麼辦?這時候只需要執行 git merge --no-ff 即可。

加入 --no-ff 參數

如前面的同一個例子,透過 --no-ff 參數,GIT 會再次的詢問為合併點撰寫 commit message。

詢問合併的資訊

撰寫完畢送出後,就可以看到多了一個合併點。

增加了一個合併點

merge --no-ff 概念圖

總結

實務上,到底是有 ff 好,還是 no-ff 好呢? 這問題是不一定的,有些公司會希望 GIT 的線圖都在同一條直線上呈現,那麽內部在使用的時候甚至會用到之後會提的 git rebase 指令,再更新到共同的儲存庫上;而有些公司則會希望保留「合併點」讓圈圈裡,都只有該分支有關的變更,以上面的例子來說,banana 這個分支裡,就只會有跟 banana 相關的原始碼變更。

今天的重點是,在 GIT 進行 merge 動作的時候,如果與合併的對象起始點(基點)一致,而本身又沒有任何變更,那麼 merge 會採取 fast-forward 的動作,僅是把分支的這標籤,移動到對象的分支上。


上一篇
Day 12 - 你手冊新增的部分不錯,我們合作吧!分支合體技 git merge
下一篇
Day 14 - 換個起點再來一次 談 git rebase
系列文
用樂高玩轉 GIT 版本控制30

尚未有邦友留言

立即登入留言