2010-09-26 8 views
66

Ich habe versehentlich eine riesige Binärdatei mit meinem neuesten Commit in ein Git-Repository hinzugefügt, festgeschrieben und gepusht.Wie unbenutzte Objekte aus einem Git-Repository entfernen?

Wie kann ich Git die Objekte entfernen lassen, die für diesen Commit erstellt wurden/wurden, so dass mein .git Verzeichnis wieder auf normale Größe schrumpft?

Bearbeiten: Danke für Ihre Antworten; Ich habe mehrere Lösungen ausprobiert. Keine funktioniert. Zum Beispiel von GitHub derjenige entfernt, um die Dateien aus der Geschichte, aber die .git Verzeichnisgröße nicht verringert hat:

$ 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 :-(
+9

Nur eine Erinnerung für Moderatoren, diese Frage zu 100% gehört auf SO, nicht Superuser. – VonC

+0

Siehe auch http://stackoverflow.com/questions/2116778/reduce-git-repository-size/2116892#2116892 und http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create -temporary-sha1-filename/685422 # 685422 – VonC

+0

Wie hier erwähnt (http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create-temporary-sha1-filename/685422#685422), hast du einen repack nach deinem gc versucht? 'git-repack -a' gefolgt von' git-prune-packed' zum Beispiel. Siehe http://blog.felipebalbi.com/2007/12/19/housekeeping-your-git-repository/ – VonC

Antwort

9

Dieses Handbuch auf removing sensitive data anwenden können, die gleiche Methode verwenden. Sie werden den Verlauf neu schreiben, um diese Datei von jeder vorhandenen Revision zu entfernen. Dies ist destruktiv und verursacht Repo-Konflikte mit anderen Checkouts, also warnen Sie zuerst alle Mitbearbeiter.

Wenn Sie die Binärdatei im Repo für andere Personen behalten möchten, gibt es keine echte Möglichkeit, das zu tun, was Sie wollen. Es ist so ziemlich alles oder nichts.

22

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

My answer zu einer ähnlichen Frage befasst sich mit dem Problem der wirklich unbenutzten Objekte aus einem Repository.

5

Hy!

Git erhält nur Objekte, die es wirklich braucht, wenn Repositories Klonen (wenn ich es richtig verstehe)

So können Sie die letzte versehentlich hinzugefügt Entfernen der Datei ändern begehen, dann die Änderungen an der Remote-Repository schieben (mit - f Option, um die alte Festschreibung auf dem Server zu überschreiben)

Wenn Sie dann einen neuen Klon dieses Repos erstellen, sollte das .git-Verzeichnis so klein sein wie vor der Übertragung der großen Datei (en).

Optional, wenn Sie zu der unnötigen Dateien vom Server entfernen möchten, können Sie das Repository auf dem Server löschen und neu geklonte Kopie drücken (das hat die volle Geschichte)

3
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all 

Denken Sie daran, Filename sich ändern für den, den Sie aus dem Repository entfernen möchten.

93

Ich antwortete das anderswo, und werde hier kopieren, da ich stolz darauf bin!

... und ohne weiteres, kann ich Ihnen präsentieren dieses nützliche Skript, git-gc-all, die garantiert alle Müll Ihre git zu entfernen, bis sie mit zusätzlichen Konfigurationsvariablen kommen könnte:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ 
    -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ 
    -c gc.pruneExpire=now gc "[email protected]" 

Die Option --aggressive könnte hilfreich sein.

HINWEIS: Dies wird alle nicht referenzierten Dinger entfernen, also nicht zu mir weinen, wenn Sie später entscheiden, dass Sie einige von ihnen behalten wollte!

Sie müssen möglicherweise auch etwas wie diese zuerst, oh Liebes, 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 einem Skript, hier:

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

+0

Wie in http : //stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repo/14728706#comment20614863_14728706, +1 an Sie wieder. – VonC

+10

ausgezeichnet: D mein böser Plan, mehr Punkte durch Klonen Antworten zu bekommen, hat funktioniert !! 1;) –

+0

Ja! Das funktionierte, aber ich musste das vollständige Skript ausführen. Das Ausführen des Befehls gc (mit Konfigurationsoptionen) war nicht ausreichend. – Daniel

11

1) Entfernen Sie die Datei aus dem git Repo (& nicht das Dateisystem):

  • git rm --cached path/to/file

2) Verkleinern der repo Verwendung:

  • git gc,

  • oder git gc --aggressive

  • oder git prune

oder eine Kombination der vorstehend als in dieser Frage vorgeschlagen: Reduce git repository size

+0

'git gc' arbeitete für mich! –

6

Der Schlüssel für mich tu rned out git repack -A -d -f und dann git gc zu laufen, um die Größe der einzelnen Git-Pack zu reduzieren, die ich hatte.

Verwandte Themen