Ich habe eine Menge Dateien in einen Zweig eingecheckt und zusammengeführt und musste sie dann entfernen. Jetzt bleibt mir eine große .pack-Datei, die ich nicht entfernen kann.
Ich habe alle Dateien mit gelöscht git rm -rf xxxxxx
und auch die --cached
Option ausgeführt.
Kann mir jemand sagen, wie ich eine große .pack-Datei entfernen kann, die sich derzeit im folgenden Verzeichnis befindet:
.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack
Muss ich nur den Zweig entfernen, den ich noch habe, aber nicht mehr benutze? Oder muss ich noch etwas ausführen?
Ich bin nicht sicher, wie viel Unterschied es macht, aber es zeigt ein Vorhängeschloss gegen die Datei.
Vielen Dank
BEARBEITEN
Hier sind einige Auszüge aus meiner bash_history, die eine Vorstellung davon geben sollen, wie ich in diesen Zustand gekommen bin (nehmen wir an, ich arbeite an einem Git-Zweig namens 'my-branch' und habe einen Ordner mit mehr Ordnern / Dateien):
git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/ (not sure why I ran this as well but I did)
Ich dachte, ich hätte auch folgendes ausgeführt, aber es erscheint nicht in der bash_history mit den anderen:
git rm -rf --cached unwanted_folder/
Ich dachte auch, ich hätte einige Git-Befehle (wie git gc
) ausgeführt, um zu versuchen, die Pack-Datei aufzuräumen, aber sie erscheinen auch nicht in der .bash_history-Datei.
quelle
Antworten:
Das Problem ist, dass die Dateien, obwohl Sie sie entfernt haben, in früheren Revisionen immer noch vorhanden sind. Das ist der springende Punkt bei git: Selbst wenn Sie etwas löschen, können Sie es durch Zugriff auf den Verlauf zurückerhalten.
Was Sie tun möchten, wird als Umschreiben des Verlaufs bezeichnet und beinhaltet den
git filter-branch
Befehl.GitHub hat eine gute Erklärung des Problems auf ihrer Website. https://help.github.com/articles/remove-sensitive-data
Um Ihre Frage direkter zu beantworten, müssen Sie diesen Befehl grundsätzlich ausführen
unwanted_filename_or_folder
und entsprechend ersetzen:Dadurch werden alle Verweise auf die Dateien aus dem aktiven Verlauf des Repos entfernt.
Nächster Schritt: Durchführen eines GC-Zyklus, um zu erzwingen, dass alle Verweise auf die Datei abgelaufen sind und aus der Packdatei gelöscht werden. In diesen Befehlen muss nichts ersetzt werden.
quelle
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
2)git reflog expire --expire=now --all
3)git gc --prune=now
bfg
viel einfacher. Es wird auch in offiziellen Github-Dokumenten empfohlen: help.github.com/articles/…Szenario A : Wenn Ihre großen Dateien nur einem Zweig hinzugefügt wurden, müssen Sie sie nicht ausführen
git filter-branch
. Sie müssen nur den Zweig löschen und die Speicherbereinigung ausführen:Szenario B : Es sieht jedoch so aus, als hätten Sie die Änderungen basierend auf Ihrem Bash-Verlauf in Master zusammengeführt. Wenn Sie die Änderungen noch niemandem mitgeteilt haben (noch keine
git push
). Am einfachsten wäre es, den Master vor dem Zusammenführen mit dem Zweig mit den großen Dateien zurückzusetzen. Dadurch werden alle Commits aus Ihrem Zweig und alle Commits, die nach dem Zusammenführen zum Master gemacht wurden, entfernt. So verlieren Sie möglicherweise Änderungen - zusätzlich zu den großen Dateien -, die Sie möglicherweise tatsächlich wollten:Führen Sie dann die Schritte aus Szenario A aus.
Szenario C : Wenn nach der Zusammenführung andere Änderungen aus dem Zweig oder Änderungen am Master vorgenommen wurden, die Sie beibehalten möchten, ist es am besten, den Master neu zu starten und die gewünschten Commits selektiv einzuschließen:
Entfernen Sie in Ihrem Editor Zeilen, die den Commits entsprechen, mit denen die großen Dateien hinzugefügt wurden, lassen Sie jedoch alles andere unverändert. Speichern und Beenden. Ihr Hauptzweig sollte nur das enthalten, was Sie möchten, und keine großen Dateien. Beachten Sie, dass
git rebase
ohne-p
Merge-Commit-Commits eliminiert werden, sodass Sie nachher einen linearen Verlauf für den Master erhalten<commit hash>
. Das ist wahrscheinlich okay für dich, aber wenn nicht, könntest du es versuchen-p
,git help rebase
sagt abercombining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
.Führen Sie dann die Befehle aus Szenario A aus.
quelle
Wie loganfsmyth bereits in seiner Antwort angegeben hat , müssen Sie den Git-Verlauf löschen, da die Dateien dort auch nach dem Löschen aus dem Repo weiterhin vorhanden sind. Offizielle GitHub-Dokumente empfehlen BFG, das ich einfacher zu verwenden finde als
filter-branch
:Dateien aus dem Verlauf löschen
Laden Sie BFG von ihrer Website herunter. Stellen Sie sicher, dass Sie Java installiert haben, erstellen Sie dann einen Spiegelklon und löschen Sie den Verlauf. Stellen Sie sicher, dass Sie
YOUR_FILE_NAME
den Namen der Datei ersetzen, die Sie löschen möchten:Löschen Sie einen Ordner
Wie oben, aber verwenden
--delete-folders
Andere Optionen
BFG ermöglicht auch noch schickere Optionen (siehe Dokumente ) wie diese:
Entfernen Sie alle Dateien, die größer als 100 MB sind, aus dem Verlauf:
Wichtig!
Achten Sie beim Ausführen von BFG darauf, dass beide
YOUR_FILE_NAME
undYOUR_FOLDER_NAME
tatsächlich nur Datei- / Ordnernamen sind. Sie sind keine Pfade , alsofoo/bar.jpg
wird so etwas nicht funktionieren! Stattdessen werden alle Dateien / Ordner mit dem angegebenen Namen aus dem Repo-Verlauf entfernt, unabhängig davon, welcher Pfad oder Zweig vorhanden war.quelle
bfg
Tool auf ein lokales Git-Repo anwenden möchte , wie der Befehl aussehen soll.Eine Option:
git gc
Manuell ausführen, um eine Anzahl von Packdateien in eine oder mehrere Packdateien zu komprimieren. Dieser Vorgang ist dauerhaft (dh die große Packdatei behält ihr Komprimierungsverhalten bei), daher kann es vorteilhaft sein, ein Repository regelmäßig mit zu komprimierengit gc --aggressive
Eine andere Möglichkeit besteht darin, den Code und .git irgendwo zu speichern und dann die .git zu löschen und diesen vorhandenen Code erneut zu verwenden, um ein neues git-Repository (
git init
) zu erstellen .quelle
git gc
und bin auf ein paar Packdateien gekommen, aber die große ist immer noch eine davon, und ich möchte sie einfach loswerden, damit ich den Ordner extern einfacher sichern kann (zip vorher war 1) -2 MB, jetzt 55 MB). Es sei denn, jemand kann etwas anderes vorschlagen. Ich denke, ich muss möglicherweise einen neuen Idioten kreieren. Ich gehe davon aus, dass dies bedeutet, dass ich den Zugriff auf die Filialen verliere, die ich derzeit habe.Führen Sie den folgenden Befehl aus und ersetzen Sie ihn
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
durch den Pfad zu der Datei, die Sie entfernen möchten, und nicht nur durch den Dateinamen. Diese Argumente werden:Dadurch werden alle Verweise auf die Dateien zwangsweise aus dem aktiven Verlauf des Repos entfernt.
Nächster Schritt: Durchführen eines GC-Zyklus, um zu erzwingen, dass alle Verweise auf die Datei abgelaufen sind und aus der Packdatei gelöscht werden. In diesen Befehlen muss nichts ersetzt werden.
quelle
Ich bin etwas spät dran für die Show, aber falls die obige Antwort die Frage nicht gelöst hat, habe ich einen anderen Weg gefunden. Entfernen Sie einfach die spezifische große Datei aus .pack. Ich hatte dieses Problem, bei dem ich versehentlich eine große 2-GB-Datei eingecheckt habe. Ich habe die in diesem Link erläuterten Schritte befolgt: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/
quelle
Dies ist eher eine praktische als eine Codierungslösung. Zip die Datei. Öffnen Sie die Zip-Datei im Dateiansichtformat (anders als beim Entpacken). Löschen Sie die .pack-Datei. Entpacken und ersetzen Sie den Ordner. Klappt wunderbar!
quelle