2010-05-21 8 views
22

Ich habe einen git Baum wieWie lösche ich wirklich einen Git-Zweig (d. H. Alle seine Objekte/Commits entfernen)?

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

I Thema entfernen möchte und alle Objekte darauf.

ich den SHA-ID Thema beachten Sie, geben Sie dann:

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

Nach dem letzten Befehl erwarte ich einen Fehler (so etwas wie „Nicht vorhandenes Objekt-ID ...“ erhalten oder somth so.). Allerdings gibt es keinen Fehler und gitk zeigt die gleiche Baumstruktur wie oben ??

Was fehlt mir - ich dachte, GC/Prune soll alle nicht erreichbaren Objekte löschen?

+2

Die Antwort von VonC erklärt die Fakten. Wenn du den "philosophischen" Grund wissen willst, ist es einfach so, dass Git sehr sehr bemüht ist, dich nicht versehentlich etwas löschen zu lassen. 'git gc' selbst soll eine Aufräum-/Umpackoperation sein. Sie müssen etwas stärker sagen, um potentielle neue Arbeiten zu löschen. – Cascabel

Antwort

4

Hinweis Mai 2010: Wenn Ihre Zweigstelle zusammengeführt wurde, wäre Topic immer noch erreichbar, wenn mentioned by Jakub.

Hier angenommen, es gab keine Zusammenführung.
Dann wird, wie mentioned in the ProGit book und detailliert in diesem SO question:

git gc --prune=now 

sollte genug sein (Sie sollten direkt git prune nennen). Sie können das mit einer git count-objects -v steuern.
Bearbeiten April 2012: maxschlepzig in den Kommentaren bestätigt, dass zusätzliche Schritte erforderlich sein können, wie in Dukeanswer (aber ohne die git repack) detailliert beschrieben.
So anstelle eines git gc --prune now:

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

"Nicht erreichbar" ist eigentlich sogar stärker als Sie hier andeuten. Was "git-gc" betrifft, ist ein Objekt erreichbar, wenn es aus einem Reflog erreichbar ist - und Reflogs benötigen eine lange Zeit, bis sie ablaufen. Zum Beispiel könnten Sie die Verzweigung mit dem Master verschmolzen haben, erkannt haben, dass sie schlecht ist und den Master zurück auf die vorherige Position zurücksetzen, und das Commit wird als erreichbar angesehen, bis der Reflog-Eintrag abgelaufen ist (standardmäßig 90 Tage). – Cascabel

+3

Auch, es ist wohl selbstverständlich, aber sei super-extra-vorsichtig mit '--prune = now'. Es wäre furchtbar zu bemerken, dass ein anderes wichtiges Commit gelöscht wurde. – Cascabel

+0

danke Jungs, du rockst! :) – Alan

24

Gerade die gc Pflaume ist oft nicht genug, um die zusätzlichen Objekte im Repo loszuwerden. Wenn Commits im Reflog immer noch referenziert werden, werden diese Objekte nicht als unerreichbar angesehen und sind daher reif für eine Bereinigung.

Hier ist, was für mich gearbeitet:

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

Dies wird einige Änderungen an Ihrem Repo-Geschichte machen, und kann auch Schwierigkeiten, wenn andere sind abhängig von den Zweigen Sie wegblasen.

Sie müssen möglicherweise Ihr Repository neu klonen, um tatsächlich einen Unterschied in seiner Größe zu sehen.

+0

Interessantes Feedback. +1 – VonC

+1

Ich musste 'git reflog expire --expire = now --all' benutzen. Beachten Sie die hinzugefügten "ablaufen". –

+0

Getestet - und der Repack-Schritt war nicht notwendig. – maxschlepzig