So entfernen Sie nicht referenzierte Blobs aus meinem Git-Repository

Lesezeit: 10 Minuten

So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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 releaseaber 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 --aggressiveohne 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?

  • 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

1647299891 501 So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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

  • Interessant. Eine gute Alternative zu meiner allgemeineren Antwort. +1

    – VonC

    6. Februar 2013 um 16:30 Uhr

  • Dies verdient mehr Up-Votes. Endlich wurden viele Git-Objekte entfernt, die andere Methoden behalten würden. Danke!

    – Jean-Philippe Pellet

    29. Oktober 2013 um 17:33 Uhr

  • Hochgestimmt. Wow, ich weiß nicht, was ich gerade getan habe, aber es scheint viel aufzuräumen. Können Sie erläutern, was es bewirkt? Ich habe das Gefühl, dass es alle meine ausgeräumt hat objects. Was sind das und warum sind sie (scheinbar) irrelevant?

    – Redsandro

    16. Januar 2014 um 21:52 Uhr

  • @Redsandro, wie ich verstehe, entfernen diese Befehle “git rm origin”, “rm” und “git update-ref -d” Verweise auf alte Commits für Remotes und dergleichen, was möglicherweise die Garbage Collection verhindert. Die Optionen für “git gc” sagen ihm, dass es nicht an verschiedenen alten Commits festhalten soll, sonst wird es sie für eine Weile behalten. Beispielsweise steht gc.rerereresolved für „Aufzeichnungen von kollidierten Zusammenführungen, die Sie zuvor gelöst haben“, die standardmäßig 60 Tage lang aufbewahrt werden. Diese Optionen befinden sich auf der git-gc-Manpage. Ich bin kein Experte für Git und weiß nicht genau, was all diese Dinge tun. Ich habe sie auf Manpages gefunden und .git nach Commit-Refs gesucht.

    – Sam Watkins

    20. Januar 2014 um 5:23 Uhr

  • Also diese Methode hat bei mir nicht funktioniert. Ich fand heraus, dass es im Inneren noch Referenzen gab .git/info/refs und .git/packed-refs. Das Entfernen dieser Referenzen mit vim und das anschließende Ausführen des Befehls war erfolgreich. Obwohl ich nicht ganz sicher bin, dass die bösen Commits nicht noch in einem Pack waren. Also entpackte ich die Pakete als stackoverflow.com/questions/16972031/… zur Sicherheit. Ich würde den Leuten wahrscheinlich raten, einfach einen Klon zu machen und dann das ursprüngliche Repository wegzublasen.

    – z. Hd. rechts

    23. Januar 2017 um 17:36 Uhr


So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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.

  • Es hat funktioniert, aber irgendwie habe ich dabei meine gespeicherten Verstecke verloren (in meinem Fall nichts Wichtiges, nur eine Warnung für andere)

    – Amro

    14. Januar 2017 um 10:51 Uhr

  • warum nicht –aggressiv?

    – JoelFan

    10. Februar 2017 um 16:35 Uhr

  • Ich denke, diese Antwort braucht eine klare Warnung, vorzugsweise ganz oben. Mein Bearbeitungsvorschlag wurde abgelehnt, weil ich ihn wohl dem Autor in einem Kommentar vorschlagen sollte? Bitte akzeptieren Sie diese Änderung entweder stackoverflow.com/review/suggested-edits/26023988 oder fügen Sie eine Warnung auf Ihre eigene Weise hinzu. Auch das lässt alle deine Verstecke fallen. Das sollte auch in der Warnung erwähnt werden!

    – Inigo

    4. Mai 2020 um 20:13 Uhr


  • Ich habe es mit Git-Version 2.17 getestet und gespeicherte Commits werden durch die obigen Befehle nicht entfernt. Sind Sie sicher, dass Sie keine zusätzlichen Befehle ausgeführt haben?

    – Mikko Rantalainen

    6. Mai 2020 um 17:37 Uhr

  • git fetch --prune Größe weiter reduzieren, da lokale Blobs gelöscht werden.

    – Hektorpal

    3. Juli 2020 um 19:39 Uhr

So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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
files=$@
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

  • stackoverflow.com/questions/359424/… ist auch ein guter Anfang für die filter-branch Befehlsverwendung.

    – VonC

    15. Dezember 2009 um 16:28 Uhr

  • Hallo VonC – NI hatte git gc prune=now ohne Erfolg versucht. Es sieht wirklich wie ein Git-Bug aus, da ich nach einer Zweiglöschung lokal mit nicht referenzierten Blobs gelandet bin, aber diese sind bei einem frischen Klon des GitHub-Repos nicht vorhanden … also ist es nur ein lokales Repo-Problem. Aber ich habe zusätzliche Dateien, die ich löschen möchte, also ist das Skript, auf das Sie oben verwiesen haben, großartig – danke!

    – kkrugler

    16. Dezember 2009 um 17:01 Uhr

git gc --prune=nowoder niedriger Pegel git prune --expire now.

1647299893 475 So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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

1647299893 306 So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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.

1647299893 306 So entfernen Sie nicht referenzierte Blobs aus meinem Git Repository
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.

1003380cookie-checkSo entfernen Sie nicht referenzierte Blobs aus meinem Git-Repository

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy