Entfernen Sie Dateien vollständig aus Git Repo und Remote auf GitHub

78

Ich habe versehentlich einen Ordner mit Bildern hinzugefügt und festgeschrieben. Dann habe ich noch ein Commit gemacht. Dann habe ich diese Dateien mit entfernt git rm -f ./imagesund erneut festgeschrieben.

Im Moment habe ich viel mehr Commits in diesem Zweig gemacht (Master). In meinem HEAD habe ich diesen ./static/imagesOrdner nicht.

Aufgrund dessen hat sich meine Repo-Größe stark erhöht. Wie kann ich diese Blobs vollständig entfernen? Und ich möchte es auch von meinem entfernten GitHub-Repo entfernen.

Abhijeet Rastogi
quelle
Aus irgendeinem Grund funktionierten die Anweisungen von github und unten nicht für mich, aber diese Antwort aus dem 'Pro Git'-Buch, auf die in dieser SO-Antwort verwiesen wird, funktionierte perfekt: stackoverflow.com/a/16877548/436014 - Ich bin neugierig über die Unterschiede zwischen Baumfilter und Indexfilter jetzt.
Waffel
Ohne Remote-Teil: stackoverflow.com/questions/2100907/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Antworten:

125

Dies ist, wonach Sie suchen: Durch Ignorieren wird keine Datei entfernt . Ich schlage vor, Sie lesen diese Seite, aber hier ist der spezifische Befehl, den Sie verwenden sollten:

git filter-branch --index-filter \
'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

Verwenden Sie außerdem Folgendes, um alle gelöschten Dateien aus den von git erstellten Caches zu entfernen:

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune

Weitere Informationen zum letzten Befehl sowie ein Skript, das alles, was Sie wollen, in einer einzigen Aktion ausführt , finden Sie hier: git: Dateien oder Ordner für immer aus dem Verlauf entfernen .

Ein weiterer Link mit vielen Erklärungen: Entfernen Sie vertrauliche Daten .

[Bearbeiten] Siehe auch diese StackOverflow-Frage: Entfernen Sie vertrauliche Dateien und ihre Commits aus dem Git-Verlauf .

(Befehle, die aus natacadoder Antwort in der oben verlinkten Frage kopiert wurden .) Wenn Sie die Dateien bereits aus der Arbeitskopie entfernt haben, sollte Folgendes funktionieren. Finden Sie den Hash für das Commit heraus, das die unerwünschten Dateien hinzugefügt hat. Dann mach:

git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
Darhuuk
quelle
1
Du hast mir gesagt, ich soll 'git rm --cached <file>' machen. Aber im Moment habe ich diesen Ordner "./statis/images" nicht, da ich im Projekt so viel vor mir habe. Danach habe ich auch viele Commits gemacht.
Abhijeet Rastogi
1
@shadyabhi Hm, versuchen Sie vielleicht, dem Befehl rm --ignore-unmatch hinzuzufügen. Lassen Sie mich wissen, ob das funktioniert.
Darhuuk
@ Darhuuk Ich habe getan, was du gesagt hast. Ich habe viele Ausgaben mit der Aufschrift "rm ...". Ich habe $ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ./static/images' HEAD und dann $ rm -rf .git / refs / original / && git reflog expire - -all && git gc --aggressiv --prune. Trotzdem ist meine Repo-Größe 2,7 MB groß. Meine Quelle ist nur 525 KB. Meine Commits sind nur 118. Es ist ziemlich groß für so weniger Änderungen.
Abhijeet Rastogi
@shadyabhi Haben Sie die Lösung in der anderen von mir verlinkten StackOverflow-Frage ausprobiert?
Darhuuk
@Darhuuk Muss ich Rebase verwenden? Ich bin nur ein Anfänger in all dem, also folge ich ihm nicht genau.
Abhijeet Rastogi
9

Sie können einfach Ihren gesamten Zweig neu gründen und sowohl das Commit, mit dem die Bilder hinzugefügt wurden, als auch das Commit, mit dem sie entfernt wurden, entfernen.

git rebase -i master

Sie erhalten eine Liste der Commits. Löschen Sie die Zeilen mit den Rogue-Commits, die Sie entfernen möchten. ("dd" löscht eine Zeile in vim, dem Standardeditor. Speichern Sie dann mit ZZ.)

Die baumelnden Commits werden dann im Verlauf der natürlichen Müllabfuhr bereinigt, ein Vorgang, den Sie mit dem in Darhuuks Antwort angegebenen Befehl erzwingen können.

Bearbeiten: Dies funktioniert auch, wenn Sie in ein Remote-Repository verschoben haben, Sie müssen jedoch mit --force pushen. (Gleiches gilt für die Git-Filter-Branch-Lösung).

Beachten Sie, dass dies für jeden, der aus Ihrer Filiale gezogen hat, sehr ärgerlich ist. Sie sollten "Wiederherstellung von Upstream-Rebase" konsultieren .


Vermutlich ist Ihre ursprüngliche versehentliche Hinzufügung von Bildern Teil eines Commits, das Sie beibehalten möchten. In diesem Fall müssen Sie das Commit während der Rebase bearbeiten, um die Teile aufzuteilen, die Sie behalten möchten. Sie können dies tun, indem Sie "pick" in der Liste "rebase -i" für dieses Commit durch "e" (zum Bearbeiten) ersetzen. Der Rebase-Prozess wird hier gestoppt und Sie können das Commit mit "git commit --amend" teilen.

RJFalconer
quelle
4

Ich wiederhole im Wesentlichen die Antwort in Kombination mit dieser Einschränkung bei der Windows-Formatierung , nur damit sie nicht als Kommentar verloren geht.

Beachten Sie die Verwendung von doppelten Anführungszeichen anstelle von einfachen Anführungszeichen, da dies von der Shell abhängt, die Sie verwenden, wie Zeichenfolgen analysiert werden.

Einzelne Zeile:

git filter-branch --index-filter "git rm -r --cached --ignore-unmatch <file/dir>" HEAD

Mehrere Zeilen:

git filter-branch --index-filter \
    "git rm -r --cached --ignore-unmatch <file/dir>" HEAD
drzaus
quelle