高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Git 小說連載系列之「可以刪掉全部的分支嗎?」

Git 小說連載系列」系列主要是針對在大家學習或使用 Git 的過程遇到的的一些有趣或微妙的情境而寫的短文,希望可以藉由這一系列的短文幫大家更容易的了解到底 Git 是怎麼回事。

曾經使用過 Git 的朋友,應該大多聽說過在 Git 裡面使用分支(Branch)很方便。不知道大家對於分支的觀念是否正確,下面有三個關於刪除分支的(蠢)問題,大家可以先想想看:

  1. 預設的 master 分支可以刪嗎?
  2. 所有的分支都可以刪嗎?
  3. 那可以把全部的分支都刪光光嗎?

分支是什麼?

即然講到要刪分支,那就要先了解一下什麼是分支。有些人以為分支像是另外複製一個子目錄出來,所以在修改的時候才不會影響到原本分支的內容。事實上分支就只是一個小小的檔案,或者你可把一個分支想像成是一張貼紙,它會在某顆 Commit 上面。

Git Branches

以這個例子來說,目前有 dogcat 跟預設的 master 這三個分支,它們分別是貼在 053fb21b174a5a 以及 e12d8ef 這三顆 Commit 上。

關於更多分支的使用,可參閱開始使用分支章節介紹。

刪掉分支的話會…?

因為分支就只像是一張貼在某顆 Commit 上的貼紙,所以刪除分支這件事差不多就只是把那張貼紙撕掉而已。貼紙雖然是撕掉了,但原本被它貼著的那顆 Commit 並不會因此而消失。它沒有不見,它只是在茫茫的 Git 海中漂浮,因為你把它的名牌撕掉了,它變得不容易被你找到而已。

如果想救回刪掉的分支,可參閱「【狀況題】不小心把還沒合併的分支砍掉了,救得回來嗎?」章節說明。

如果你對分支的觀念正確的話,「救回刪掉的分支」這樣的說法其實也不太正確,應該說「找回原本貼著分支貼紙的那個 Commit」會更精準一些。

預設的分支

master 分支是 Git 預設的分支,其實它也只是一個普通的分支,只是它剛好叫做 master 而已,除此之外並沒什麼特別的,所以如果想換個名字甚至是刪掉它也是沒問題的。

所以,什麼分支都能刪嗎?

這個嘛…這要看狀況,有些情況是沒辦法刪掉某些分支,像是你不能刪掉你目前所在的那個分支:

$ git branch
  cat
  dog
* master

因為現在剛好處在 master 分支,所以硬是要刪掉的話會出現這個錯誤訊息:

$ git branch -D master
error: Cannot delete branch 'master' checked out at '/tmp/git-practice'

因為現在就剛好踩在 master 上,你把 master 抽走它就無立足之地啦。但這並不表示 master 這個分支不能刪,只要先切換到別的分支就可以了:

$ git checkout cat
Switched to branch 'cat'

$ git branch
* cat
  dog
  master

$ git branch -D master
Deleted branch master (was e12d8ef).

先切到別的分支後,轉頭打個回馬槍,搞定!

全部刪光光!

大概對分支有點概念後,知道所有的分支都可刪,再回到原本這個有點微妙的主題「可以刪掉全部的分支嗎?」

嗯…答案是可以的,但在刪最後一個的時候會遇到「不能刪除目前所在的分支」的狀況,所以只要先 Checkout 到任意一個 沒有分支的 Commit 就行(這時候會變成「detached HEAD」狀態),例如我直接切到 053fb21 這個 Commit(就是原本 dog 分支貼著的那顆 Commit):

$ git checkout 053fb21
Note: checking out '053fb21'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 053fb21... add dog 2

變成這個狀態並不是錯誤訊息,所以不要太害怕。關於 detached HEAD 狀態,請參閱「【冷知識】斷頭(detached HEAD)是怎麼一回事?」章節介紹。

讓我們檢視一下目前的分支:

$ git branch
* (HEAD detached at 053fb21)
  cat
  dog

現在不在 cat 分支也不在 dog 分支了,剛剛的 master 也先被刪掉了,所以接下來就可以放大絕:

$ git branch -D cat dog
Deleted branch cat (was b174a5a).
Deleted branch dog (was 053fb21).

來檢視一下成果:

$ git branch
* (HEAD detached at 053fb21)

這樣就刪光光了!

為什麼要把全部的分支刪光光啊?這樣有什麼意義嗎?

意義是三小其實沒什麼意義啊,就好玩而已!

歡迎來聊聊

有任何跟 Git 有關的疑難雜症或是應用情境,都歡迎來信或留言,如果討論的篇幅夠多就會另外整理一篇文章供大家參考 :)

Comments