前言
接續前篇 開始使用 Git 管理專案,我們學習了如何透過 Git 與 VS Code 建立儲存庫、新增檔案至暫存區,並提交至本地端的儲存庫。
本篇將著重在分支(branch)的操作上。並藉由 VS Code 與 Git Graph 說明分支的切換、新增、刪除。
什麼是分支?
分支在 Git 中扮演著重要的角色。舉例來說,當我們需要開發一個新功能時,可以在不影響主分支(例如 main/master)的情況下,建立一個新的分支(例如 feature/user-login)。待新功能開發完成後,再將其與主分支整合。
以 GitHub 上 AdGuardHome 專案為例:
master 分支藍色為 v108 的新版本開發,現有正式版本為紅色 v107,每釋出一版 beta 或是 release 就會開一個新的分支進行記錄。
建立分支的好處有以下幾點:
- 允許團隊成員進行多個獨立的工作,而彼此之間不會互相干擾,並能夠輕鬆地同步工作進度。
- 在不影響主分支的情況下,可以進行修改和測試,確保主分支的穩定性。
- 可以自由切換不同分支版本,以便確認各版本之間的差異,進而更好地掌握整個開發流程。
- 當操作出錯時,可以更直觀地還原到原本的狀態,進行修復。此外,雖然也可以透過 reflog 來進行還原,但相較之下較為複雜不直觀。
何時應該建立分支?
- 在開發新功能或修復 Bug 時。
- 當不確定操作 Git 會如何影響時,或進行複雜操作時。
- 當要針對里程碑進行新分支建立時,確保每個版本都是獨立且可控的。
- 🚩當在本地複製遠端儲存庫後,進行新功能修改時。🚩
👉 其中第 4 點與第 1 點類似,但值得特別提出來討論的是:
在初學 Git 時,若忽略了此步驟,往後在提交時很容易發生因主分支改變而引發的衝突。
此外,在多人共同開發的情況下,通常會希望由單一負責人進行主分支的整合與確認。因此建議在不影響主分支的情況下開啟新分支進行推送,然後由負責人進行整合(merge 或 cherry-pick)。
複製一個遠端儲存庫(git clone)
首先,我們先從 GitHub 上複製既有的遠端儲存庫,在此我選用的是 AdGuardHome 這個專案,專案選用是不限定的,也可以使用自己的新增專案,或是其它相關的專案都可以。
我們到專案頁面下,有一個藍色的 Code
按鈕,在 Local 標籤下,找到 Clone 選項內的 HTTPS 的儲存庫網址:https://github.com/AdguardTeam/AdGuardHome.git
。
若使用 SSH 的話,需要配置一組金鑰給 GitHub,可以參照先前文章:使用 SSH 金鑰進行無密碼遠端連線 進行金鑰配置。
到 VS Code 中,Ctrl + `
叫出終端介面,輸入 git clone 儲存庫網址
,便可以進行複製:
|
|
也可以在 VS Code 中,按 F1 叫出指令視窗,輸入 git clone
後 enter,並在提供網址後,選擇儲存庫的路徑。不過這我幾乎沒有用過。畢竟直接在終端機輸入 git clone 打指令快速多了。
之後,透過可以於終端機輸入 code AdGuardHome
或是 Ctrl+K, Ctrl+O
以開啟資料夾,選擇 AdGuardHome 這個資料夾。便可開啟 AdGuardHome 的專案資料夾。
|
|
分支的切換(git checkout)
切換到現有分支
打開 Git Graph,可以看到:
- 空心的藍點為本地端的指標,為我們目前所操作的位置。目前是指到的對應提交 ID 為 2611534d。
- 粗體表示選中的分支,目前是選中
master/origin
。同時本地端也有一個 master 分支。 - 遠端指標(origin/HEAD)指向 master/origin,意思是預設的主分支。指標就是指標,是不能進行 checkout 的。
進行 checkout 切換時,就是把 HEAD 指標指到某個分支或是提交上。
我們對著分支的框框雙點兩下,或是右鍵 → Checkout Branch…,就可以切換到對應的分支。此時原本的分支有的 A 檔案、B 檔案,如果切換的分支沒有。則會自動刪除。(沒有忽略的情況下。)
分離指標(detached HEAD)
切換是可以切換到提交(commit)上的,對著任何一個提交(commit)右鍵進行 checkout,會出現 detached HEAD (分離指標)的狀態,此狀態的意思是目前 HEAD 沒有指在分支上,若未來在推送時,由於 HEAD 沒有指向分支所以沒辦法成功推送。
此外在分離指標狀態下進行提交後,未來在切分支時,若沒有先建立分支,原本所提交的內容由於沒有分支,所以會不見變成孤立的提交(orphan commit),此時要透過 git reflog --all
進行查找。
⚠️ detached 狀態下 → 新增 2 筆提交 → 推送失敗 → 切換至某個存在分支 → 原本提交的 2 筆變為孤立的提交
✅ 所以請確定進行切換時是切換到分支上而不是提交上。否則會造成很多不必要的麻煩與處理。另外,孤立的提交會在 git 某些觸發條件下被清除。
建立新分支(git branch)
假設要在某個提交後長出新的功能或是嘗試性的錯誤修復。對著該提交(73ad1f95)右鍵 → Create Branch…。中間有個 check out 的選項,打勾會自動切換到該分支,不勾選的話就單純的新增一個分支。
圖中建立新分支時有勾選 checkout,所以可以看到 HEAD 會指向新建立的分支。
刪除分支
假設要刪除我們剛剛建立的分支,由於我們目前是在該分支上,所以是沒辦法刪除的。可以先切換到其它分支上,然後對著原本的分支右鍵 → Delete branch。
刪除的選項中有個 Force Delete 的選項,在刪除時會先檢查該分支中的提交有沒有被應用到其它分支上。例如:新增了一個 feature/test 分支,然後提交了 3 個新的內容,在刪除 feature/test 分支就會多了一個確認提醒這 3 個新內容沒有合併到其它分支上。如果還是堅持要刪除,則會跳出額外的 Force Delete 視窗,點選即可強制刪除該分支。
結論
我們學習了如何從 GitHub 中進行複製遠端儲存庫,並且在不同分支之間進行切換、新增分支、刪除分支等操作。在這個過程中,我們也學會了處理可能導致分離指標狀態的情況。
若不小心切換到提交而非分支,就會進入分離指標狀態,從而導致推送失敗。若直接切換到現有分支上,則會導致新提交變成孤立提交,只能透過 git reflog 查找。因此建議的做法是,在切換前先建立一個暫存分支,然後進行切換。在暫存分支上進行操作後,再進行 cherry-pick,最後刪除暫存分支。
分離指標狀態 → 提交新的 2 筆 → 推送失敗 → 建立暫存分支 → 切換到既有分支 → cherry-pick 這 2 筆提交 → 推送 → 刪除暫存分支。
在開始複製遠端儲存庫時,建立新的分支是第一要務,以確保主分支不受影響。不過當功能確認是正常的情況下或僅有單人操作時,建立新的分支可能就不是必要的。然而,無論在操作、整理、或是存在不確定因素時,都建議開新的分支進行操作,如此一來操作錯誤可以直接切回正常的分支,然後刪除操作失敗的分支。
熟悉分支的切換、新增、刪除後,就可以開始學習 git rebase 整理好已經提交的內容了。