113 Stimmen

Wie entfernt man unbenutzte Objekte aus einem Git-Repository?

Ich habe versehentlich eine riesige Binärdatei mit meinem allerletzten Commit zu einem Git-Repository hinzugefügt, committed und gepusht.

Wie kann ich Git dazu bringen, das/die Objekt(e) zu entfernen, das/die für diesen Commit erstellt wurde(n), damit meine .git Verzeichnis wieder auf eine vernünftige Größe schrumpft?

bearbeiten : Danke für Ihre Antworten; ich habe mehrere Lösungen ausprobiert. Keine hat funktioniert. Zum Beispiel hat die von GitHub die Dateien aus dem Verlauf entfernt, aber die .git Die Größe des Verzeichnisses hat sich nicht verringert:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(

157voto

Sam Watkins Punkte 7162

Ich habe diese Frage bereits an anderer Stelle beantwortet und werde sie hierher kopieren, da ich stolz darauf bin!

... und ohne weitere Umschweife präsentiere ich Ihnen dieses nützliche Skript, git-gc-all, das garantiert all Ihren Git-Müll entfernt, bis er mit zusätzlichen Konfigurationsvariablen auftaucht:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"

Die Option --aggressive könnte hilfreich sein.

HINWEIS: Damit werden ALLE nicht referenzierten Dinge entfernt, also kommen Sie nicht zu mir, wenn Sie später feststellen, dass Sie einige davon behalten wollten!

Möglicherweise müssen Sie auch so etwas wie diese zuerst ausführen, oh je, git ist kompliziert!!

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d

Ich habe das alles in ein Skript geschrieben, hier:

http://sam.nipl.net/b/git-gc-all-ferocious

32voto

Josh Lee Punkte 159535

Ihr git reflog expire --all ist falsch. Es entfernt Reflog-Einträge, die älter sind als die Verfallszeit, die standardmäßig 90 Tage beträgt. Verwenden Sie git reflog expire --all --expire=now .

Meine Antwort zu einer ähnlichen Frage befasst sich mit dem Problem, unbenutzte Objekte wirklich aus einem Repository zu entfernen.

25voto

Jamie Punkte 221

1) Entfernen Sie die Datei aus dem Git-Repository (und nicht aus dem Dateisystem):

  • git rm --cached path/to/file

2) Verkleinern Sie das Repository mit:

  • git gc ,

  • o git gc --aggressive

  • o git prune

oder eine Kombination der oben genannten Möglichkeiten, wie in dieser Frage vorgeschlagen: Größe des Git-Repositorys reduzieren

10voto

Daenyth Punkte 33328

Dieser Leitfaden über Entfernen sensibler Daten können sich nach der gleichen Methode bewerben. Sie werden die Geschichte umschreiben, um diese Datei aus jeder Revision zu entfernen, in der sie vorhanden war. Dies ist destruktiv und führt zu Konflikten mit anderen Checkouts, also warnen Sie alle Mitarbeiter vorher.

Wenn Sie die Binärdatei im Repo für andere Leute verfügbar halten wollen, dann gibt es keine wirkliche Möglichkeit, das zu tun, was Sie wollen. Es ist ziemlich viel alles oder nichts.

9voto

Andrew Charneski Punkte 471

Der Schlüssel für mich war das Laufen git repack -A -d -f und dann git gc um die Größe des einzelnen Git-Pakets, das ich hatte, zu reduzieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X