Ich möchte ein Git-Projekt auf GitHub stellen, aber es enthält bestimmte Dateien mit vertraulichen Daten (Benutzernamen und Passwörter wie /config/deploy.rb für capistrano).
Ich weiß, dass ich diese Dateinamen zu .gitignore hinzufügen kann , aber dies würde ihren Verlauf in Git nicht entfernen.
Ich möchte auch nicht noch einmal von vorne anfangen, indem ich das Verzeichnis /.git lösche.
Gibt es eine Möglichkeit, alle Spuren einer bestimmten Datei in Ihrem Git-Verlauf zu entfernen ?
Antworten:
Für alle praktischen Zwecke ist das erste , worüber Sie sich Sorgen machen sollten, das Ändern Ihrer Passwörter! Aus Ihrer Frage geht nicht hervor, ob Ihr Git-Repository vollständig lokal ist oder ob Sie noch ein Remote-Repository an einem anderen Ort haben. Wenn es entfernt und nicht vor anderen geschützt ist, haben Sie ein Problem. Wenn jemand dieses Repository geklont hat, bevor Sie dies beheben, hat er eine Kopie Ihrer Kennwörter auf seinem lokalen Computer, und Sie können ihn auf keinen Fall zwingen, auf Ihre "feste" Version zu aktualisieren, wenn diese aus dem Verlauf verschwunden ist. Das einzig sichere, was Sie tun können, ist, Ihr Passwort überall dort, wo Sie es verwendet haben, in etwas anderes zu ändern.
Hier erfahren Sie, wie Sie das Problem beheben können. GitHub beantwortete genau diese Frage als FAQ :
Hinweis für Windows-Benutzer : Verwenden Sie in diesem Befehl doppelte Anführungszeichen (") anstelle von einfachen Anführungszeichen
Update 2019:
Dies ist der aktuelle Code aus den FAQ:
Denken Sie daran, dass Sie sich jetzt in einer Situation befinden, in der Sie den Verlauf neu schreiben, sobald Sie diesen Code in ein Remote-Repository wie GitHub übertragen haben und andere dieses Remote-Repository geklont haben. Wenn andere versuchen, Ihre letzten Änderungen abzurufen, erhalten sie eine Meldung, dass die Änderungen nicht übernommen werden können, da es sich nicht um einen schnellen Vorlauf handelt.
Um dies zu beheben, müssen sie entweder ihr vorhandenes Repository löschen und es erneut klonen oder die Anweisungen unter "WIEDERHERSTELLEN VON UPSTREAM REBASE" in der git-rebase-Manpage befolgen .
Tipp : Ausführen
git rebase --interactive
Wenn Sie in Zukunft versehentlich einige Änderungen mit vertraulichen Informationen festschreiben, diese jedoch vor dem Verschieben in ein Remote-Repository bemerken , gibt es einige einfachere Korrekturen. Wenn Sie beim letzten Commit die vertraulichen Informationen hinzugefügt haben, können Sie die vertraulichen Informationen einfach entfernen und dann Folgendes ausführen:
Dadurch wird das vorherige Commit mit allen neuen Änderungen geändert, die Sie vorgenommen haben, einschließlich des vollständigen Entfernens von Dateien, die mit a vorgenommen wurden
git rm
. Wenn die Änderungen weiter zurück in der Historie liegen, aber immer noch nicht in ein Remote-Repository übertragen werden, können Sie eine interaktive Rebase durchführen:Dadurch wird ein Editor mit den Commits geöffnet, die Sie seit Ihrem letzten gemeinsamen Vorfahren mit dem Remote-Repository vorgenommen haben. Ändern Sie "pick" in "edit" in allen Zeilen, die ein Commit mit vertraulichen Informationen darstellen, und speichern und beenden Sie es. Git wird die Änderungen durchgehen und Sie an einem Ort zurücklassen, an dem Sie:
Für jede Änderung mit vertraulichen Informationen. Schließlich landen Sie wieder in Ihrer Filiale und können die neuen Änderungen sicher übertragen.
quelle
filter-branch
Code und dem auf der Github-Seite zu geben, auf die Sie verlinkt haben. ZB ihre 3. Zeile--prune-empty --tag-name-filter cat -- --all
. Hat sich die Lösung geändert oder fehlt mir etwas?<introduction-revision-sha1>..HEAD
funktioniert sie nicht. Die Datei wird erst ab dem zweiten Commit entfernt. (Wie füge ich das anfängliche Commit in den Bereich der Commits ein?) Der sichere Weg wird hier beschrieben: help.github.com/articles/…git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \ --prune-empty --tag-name-filter cat -- --all
Das Ändern Ihrer Passwörter ist eine gute Idee, aber für das Entfernen von Passwörtern aus dem Verlauf Ihres Repos empfehle ich den BFG Repo-Cleaner , eine schnellere und einfachere Alternative zu
git-filter-branch
Repos expliziten Entwerfen privater Daten aus Git-Repos.Erstellen Sie eine
private.txt
Datei mit den Kennwörtern usw., die Sie entfernen möchten (ein Eintrag pro Zeile), und führen Sie dann den folgenden Befehl aus:Alle Dateien mit einer Schwellengröße (standardmäßig 1 MB) im Verlauf Ihres Repos werden gescannt, und alle übereinstimmenden Zeichenfolgen (die nicht in Ihrem letzten Commit enthalten sind) werden durch die Zeichenfolge "*** ENTFERNT ***" ersetzt. Sie können dann
git gc
die toten Daten entfernen:Die BFG ist in der Regel 10-50-mal schneller als die Ausführung,
git-filter-branch
und die Optionen werden vereinfacht und auf diese beiden gängigen Anwendungsfälle zugeschnitten:Vollständige Offenlegung: Ich bin der Autor des BFG Repo-Cleaner.
quelle
git commit
. Ansonsten +1 für neues Tool in der Toolbox des Entwicklers :)These are your protected commits, and so their contents will NOT be altered
während es den Rest Ihres Commit-Verlaufs durchläuft und überarbeitet. Wenn Sie jedoch ein Rollback durchführen müssen, müssen***REMOVED***
Sie in dem Commit, auf das Sie gerade zurückgesetzt haben, nur nach suchen .Wenn Sie auf GitHub pushen, reicht ein erzwungenes Pushen nicht aus. Löschen Sie das Repository oder wenden Sie sich an den Support
Selbst wenn Sie eine Sekunde später einen Druck erzwingen, reicht dies nicht aus, wie unten erläutert.
Die einzig gültigen Vorgehensweisen sind:
Was hat einen veränderbaren Berechtigungsnachweis wie ein Passwort verloren?
nein (nackte Bilder):
Interessiert es Sie, wenn alle Probleme im Repository behoben werden?
Ja:
Eine Sekunde später zu drücken, reicht nicht aus, weil:
GitHub lässt Commits noch lange baumeln.
GitHub-Mitarbeiter haben die Möglichkeit, solche baumelnden Commits zu löschen, wenn Sie sie jedoch kontaktieren.
Ich habe dies aus erster Hand erlebt, als ich alle GitHub-Commit-E-Mails in ein Repo hochgeladen habe. Sie haben mich gebeten, es zu entfernen, also habe ich es getan, und sie haben es getan
gc
. Pull-Anfragen, die die Daten enthalten, müssen jedoch gelöscht werden : Diese Repo-Daten blieben aus diesem Grund bis zu einem Jahr nach der ersten Abschaltung zugänglich.Dangling Commits können entweder durch gesehen werden:
Eine bequeme Möglichkeit, die Quelle bei diesem Commit abzurufen, ist die Verwendung der Download-Zip-Methode, die alle Verweise akzeptieren kann, z. B.: Https://github.com/cirosantilli/myrepo/archive/SHA.zip
Es ist möglich, die fehlenden SHAs abzurufen, indem Sie:
type": "PushEvent"
. ZB meins: https://api.github.com/users/cirosantilli/events/public ( Wayback-Maschine )Es gibt Scrapper wie http://ghtorrent.org/ und https://www.githubarchive.org/ , die regelmäßig GitHub-Daten bündeln und an anderer Stelle speichern.
Ich konnte nicht feststellen, ob sie das tatsächliche Commit-Diff kratzen, und das ist unwahrscheinlich, da es zu viele Daten geben würde, aber es ist technisch möglich, und die NSA und Freunde haben wahrscheinlich Filter, um nur Dinge zu archivieren, die mit Personen oder Commits von Interesse verknüpft sind.
Wenn Sie das Repository löschen, anstatt nur das Drücken zu erzwingen, verschwinden Commits sogar sofort aus der API und geben 404 an, z. B. https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Dies funktioniert auch wenn Sie ein anderes Repository mit demselben Namen neu erstellen.
Um dies zu testen, habe ich ein Repo erstellt: https://github.com/cirosantilli/test-dangling und habe:
Siehe auch: Wie entferne ich ein baumelndes Commit von GitHub?
quelle
Ich empfehle dieses Skript von David Underhill, das für mich wie ein Zauber funktioniert hat.
Es fügt diese Befehle zusätzlich zum Filterzweig von natacado hinzu, um das Chaos zu beseitigen, das es hinterlässt:
Vollständiges Skript (alle Ehre gebührt David Underhill)
Die letzten beiden Befehle funktionieren möglicherweise besser, wenn sie wie folgt geändert werden:
quelle
git gc --aggressive --prune=now
Um es klar auszudrücken: Die akzeptierte Antwort ist richtig. Versuchen Sie es zuerst. In einigen Anwendungsfällen kann dies jedoch unnötig komplex sein, insbesondere wenn Sie auf unangenehme Fehler wie "fatal: bad revision --prune-empty" stoßen oder sich wirklich nicht um den Verlauf Ihres Repos kümmern.
Eine Alternative wäre:
Dadurch werden natürlich alle Commit-Verlaufszweige und Probleme sowohl aus Ihrem Github-Repo als auch aus Ihrem lokalen Git-Repo entfernt. Wenn dies nicht akzeptabel ist, müssen Sie einen alternativen Ansatz verwenden.
Nennen Sie dies die nukleare Option.
quelle
Sie können verwenden
git forget-blob
.Die Verwendung ist ziemlich einfach
git forget-blob file-to-forget
. Weitere Informationen erhalten Sie hierhttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Es verschwindet aus allen Commits in Ihrem Verlauf, Reflog, Tags und so weiter
Hin und wieder stoße ich auf das gleiche Problem, und jedes Mal, wenn ich auf diesen und andere Beiträge zurückkommen muss, habe ich den Prozess automatisiert.
Dank an die Mitwirkenden von Stack Overflow, mit denen ich dies zusammenstellen konnte
quelle
Hier ist meine Lösung in Windows
Stellen Sie sicher, dass der Pfad korrekt ist, da er sonst nicht funktioniert
Ich hoffe, es hilft
quelle
Verwendung Filterzweig :
quelle
Ich musste das bis jetzt ein paar Mal machen. Beachten Sie, dass dies jeweils nur für eine Datei funktioniert.
Rufen Sie eine Liste aller Commits ab, die eine Datei geändert haben. Der unten stehende wird den ersten Commit ausführen:
git log --pretty=oneline --branches -- pathToFile
Um die Datei aus dem Verlauf zu entfernen, verwenden Sie das erste Commit sha1 und den Pfad zur Datei aus dem vorherigen Befehl und füllen Sie sie in diesen Befehl:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
quelle
Es sieht also ungefähr so aus:
quelle
In meinem Android-Projekt hatte ich admob_keys.xml als getrennte XML-Datei im Ordner app / src / main / res / values / . Um diese vertrauliche Datei zu entfernen, habe ich das folgende Skript verwendet und perfekt funktioniert.
quelle