Wie kann ich meinen .git-Ordner bereinigen? Ich habe mein Projektverzeichnis aufgeräumt, aber .git ist immer noch riesig

85

Das .git / -Objekt in meinem Rails-Projektverzeichnis ist immer noch riesig, nachdem Hunderte von Megabyte versehentlich generierten Mülls gelöscht wurden.

Ich habe versucht git add -A, sowie andere Befehle, um den Index zu aktualisieren und nicht vorhandene Dateien zu entfernen. Ich habe möglicherweise fälschlicherweise festgestellt, dass die Dateien mit zwei Zeichennamen im Verzeichnis Blobs sind. Ich habe versucht, zu früheren Commits zurückzukehren, aber kein Glück.

Was kann ich tun, um dieses Verzeichnis zu bereinigen?

Glühbirnen
quelle

Antworten:

137
  • Wenn Sie die Dateien hinzugefügt und dann entfernt haben, sind die Blobs noch vorhanden, baumeln jedoch. git fscklistet nicht erreichbare Blobs auf und git prunelöscht sie.

  • Wenn Sie die Dateien hinzugefügt, festgeschrieben und dann zurückgesetzt haben git reset --hard HEAD^, stecken sie etwas tiefer. git fscklistet keine baumelnden Commits oder Blobs auf, da das Reflog Ihres Zweigs daran festhält . Hier ist eine Möglichkeit, um sicherzustellen, dass nur Objekte übrig bleiben, die sich in Ihrem eigentlichen Verlauf befinden:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • Eine andere Möglichkeit besteht darin, das Repository zu klonen, da nur die erreichbaren Objekte übertragen werden. Wenn jedoch die baumelnden Objekte gepackt wurden (und wenn Sie viele Operationen ausgeführt haben, hat git möglicherweise automatisch gepackt), trägt ein lokaler Klon die gesamte Packdatei:

    git clone foo bar                 # bad
    git clone --no-hardlinks foo bar  # also bad
    

    Sie müssen ein Protokoll angeben, um git zu zwingen, ein neues Paket zu berechnen:

    git clone file://foo bar  # good
    
Josh Lee
quelle
Ja, ich habe mich verpflichtet, bevor ich das Problem bemerkt habe. Ich habe alles außer dem letzten Befehl versucht. Wenn ich dies in meinem Projektverzeichnis ausführe "Warnung: Sie scheinen ein leeres Repository geklont zu haben." Ich habe die Dokumentation gelesen, aber es ist schweres Zeug. Wie kann ich den Klon auf die richtige Quelle verweisen?
light24bulbs
1
@user Die file://fooURL ist relativ zum aktuellen Verzeichnis und a file:///home/me/foo(drei Schrägstriche) ist absolut.
Josh Lee
Vielen Dank! Das ist halbiert, aber mein Pack ist immer noch zehnmal so groß wie der Rest des Repositorys. Ich habe versucht zu beschneiden ..
light24bulbs
1
@user Wenn viele Commits fälschlicherweise große Dateien enthalten, möchten Sie möglicherweise den Git-Filter-Zweig verwenden , um sie auszuwählen.
Josh Lee
2
Entschuldigung, ohne Wirkung. Mein Entwickler sagt, dass die Größe jetzt in einem akzeptablen, aber ungünstigen Bereich liegt. Wenn Sie die Zeit haben, mich weiterhin mit einem Löffel zu füttern, wäre das ausgezeichnet, aber Sie haben mich wieder auf die Beine gebracht. Danke jleedev.
light24bulbs
33

Haben Sie den git gcBefehl ausprobiert ?

Ryanprayogo
quelle
3
git gc --aggressive --prunefunktioniert bei mir. git gcnicht. Möglicherweise reicht die Standardeinstellung nicht aus.
Moonlight Knight
13

Sparkleshare hat 13 GB tmp_pack_-Dateien in meinem Git erstellt, nachdem es nicht gelungen war, mehrmals ein großes Einchecken von Bildern durchzuführen. Das einzige was half war ...

rm -f .git/objects/*/tmp_*

'git gc' hat diese Dateien nicht entfernt.

Katze
quelle
Das ist eine ziemlich brutale Lösung, aber ich sehe keinen Grund, warum es nicht funktionieren würde. Nett!
Glühbirnen
1
Verzweifelte Situationen erfordern verzweifelte Maßnahmen. Es hat wie ein Zauber funktioniert! Tks.
Medina
rm ist für Linux-Befehl? Was ist mit Windows-Benutzer dann @cat?
Gumuruh
7

Wenn Sie nach dem Beschneiden und Umpacken ( gc --aggressive --prune=tomorrow...) immer noch ein großes Repo haben , können Sie einfach nach dem ungeraden suchen:

git rev-list --objects --all |
    while read sha1 fname
    do 
        echo -e "$(git cat-file -s $sha1)\t$\t$fname"
    done | sort -n

Dadurch erhalten Sie eine sortierte Liste von Objekten in aufsteigender Größe. Sie könnten git-filter-branch verwenden, um den Täter aus Ihrem Repo zu entfernen.

Siehe „Entfernen von Objekten“ in http://progit.org/book/ch9-7.html zur Führung

sehe sehen
quelle
@ DavidJames danke für den Hinweis. Ich habe es noch lesbarer gemacht, IMO
sehe
Nur für den Fall, dass jemand anderes darüber stolpert: Es gibt einen Tippfehler in den Argumenten in Klammern: sollte sein --aggressive. Versucht zu bearbeiten, aber es stellt sich heraus, dass Sie einen so kleinen Tippfehler nicht bearbeiten können.
Hellobenallan
@ Shellobenallan danke für die Notiz, behoben
sehe
1

Rekursiv:

find ./ -iname '*.!*' -size 0 -delete
for i in */.git; do ( echo $i; cd $i/..; git gc --aggressive --prune=now --force; ); done
Marcelo Grebois
quelle