iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
3
Software Development

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

Day 21 - 如何讓 GIT 的線圖更整齊好閱讀,談 GIT 合併的各種方法

今天完全沒有樂高,在 Day 20 的內容中,我們提到了與遠端溝通時,當遠端共用區的儲存庫有新物件,而本地儲存庫也有新物件時,進行 git pull 其實就等同於先進行了 git fetch 再加上 git merge origin/master,而因為兩端都有新的 commit 產生,因此在 git merge 的動作中,會產出一個因為 merge 而產生的新 commit。

在實務上,程式碼的確合併了,但如果共用儲存庫有更多的共同使用者一起同時在使用,也同時都有新的 commit,那 GIT 的線圖會變成怎麼樣呢?

當同一個分支上有多個人同時提出新的物件

在這邊,我們在本地的儲存庫以多個分支同時進行開發,來模擬同一個共用儲存庫,有多個人同時使用的情境,主要的分支為 master (模擬為共用儲存庫),其他這些分支分別是 apple、banana、cake、dog 等四個分支,他們目前都有一些自己的 commit。

每個分支都有自己的 commit

這時候,大家陸續更新自己的 commit 到共用儲存庫。當 apple 先回到 master ,因為是第一個分支,這時候 git pull 會啟用 ff 的機制。(什麼是 ff 機制,請參見 Day 13)

第一個分支 啟用 ff 機制

而後 banana 也回到 master,因為 apple 已經先回來了,所以 banana 回到 master 會因此多一個 merge 的 commit。(為什麼會多一個 commit,也請參見 Day 13)

Banana 第二個 回到 master

接著,cake 及 dog 分支也都陸續回到 master,這時候會發現,GIT 的線圖呈現有很多圈圈的狀況。

Cake 及 dog 也陸續回到 master 分支,GIT 線圖呈現很多圈圈

這時候,可以思考目前的 GIT 的線圖,如果要檢查 apple 這個分支,到底更新了哪些內容,是不是容易閱讀?可以發現,當要看 apple 分支的時候,期間還會被 dog、banana、cake 等分支的 commit 稍微干擾到。

那如果是在每次的 merge 之前,先做過 rebase 呢?

這樣與上面的例子相同,不過,當第二步驟,banana 準備要回到 master 之前,先針對 master 執行了 git rebase master,而後在 master 分支上,進行 git merge banana

先在 banana 分之上進行 rebase

先進行 rebase

再進行 merge

先進行 rebase 而後再進行merge

接著,cake 及 dog 分支也執行同樣的步驟

當 cake 及 dog 也執行同樣的步驟後的線圖

這時候可以再和上面直接進行 git merge 的線圖進行比較,當有一天,我們需要針對程式碼進行檢查,或者是閱讀的時候,什麼樣的線圖模式,比較容易讓人閱讀?

都在一條直線上的好處是,閱讀儲存庫上面的變更,會是接連著都是同一個來源所更新進來的,在查看儲存庫原始碼的變化,比較容易跟著查看每次變更的內容,缺點則是,每個使用共用儲存庫的團隊成員,每次在更新本地儲存庫到遠端的時候,都必須多增加一個 rebase 的指令。

上面的例子是以都在本地儲存庫的例子,如果本地及遠端的儲存庫該怎麼做?

在真正的本地及遠端共用儲存庫的實例中,如果要達到同樣的效果,可以這樣做:

  1. 一樣的先取得遠端共用儲存區的更新:git fetch
  2. 發現有更新,則進行 git rebase origin/master
  3. git rebase 完畢之後,因為已經是基於遠端共用儲存庫之後所做的變更,這時候進行 git push 將本地端的儲存庫狀況,更新到共用儲存區,在共用儲存區上面所看到的,就會一直都是一直線的線圖。

而,上面的第一步驟 git fetch 以及第二步驟 git rebase origin/master,也就等同於 GIT 指令 git pull --rebase

git pull --rebase

總結:

還記得同樣是 Day 13 所提到的在 git merge 加上 --no-ff 參數嗎?如果每次都進行 rebase,在 merge 的時候,都固定採用 git merge --no-ff 呢?結果會是什麼樣的線圖?

每次都經過 no-ff 的 merge

可以發現每個分支所新增的 commit 都在自己的圈圈裡頭,而且自己獨立為一個圈圈,這樣有什麼好處?

假設,共用儲存區使用的習慣是,針對新的需求,都必須新增一個分支在新的分支上進行變更原始碼,而有上面的流程所產生的線圖,每一個圈圈對應的一定只會是一個需求。在日後,如果要針對某些需求搜尋針對該需求所做的變更有哪些時,就會相對於完全一直線,來的更好找到。

不過在今天的內容中就不繼續說明更多,留待之後針對團隊共同合作的一些使用流程做更多的說明解釋。


上一篇
Day 20 - 與中心溝通出現障礙 繼續談 git push, fetch, pull
下一篇
Day 22 - 雜談更多的 GIT 合併方法以及怎麼復原已更新到儲存庫的 commit
系列文
用樂高玩轉 GIT 版本控制30

1 則留言

0
wade790720
iT邦新手 5 級 ‧ 2021-01-22 14:34:26

banana準備要回到master之前,先針對master執行git rebase master,這之後要執行git push origin banana -f 對吧? 這個指令偏危險,想請問作者是如何讓團隊能去執行讓GIT的線圖更整齊好閱讀??

墨嗓 iT邦新手 3 級 ‧ 2021-01-22 14:45:29 檢舉

我認為,執行 push -f 危險的原因在於,會「影響」到其他也在使用相同分支的使用者以及其他非在「可控範圍」內的事件。

而當一個 banana 分支是一個單一使用者的短暫開發用分支時,從開始開發,到開發完畢,僅一個或極少數可控範圍內的使用者使用時,就屬於在可控範圍內。

這時候在 banana 分支上 rebase masterpush -f 就不危險,因為並不會影響到團隊的其他未知的成員。

我要留言

立即登入留言