2010-05-21 119 views
22

我有一個Git樹像如何真正刪除一個git分支(即刪除所有對象/提交)?

    A---B---C topic 
       /
      D---E---F---G master  <-- 

我想刪除主題,並在其上的所有對象。

我注意到主題的SHA ID,然後鍵入:

git branch -D topic 
git gc         # <-- I also tried prune here... 
git checkout -b temp <SHA1 ID of topic> 

的最後一個命令後,我希望得到一個錯誤(類似「不存在的對象ID ...」或somth這樣。 )。然而,沒有錯誤,並且gitk顯示了與上面相同的樹形結構??

我錯過了什麼 - 我認爲gc/prune應該刪除所有不可訪問的對象?

+2

VonC的答案解釋了事實的真相。如果你想知道「哲學」的原因,那簡直是git非常努力地不讓你意外刪除任何東西。 git gc本身就是一個清理/重新打包操作。你必須說一些更強的東西來讓它潛在地刪除最近的工作。 – Cascabel 2010-05-21 17:32:29

回答

4

2010年5月注意:由於mentioned by Jakub,如果您的分支合併,主題仍然可以訪問。

在這裏,我們假設沒有合併。
然後,mentioned in the ProGit book和詳細在這個SO question

git gc --prune=now 

應該足夠(你應該直接撥打電話git prune)。你可以用git count-objects -v來控制它。
編輯2012年4月:maxschlepzig在評論中確認可能需要額外的步驟,詳見Dukeanswer(但沒有git repack)。
因此,而不是一個git gc --prune now

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
+1

「無法到達」實際上比你在此暗示的更強。就'git-gc'而言,如果一個對象可以從reflog中訪問,那麼這個對象是可訪問的 - 並且reflog需要很長時間才能過期。例如,您可能已將分支合併到主分支,意識到這是錯誤的,並將主設備重置回以前的位置,並且提交將被視爲可訪問,直到reflog條目到期(默認90天)。 – Cascabel 2010-05-21 17:30:51

+3

此外,它可能不言而喻,但使用'--prune = now'超級小心。只有在輸入後才意識到一些其他重要的提交被抹去了。 – Cascabel 2010-05-21 17:37:49

+0

謝謝你們,你們搖滾! :) – Alan 2010-05-25 17:24:28

24

就在GC修剪往往是不夠的,擺脫回購額外的對象。如果提交仍然在reflog中引用,那麼它將不會考慮那些不可到達的對象,因此可能無法進行修剪。

下面是我工作:

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
git repack -a -d -l 

這將使一些更改回購的歷史,並且如果別人都取決於你吹走分支機構以及目前的困難。

您可能需要重新克隆存儲庫以實際查看其大小的差異。

+0

有趣的反饋。 +1 – VonC 2010-12-16 04:56:09

+1

我不得不使用'git reflog expire --expire = now --all'。請注意添加的「過期」。 – 2011-10-26 15:44:16

+0

經過測試 - 重新包裝步驟沒有必要。 – maxschlepzig 2012-04-19 16:31:27