這是一張有關標題為 Git 分支的建立與切換與刪除 的圖片

Git 分支的建立與切換與刪除

學習如何在 VS Code 上進行建立、切換和刪除分支的操作流程。

前言

接續前篇 開始使用 Git 管理專案,我們學習了如何透過 Git 與 VS Code 建立儲存庫、新增檔案至暫存區,並提交至本地端的儲存庫。

本篇將著重在分支(branch)的操作上。並藉由 VS Code 與 Git Graph 說明分支的切換、新增、刪除。

什麼是分支?

分支在 Git 中扮演著重要的角色。舉例來說,當我們需要開發一個新功能時,可以在不影響主分支(例如 main/master)的情況下,建立一個新的分支(例如 feature/user-login)。待新功能開發完成後,再將其與主分支整合。

以 GitHub 上 AdGuardHome 專案為例:

master 分支藍色為 v108 的新版本開發,現有正式版本為紅色 v107,每釋出一版 beta 或是 release 就會開一個新的分支進行記錄。

AdGuardHome 的分支結構

建立分支的好處有以下幾點:

  1. 允許團隊成員進行多個獨立的工作,而彼此之間不會互相干擾,並能夠輕鬆地同步工作進度。
  2. 在不影響主分支的情況下,可以進行修改和測試,確保主分支的穩定性。
  3. 可以自由切換不同分支版本,以便確認各版本之間的差異,進而更好地掌握整個開發流程。
  4. 當操作出錯時,可以更直觀地還原到原本的狀態,進行修復。此外,雖然也可以透過 reflog 來進行還原,但相較之下較為複雜不直觀。

何時應該建立分支?

  1. 在開發新功能或修復 Bug 時。
  2. 當不確定操作 Git 會如何影響時,或進行複雜操作時。
  3. 當要針對里程碑進行新分支建立時,確保每個版本都是獨立且可控的。
  4. 🚩當在本地複製遠端儲存庫後,進行新功能修改時。🚩

👉 其中第 4 點與第 1 點類似,但值得特別提出來討論的是:

在初學 Git 時,若忽略了此步驟,往後在提交時很容易發生因主分支改變而引發的衝突。

此外,在多人共同開發的情況下,通常會希望由單一負責人進行主分支的整合與確認。因此建議在不影響主分支的情況下開啟新分支進行推送,然後由負責人進行整合(merge 或 cherry-pick)。

複製一個遠端儲存庫(git clone)

首先,我們先從 GitHub 上複製既有的遠端儲存庫,在此我選用的是 AdGuardHome 這個專案,專案選用是不限定的,也可以使用自己的新增專案,或是其它相關的專案都可以。

我們到專案頁面下,有一個藍色的 Code 按鈕,在 Local 標籤下,找到 Clone 選項內的 HTTPS 的儲存庫網址:https://github.com/AdguardTeam/AdGuardHome.git

若使用 SSH 的話,需要配置一組金鑰給 GitHub,可以參照先前文章:使用 SSH 金鑰進行無密碼遠端連線 進行金鑰配置。

找到 GitHub 上的專案進行 clone

到 VS Code 中,Ctrl + ` 叫出終端介面,輸入 git clone 儲存庫網址,便可以進行複製:

1
2
3
4
5
6
7
8
PS C:\Users\Wells> git clone https://github.com/AdguardTeam/AdGuardHome.git
Cloning into 'AdGuardHome'...
remote: Enumerating objects: 35971, done.
remote: Counting objects: 100% (3588/3588), done.
remote: Compressing objects: 100% (689/689), done.
remote: Total 35971 (delta 3101), reused 3014 (delta 2898), pack-reused 32383
Receiving objects: 100% (35971/35971), 18.10 MiB | 16.05 MiB/s, done.
Resolving deltas: 100% (27165/27165), done.

也可以在 VS Code 中,按 F1 叫出指令視窗,輸入 git clone 後 enter,並在提供網址後,選擇儲存庫的路徑。不過這我幾乎沒有用過。畢竟直接在終端機輸入 git clone 打指令快速多了。

在 VS Code 中使用 git clone 介面

之後,透過可以於終端機輸入 code AdGuardHome 或是 Ctrl+K, Ctrl+O 以開啟資料夾,選擇 AdGuardHome 這個資料夾。便可開啟 AdGuardHome 的專案資料夾。

1
code 專案資料夾

分支的切換(git checkout)

切換到現有分支

打開 Git Graph,可以看到:

  • 空心的藍點為本地端的指標,為我們目前所操作的位置。目前是指到的對應提交 ID 為 2611534d。
  • 粗體表示選中的分支,目前是選中 master/origin。同時本地端也有一個 master 分支。
  • 遠端指標(origin/HEAD)指向 master/origin,意思是預設的主分支。指標就是指標,是不能進行 checkout 的。

AdGuardHome 的 Git Graph

進行 checkout 切換時,就是把 HEAD 指標指到某個分支或是提交上。

我們對著分支的框框雙點兩下,或是右鍵 → Checkout Branch…,就可以切換到對應的分支。此時原本的分支有的 A 檔案、B 檔案,如果切換的分支沒有。則會自動刪除。(沒有忽略的情況下。)

切換 Git 分支

分離指標(detached HEAD)

切換是可以切換到提交(commit)上的,對著任何一個提交(commit)右鍵進行 checkout,會出現 detached HEAD (分離指標)的狀態,此狀態的意思是目前 HEAD 沒有指在分支上,若未來在推送時,由於 HEAD 沒有指向分支所以沒辦法成功推送。

checkout 至提交

此外在分離指標狀態下進行提交後,未來在切分支時,若沒有先建立分支,原本所提交的內容由於沒有分支,所以會不見變成孤立的提交(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 整理好已經提交的內容了。

參考文獻

  1. GitHub - mhutchie/vscode-git-graph
主題 Stack 由 Jimmy 設計