
kkrugler
Ich habe ein GitHub-Repository mit zwei Zweigen – Meister und Freisetzung.
Die Freisetzung branch enthielt binäre Distributionsdateien, die zu einer sehr großen Repository-Größe beitrugen (mehr als 250 MB), also beschloss ich, die Dinge zu bereinigen.
Zuerst habe ich den Remote-Release-Zweig via gelöscht git push origin :release
.
Dann habe ich die lokale gelöscht Freisetzung sich verzeigen. Zuerst habe ich es versucht git branch -d release
aber Git sagte “Fehler: Der Zweig ‘Release’ ist kein Vorfahre Ihres aktuellen HEAD.” was wahr ist, also tat ich es git branch -D release
zu erzwingen, dass es gelöscht wird.
Aber meine Repository-Größe, sowohl lokal als auch auf GitHub, war immer noch riesig. Dann bin ich die übliche Liste von Git-Befehlen durchgegangen, wie z git gc --prune=today --aggressive
ohne Glück.
Indem ich den Anweisungen von Charles Bailey unter SO 1029969 folgte, konnte ich eine Liste der SHA-1-Hashes für die größten Blobs erhalten. Ich habe dann das Skript von SO 460331 verwendet, um die Blobs zu finden … und die fünf größten existieren nicht, obwohl kleinere Blobs gefunden werden, sodass ich weiß, dass das Skript funktioniert.
Ich denke, diese Blogs sind die Binärdateien aus dem Release-Zweig, und sie sind irgendwie nach dem Löschen dieses Zweigs übrig geblieben. Was ist der richtige Weg, um sie loszuwerden?

Sam Watkins
Ich präsentiere Ihnen diesen nützlichen Befehl „git-gc-all“, der garantiert entfernt werden kann alle Ihren Git-Müll, bis möglicherweise zusätzliche Konfigurationsvariablen angezeigt werden:
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \
-c gc.rerereunresolved=0 -c gc.pruneExpire=now gc
Möglicherweise müssen Sie auch zuerst Folgendes ausführen:
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
Möglicherweise müssen Sie auch einige Tags entfernen:
git tag | xargs git tag -d

Löwe
Sie können (wie in dieser Antwort beschrieben) Entfernen Sie dauerhaft alles, was nur im Reflog referenziert wird.
HINWEIS: Dadurch werden viele Objekte entfernt, die Sie vielleicht behalten möchten: Stashes; Alte Historie in keinem aktuellen Zweig; usw. Lesen Sie die Dokumentation um sicher zu sein, dass es das ist, was Sie wollen.
So lassen Sie das Reflog auslaufen und löschen dann alle Objekte, die sich nicht in Branches befinden:
git reflog expire --expire-unreachable=now --all
git gc --prune=now
git reflog expire --expire-unreachable=now --all
entfernt alle Verweise auf nicht erreichbare Commits in reflog
.
git gc --prune=now
entfernt die Commits selbst.
Aufmerksamkeit: Nur mit git gc --prune=now
wird nicht funktionieren, da diese Commits immer noch im Reflog referenziert werden. Daher ist das Löschen des Reflogs obligatorisch. Beachten Sie auch, dass, wenn Sie verwenden rerere
es enthält zusätzliche Referenzen, die durch diese Befehle nicht gelöscht wurden. Sehen git help rerere
für mehr Details. Darüber hinaus werden alle Commits, auf die von lokalen oder entfernten Branches oder Tags verwiesen wird, nicht entfernt, da diese von Git als wertvolle Daten betrachtet werden.

VonC
Wie in dieser SO-Antwort erwähnt, git gc
kann die Größe des Repos tatsächlich erhöhen!
Siehe auch dieser Faden
Jetzt hat git einen Sicherheitsmechanismus dazu nicht lösche nicht referenzierte Objekte sofort beim Ausführen von ‘git gc
‘.
Standardmäßig werden nicht referenzierte Objekte für einen Zeitraum von 2 Wochen aufbewahrt. Dies soll es Ihnen erleichtern, versehentlich gelöschte Branches oder Commits wiederherzustellen oder ein Rennen zu vermeiden, bei dem ein gerade erstelltes Objekt, das gerade erstellt, aber noch nicht referenziert wird, durch ein gelöscht werden könnte ‘git gc
‘Prozess läuft parallel.
Um also gepackten, aber nicht referenzierten Objekten diese Gnadenfrist zu geben, schiebt der Repack-Prozess diese nicht referenzierten Objekte aus dem Paket in ihre lose Form, damit sie gealtert und schließlich gekürzt werden können.
Objekte, die nicht mehr referenziert werden, sind jedoch normalerweise nicht so viele. 404855 nicht referenzierte Objekte zu haben ist ziemlich viel, und diese Objekte überhaupt über einen Klon zu senden, ist dumm und eine völlige Verschwendung von Netzwerkbandbreite.
Wie auch immer … Um Ihr Problem zu lösen, müssen Sie einfach ‘ ausführengit gc
‘ mit dem --prune=now
Argument, um diese Nachfrist zu deaktivieren und diese nicht referenzierten Objekte sofort loszuwerden (nur sicher, wenn keine anderen Git-Aktivitäten gleichzeitig stattfinden, was auf einer Workstation einfach sicherzustellen sein sollte).
Und übrigens, mit ‘git gc --aggressive
‘ mit einer neueren Git-Version (oder ‘git repack -a -f -d --window=250 --depth=250
‘)
Die gleichen Thread erwähnt:
git config pack.deltaCacheSize 1
Dadurch wird die Delta-Cache-Größe auf ein Byte begrenzt (effektiv deaktiviert) anstelle des Standardwerts von 0, was unbegrenzt bedeutet. Damit bin ich in der Lage, dieses Repository mit dem oben Gesagten neu zu packen git repack
Befehl auf einem x86-64-System mit 4 GB RAM und Verwendung von 4 Threads (dies ist ein Quad-Core). Die Nutzung des residenten Speichers wächst jedoch auf fast 3,3 GB.
Wenn Ihr Computer SMP ist und Sie nicht über ausreichend RAM verfügen, können Sie die Anzahl der Threads auf nur einen reduzieren:
git config pack.threads 1
Darüber hinaus können Sie die Speichernutzung mit weiter einschränken --window-memory argument
zu ‘git repack
‘.
Zum Beispiel mit --window-memory=128M
sollte eine angemessene Obergrenze für die Speichernutzung der Delta-Suche beibehalten, obwohl dies zu einer weniger optimalen Delta-Übereinstimmung führen kann, wenn das Repo viele große Dateien enthält.
Auf der Vorderseite des Filterzweigs können Sie (mit Vorsicht) Folgendes in Betracht ziehen: dieses Skript
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
[email protected]
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune
git gc --prune=now
oder niedriger Pegel git prune --expire now
.

vdboor
Jedes Mal Ihre KOPF bewegt, verfolgt Git dies in der reflog
. Wenn Sie Commits entfernt haben, haben Sie immer noch „hängende Commits“, weil sie immer noch von der referenziert werden reflog
für etwa 30 Tage. Dies ist das Sicherheitsnetz, wenn Sie Commits versehentlich löschen.
Du kannst den … benutzen git reflog
Befehl, um bestimmte Commits zu entfernen, neu zu packen usw., oder nur der Befehl auf hoher Ebene:
git gc --prune=now

Peter Mortensen
Sie können verwenden git forget-blob
.
Die Verwendung ist ziemlich einfach:
git forget-blob file-to-forget
Weitere Informationen erhalten Sie in Entfernen Sie eine Datei vollständig aus einem Git-Repository mit „git forget-blob“..
Es wird aus allen Commits in Ihrem Verlauf, Reflog, Tags usw. verschwinden.
Ich stoße hin und wieder auf das gleiche Problem, und jedes Mal muss ich auf diesen und andere Beiträge zurückkommen. Deshalb habe ich den Prozess automatisiert.
Credits gehen an Mitwirkende wie Sam Watkins.

Peter Mortensen
Vorher tun git filter-branch
und git gc
, sollten Sie Tags überprüfen, die in Ihrem Repository vorhanden sind. Jedes echte System, das automatisches Tagging für Dinge wie hat kontinuierliche Integration und Einsätze Dadurch werden unerwünschte Objekte weiterhin von diesen Tags referenziert gc
können sie nicht entfernen und Sie werden sich immer noch fragen, warum die Größe des Repositorys immer noch so groß ist.
Der beste Weg, um alle unerwünschten Dinge loszuwerden, ist zu rennen git-filter
& git gc
und pushen Sie dann master in ein neues Bare-Repository. Das neue Bare-Repository wird den bereinigten Baum haben.
10033800cookie-checkSo entfernen Sie nicht referenzierte Blobs aus meinem Git-Repositoryyes
Welche Git-Version verwendest du? Und haben Sie es mit stackoverflow.com/questions/1106529/… versucht?
– VonC
15. Dezember 2009 um 4:56 Uhr
git version 1.6.2.3 Ich hatte gc und prune mit verschiedenen Argumenten ausprobiert. Ich hatte repack -a -d -l nicht ausprobiert, nur ausgeführt, keine Änderung.
– kkrugler
15. Dezember 2009 um 14:32 Uhr
Neue Informationen – ein frischer Klon von GitHub hat nicht mehr die nicht referenzierten Blobs und ist von 250 MB auf “nur” 84 MB gesunken.
– kkrugler
15. Dezember 2009 um 14:33 Uhr