2010-05-21 80 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