Was Sie vorhaben, ist äußerst störend, wenn Sie die Geschichte an andere Entwickler weitergegeben haben. Siehe "Wiederherstellung von Upstream Rebase" in der git rebase
Dokumentation für die notwendigen Schritte nach der Reparatur Ihrer Geschichte.
Sie haben mindestens zwei Möglichkeiten: git filter-branch
und ein interaktive Umbasierung , die beide weiter unten erläutert werden.
Verwendung von git filter-branch
Ich hatte ein ähnliches Problem mit sperrigen binären Testdaten aus einem Subversion-Import und schrieb über Entfernen von Daten aus einem Git-Repository .
Sagen wir, Ihr Git-Verlauf ist:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
Beachten Sie, dass git lola
ist ein nicht standardisierter, aber sehr nützlicher Alias. Mit dem --name-status
Schalter können wir die Baumänderungen sehen, die mit jeder Übergabe verbunden sind.
In der Übergabe "Careless" (deren SHA1-Objektname ce36c98 ist) wird die Datei oops.iso
ist der DVD-Rip, der versehentlich hinzugefügt und in der nächsten Übergabe, cb14efd, entfernt wurde. Mit der im oben erwähnten Blogbeitrag beschriebenen Technik lautet der auszuführende Befehl:
git filter-branch --prune-empty -d /dev/shm/scratch \
--index-filter "git rm --cached -f --ignore-unmatch oops.iso" \
--tag-name-filter cat -- --all
Optionen:
--prune-empty
entfernt Commits, die leer werden ( d.h. ändern Sie den Baum nicht) als Ergebnis des Filtervorgangs. Im typischen Fall führt diese Option zu einem saubereren Verlauf.
-d
benennt ein temporäres, noch nicht existierendes Verzeichnis, das für die Erstellung des gefilterten Verlaufs verwendet wird. Wenn Sie mit einer modernen Linux-Distribution arbeiten, ist die Angabe eines Baum in /dev/shm
wird zu einer schnelleren Ausführung führen .
--index-filter
ist das Hauptereignis und läuft bei jedem Schritt in der Historie gegen den Index. Sie möchten entfernen oops.iso
wo immer er gefunden wird, aber er ist nicht in allen Übertragungen vorhanden. Der Befehl git rm --cached -f --ignore-unmatch oops.iso
löscht den DVD-Rip, wenn er vorhanden ist, und schlägt ansonsten nicht fehl.
--tag-name-filter
beschreibt, wie Tag-Namen umgeschrieben werden können. Ein Filter von cat
ist die Identitätsoperation. Ihr Repository, wie das obige Beispiel, hat möglicherweise keine Tags, aber ich habe diese Option aus Gründen der Allgemeinheit hinzugefügt.
--
gibt das Ende der Optionen für git filter-branch
--all
unter --
ist die Kurzform für alle Schiedsrichter. Ihr Repository, wie das obige Beispiel, hat vielleicht nur eine Referenz (master), aber ich habe diese Option aus Gründen der Allgemeinheit hinzugefügt.
Nach einigem Hin und Her ist die Geschichte jetzt:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
|
| * f772d66 (refs/original/refs/heads/master) Login page
| | A login.html
| * cb14efd Remove DVD-rip
| | D oops.iso
| * ce36c98 Careless
|/ A oops.iso
| A other.html
|
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
Beachten Sie, dass die neue "Careless"-Übertragung nur other.html
und dass der Commit "Remove DVD-rip" nicht mehr auf dem Master-Zweig ist. Der Zweig mit der Bezeichnung refs/original/refs/heads/master
enthält Ihre ursprünglichen Übertragungen, falls Sie einen Fehler gemacht haben. Um sie zu entfernen, folgen Sie den Schritten in "Checkliste für die Verkleinerung eines Repositorys".
$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now
Eine einfachere Alternative ist das Klonen des Repositorys, um die unerwünschten Teile zu entfernen.
$ cd ~/src
$ mv repo repo.old
$ git clone file:///home/user/src/repo.old repo
Mit einer file:///...
clone URL kopiert Objekte, anstatt nur Hardlinks zu erstellen.
Jetzt ist Ihre Geschichte:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
Die SHA1-Objektnamen für die ersten beiden Übertragungen ("Index" und "Admin page") blieben unverändert, da der Filtervorgang diese Übertragungen nicht verändert hat. "Unachtsam" verloren oops.iso
und "Login-Seite" haben ein neues Elternteil bekommen, so dass ihre SHA1s a fait ändern.
Interaktive Umbasierung
Mit einer Geschichte von:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
die Sie entfernen möchten oops.iso
aus "Sorglos", als hätten Sie es nie hinzugefügt, und dann ist "DVD-Rip entfernen" für Sie nutzlos. Unser Plan für eine interaktive Neuauflage ist daher, "Admin-Seite" beizubehalten, "Sorglos" zu bearbeiten und "DVD-Rip entfernen" zu verwerfen.
Laufen $ git rebase -i 5af4522
startet einen Editor mit dem folgenden Inhalt.
pick ce36c98 Careless
pick cb14efd Remove DVD-rip
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Indem wir unseren Plan ausführen, ändern wir ihn zu
edit ce36c98 Careless
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
# ...
Das heißt, wir löschen die Zeile mit "DVD-Rip entfernen" und ändern die Operation für "Careless" in edit
statt pick
.
Nach dem Beenden des Editors durch Speichern erscheint eine Eingabeaufforderung mit der folgenden Meldung.
Stopped at ce36c98... Careless
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
Wie uns die Meldung sagt, befinden wir uns auf der "Careless"-Übertragung, die wir bearbeiten wollen, also führen wir zwei Befehle aus.
$ git rm --cached oops.iso
$ git commit --amend -C HEAD
$ git rebase --continue
Im ersten Fall wird die betreffende Datei aus dem Index entfernt. Die zweite ändert oder ergänzt "Careless" so, dass es der aktualisierte Index ist und -C HEAD
weist Git an, die alte Commit-Nachricht wieder zu verwenden. Zum Schluss, git rebase --continue
fährt mit dem Rest des Umbasierungsvorgangs fort.
Dies gibt einen Überblick über die Geschichte:
$ git lola --name-status
* 93174be (HEAD, master) Login page
| A login.html
* a570198 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
das ist das, was Sie wollen.
13 Stimmen
Dieser Artikel soll Ihnen helfen help.github.com/removing-sensitive-data
4 Stimmen
Verwandt: Vollständiges Entfernen der Datei aus der Historie aller Git-Repository-Übertragungen .
1 Stimmen
Beachten Sie, dass Sie den vollständigen relativen Pfad angeben müssen, wenn sich Ihre große Datei in einem Unterverzeichnis befindet.
1 Stimmen
Auch verwandt help.github.com/de/articles/
0 Stimmen
In vielen Antworten wird BFG als einfacher dargestellt als
git filter-branch
aber ich habe das Gegenteil festgestellt.13 Stimmen
Bitte sehen Sie sich auch meine Antwort an, in der
git filter-repo
. Sie sollten nicht mehr verwendengit filter-branch
da es sehr langsam und oft schwierig zu bedienen ist.git filter-repo
ist etwa 100 Mal schneller.1 Stimmen
Die Antworten enthalten eine Menge guter Informationen für komplexe Situationen. Für den einfachen Fall, dass Sie die Datei hinzugefügt und im nächsten Commit wieder entfernt haben, können Sie diese beiden Commits einfach zusammenfassen.
1 Stimmen
Wild, dass sich so viele Antworten auf die Geschwindigkeit beziehen. Wie oft schrauben Sie an Ihrer Repo-Historie herum, dass Sie sich um die Effizienz dieses Vorgangs kümmern müssen?
3 Stimmen
Nach dem zehnten Mal, das ich das durchgemacht habe, ist die richtige Antwort, dass Git sich einfach weigern sollte, diese Dateien einzuchecken, anstatt dieses ganze Durcheinander zu verursachen.
0 Stimmen
Ich kam hierher, nachdem ich gegoogelt hatte, wie man solche Git-Pushes überhaupt blockieren kann. Ich fragte danach aquí .
0 Stimmen
Wie in anderen Kommentaren vorgeschlagen, ist die beste Option heutzutage die Verwendung von
git filter-repo
wie in diese Antwort0 Stimmen
Hier ist ein aktualisierter Link für die " Entfernen sensibler Daten " Link ursprünglich gepostet von @MBO