在 Day 1 的時候,有提到,平常遇到 GIT 使用上碰到的難題,常常是對於 GIT 的概念上突然打結,而導致突然無法解決眼前的難題。鐵人賽至今,關於 GIT 的概念,我覺得談的也差不多了,今天開始想透過一些狀況題,來一一解答,為什麼我會覺得,常常都只是對於 GIT 的概念打結。首先,來熱個身:
如上圖,目前在 apple 分支,希望讓 apple 移動到 banana 所在的位置(同一個 HASH)?(如下圖)
git merge banana
這題可以這樣思考,移動分支到新的位置,等於是讓目前的這個分支也有跟 banana 分支一樣的 commit。所以這邊可以使用 Day 13 提到的 git merge banana
,通常預設就是 fast-forward
(什麼是 fast-forward 也可以參見 Day 13 的內容),因此通常只要 git merge banana
即可。如果預設值非 fast-forward
也可以增加一個參數 git merge banana --ff
,讓 GIT 強制使用 fast-forward
機制。
git rebase banana
方法只有這個嗎?還記得 Day 14 的 rebase 機制嗎?記得,但 rebase 不是把本地分支與目的端同樣的基點起的每個步驟、每個變更,重新在新的基點實作嗎?對,但因為目前 apple 並沒有任何的實作,因此直接執行 git rebase banana
等於是將 apple 切換基點到 banana 分支,一樣也是 fast-forward
。
git cherry-pick HASH --ff
還有嗎?rebase 的基礎原理方法是什麼?把每個步驟重新再實作一次,也就是 Day 15 提到的 git cherry-pick
,在這邊是不是也可以透過 cherry-pick
做同樣的動作?可以的,我們可以想像,把直到 banana 的所有步驟,依序都在 apple 分支上實作,所以可以根據 banana 分支上的 commit 對應之 HASH Code依序執行指令:
git cherry-pick f34e508 --ff
git cherry-pick dc6a86b --ff
那個 --ff
是必要的嗎?是的。如果沒有執行 ff 則根據 cherry-pick
會在 apple 分支上,重新實作,並且建立新的 commit,當沒有執行 --ff
的時候,就會如下圖一樣,不在同樣的線上。
git cherry-pick --ff ..banana
解法三的方法太慢了,如果要切換的目標有更多的 commit,這樣做會非常慢,那有可能一次執行嗎?可以的,在Day 15 的時候有提到,當需要 cherry-pick 連續的 commit 時,可以使用「from..to」,而現在因為是從目前的位置直到 babana 對應的 commit ,所以可以執行指令 git cherry-pick --ff ..banana
。同樣的 --ff
是必要的。
還有其他的方法嗎?我也還在思考,如果有想到也會持續更新到這邊,也歡迎大家跟我分享。
寫狀況題的初衷,其實是希望根據基礎的 GIT 觀念,做一些衍伸的思考,進而不害怕各種情境,開始根據當下的情境,用基礎的 GIT 指令來完成想完成的事情,希望這系列可以對看鐵人賽文章的邦友們有幫助。