在上一篇的內容中,提到了 Merge 其實就是在合併的點上,把與本身不一樣的地方,實作一次,做成動畫大概類似底下的圖示:
一、舉例來說,有一個儲存庫,有一個 fruit.html 檔案,內容只有一行文字,目前只有 master 分支,在這位置建立了 apple 及 banana 分支,而此之後,只有在 banana 分支上,有針對 fruit.html 進行編寫動作,這時候如果在 apple 分支上(HEAD 指向 apple 分支),那 GIT 會怎麼動作?
如下圖,是原始的線圖:
執行指令:git merge banana
:
當執行完 Merge 的動作,可以發現,底下出現「fast-forward」的提示字,且現在 apple 和 banana 的分支,在同一個 commit (67a5aa1) 上。
大家還記得,在 Day 08 的時候,提到 GIT 的分支,只是一個 可移動的標籤 ,而面對自己都還沒有進行任何變更的情境下,要 merge 其他已經有變更的分支,怎麼做最快?對於可移動標籤的概念,搭配合併只是把來源分支跟自己不一樣的地方再做一次的概念來說,我們只要把目前分支的標籤,直接移動到預計合併的來源分支上,就完成了合併動作。
再舉一個例子,老師出作業給學生,大雄寫好了作業,技安(胖虎)什麼都沒有寫,請問技安(胖虎)要怎麼做可以最快擁有大雄的作業?借大雄的來,抄一次?還是把大雄的便自己的?以技安(胖虎)的個性,大家可能都知道,把大雄的作業直接變成自己的,會是最快的途徑。
GIT 執行 Merge ,在所在的分支沒變更,只有預計要合併的分支有變更時,只要把自己的分支標籤,移動到預計要變更的那個分支對應的 commit HASH,就等同於完成了合併動作,而且還省了一個 HASH Code。動畫的概念,就如下圖:
在 GIT 上,這樣的合併動作,稱為 fast-forward,也會簡稱「ff」, ff 對於 git merge
一般而言,是預設的,也就是當 GIT 判斷到只有 merge 的對象有變更,預設會使用 fast-forward 的機制。
有些情境,執行「抄一次」的 commit HASH 紀錄很重要,想留存,就是不想佔別人便宜,那該怎麼辦?這時候只需要執行 git merge --no-ff
即可。
如前面的同一個例子,透過 --no-ff
參數,GIT 會再次的詢問為合併點撰寫 commit message。
撰寫完畢送出後,就可以看到多了一個合併點。
實務上,到底是有 ff 好,還是 no-ff 好呢? 這問題是不一定的,有些公司會希望 GIT 的線圖都在同一條直線上呈現,那麽內部在使用的時候甚至會用到之後會提的 git rebase
指令,再更新到共同的儲存庫上;而有些公司則會希望保留「合併點」讓圈圈裡,都只有該分支有關的變更,以上面的例子來說,banana 這個分支裡,就只會有跟 banana 相關的原始碼變更。
今天的重點是,在 GIT 進行 merge 動作的時候,如果與合併的對象起始點(基點)一致,而本身又沒有任何變更,那麼 merge 會採取 fast-forward 的動作,僅是把分支的這標籤,移動到對象的分支上。