Entfernen Sie sensible Dateien und ihre Commits aus der Git -Geschichte
-
22-08-2019 - |
Frage
Ich möchte ein Git -Projekt auf GitHub einstellen, aber es enthält bestimmte Dateien mit sensiblen Daten (Benutzernamen und Passwörter wie /config/deploy.rb für Capistrano).
Ich weiß, dass ich diese Dateinamen hinzufügen kann .Gitignore, aber das würde ihre Geschichte innerhalb von Git nicht beseitigen.
Ich möchte auch nicht wieder von vorne beginnen, indem ich das /.git -Verzeichnis lösche.
Gibt es eine Möglichkeit zum Entfernen? alle Spuren einer bestimmten Datei in Ihrem Git -Verlauf?
Lösung
Für alle praktischen Zwecke die Erste Sie sollten sich Sorgen machen, ist Ä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 anderer Stelle haben. Wenn es abgelegen und nicht von anderen gesichert ist, haben Sie ein Problem. Wenn jemand dieses Repository vor der Behebung von diesem Repository kloniert hat, verfügt er über eine Kopie Ihrer Passwörter auf seinem lokalen Computer. Es gibt keine Möglichkeit, sie zu einer Aktualisierung Ihrer "behobenen" Version mit dieser aus der Geschichte zu aktualisieren. Das einzig sichere, was Sie tun können, ist Ihr Passwort in etwas anderes zu ändern, wo Sie es verwendet haben.
Damit aus dem Weg herauszufinden, wie Sie es beheben können. Github beantwortete genau diese Frage als FAQ:
Hinweis für Windows -Benutzer: Verwenden Sie in diesem Befehl Doppelzitate (") anstelle von Singles
git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
Denken Sie daran, dass Sie sich jetzt in einer Situation befinden, in der Sie die Geschichte neu schreiben. Wenn andere versuchen, Ihre neuesten Änderungen danach abzurufen, erhalten sie eine Nachricht, die angibt, dass die Änderungen nicht angewendet werden können, da sie nicht schnell vorwärts gehen.
Um dies zu beheben, müssen sie entweder ihr vorhandenes Repository löschen und sie erneut klingen oder die Anweisungen unter "Wiederherstellung von vorgelagerter Rebase" in der befolgen Git-Rebase Manpage.
Wenn Sie in Zukunft versehentlich einige Änderungen mit sensiblen Informationen begehen, aber Sie bemerken Vor Wenn Sie in ein Remote -Repository drücken, gibt es einige einfachere Korrekturen. Wenn Sie das letzte Mal die sensible Informationen hinzufügen, können Sie einfach die empfindlichen Informationen entfernen und dann ausführen:
git commit -a --amend
Dies ändert das vorherige Commit mit neuen Änderungen, die Sie vorgenommen haben, einschließlich der gesamten Dateiumrichter git rm
. Wenn die Änderungen weiter in die Geschichte zurückzuführen sind, aber immer noch nicht in ein Remote -Repository gedrängt werden, können Sie eine interaktive Rebase durchführen:
git rebase -i origin/master
Das öffnet einen Redakteur mit den Commits, die Sie seit Ihrem letzten gemeinsamen Vorfahren mit dem Remote -Repository gemacht haben. Ändern Sie "auswählen" in "Bearbeiten" in allen Zeilen, die einen Commit mit vertraulichen Informationen darstellen, und speichern und beenden. Git wird durch die Änderungen gehen und Sie an einem Ort lassen, an dem Sie können:
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
Für jede Änderung mit sensiblen Informationen. Schließlich werden Sie wieder in Ihrer Niederlassung landen und Sie können die neuen Änderungen sicher schieben.
Andere Tipps
Das Ändern Ihrer Passwörter ist eine gute Idee, aber für den Prozess des Entfernens von Passwort aus der Geschichte Ihres Repos empfehle ich die BFG Repo-Cleaner, eine schnellere, einfachere Alternative zu git-filter-branch
Explizit entwickelt, um private Daten aus Git -Repos zu entfernen.
Ein ... kreieren private.txt
Dateiauflistung der Passwörter usw., die Sie entfernen möchten (ein Eintrag pro Zeile) und dann diesen Befehl ausführen:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
Alle Dateien unter einer Schwellenwertgröße (standardmäßig 1 MB) im Verlauf Ihres Repos werden gescannt, und jede passende Zeichenfolge (die nicht in Ihrem liegt neueste Commit) wird durch die Zeichenfolge "*** entfernt ***" ersetzt. Sie können dann verwenden git gc
Um die toten Daten wegzuräumen:
$ git gc --prune=now --aggressive
Das BFG ist in der Regel 10-50x schneller als das Laufen git-filter-branch
und die Optionen werden vereinfacht und auf diese beiden häufigen Anwendungsfälle zugeschnitten:
- Entfernen Verrückte große Dateien
- Entfernen Passwörter, Anmeldeinformationen & Sonstiges Private Daten
Vollständige Offenlegung: Ich bin der Autor des BFG Repo-Cleaner.
Ich empfehle dieses Skript Von David Underhill arbeitete für mich wie ein Zauber.
Es fügt diese Befehle zusätzlich hinzu, dass Natacados Filter-Branch das durcheinander liegende Chaos aufräumt:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
Vollständiges Skript (alles Guthaben an David Underhill)
#!/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
Die letzten beiden Befehle können besser funktionieren, wenn sie in Folgendes geändert werden:
git reflog expire --expire=now --all && \
git gc --aggressive --prune=now
Wenn Sie auf GitHub gedrängt haben, reicht das Kraftschieben nicht aus, löschen Sie das Repository oder Kontaktunterstützung
Selbst wenn Sie danach eine Sekunde drücken, reicht es nicht aus, wie unten erläutert.
Die einzigen gültigen Aktionskurse sind:
Hat ein veränderlicher Anmeldeinformator wie ein Passwort durchgesickert?
- Ja: Ändern Sie Ihre Passwörter sofort und überlegen Sie, ob Sie mehr OAuth- und API -Schlüssel verwenden!
Nein (nackte Bilder):
Interessiert es Sie, ob alle Probleme im Repository ein Nuk werden?
- Nein: Löschen Sie das Repository
Jawohl:
- Kontaktieren Sie Support
- Wenn das Leck für Sie sehr kritisch ist, bis zu dem Punkt, dass Sie bereit sind, einige Ausfallzeiten von Repository zu erhalten, damit es weniger wahrscheinlich ist, dass Sie austreten. mach es privat Während Sie auf GitHub -Unterstützung warten, um Ihnen zu antworten
Die Kraft, die eine Sekunde später drückt, reicht nicht aus, weil:
Github baumelt für lange Zeit.
Github Staff hat die Befugnis, solche baumelnden Commits zu löschen, wenn Sie sie jedoch kontaktieren.
Ich habe diese aus erster Hand erlebt, als ich Hochgeladen alle Github -Beiten -E -Mails an ein Repo Sie baten mich, es niederzusetzen, also tat ich es und sie machten eine
gc
. Ziehen Sie Anfragen an, die die Daten enthalten müssen jedoch gelöscht werden: Diese Repo -Daten blieben aufgrund dessen bis zu einem Jahr nach dem ersten Takedown zugänglich.Baumelnde Commits sind entweder durch zu sehen: durch:
- Die Commit -Web -Benutzeroberfläche: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bb59f2faa34EBA15CD89EF8E83 (Wayback -Maschine)
- Die API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092BBB59F2FAA34EBA15CD89EF8E83 (Wayback -Maschine)
Eine bequeme Möglichkeit, die Quelle in diesem Commit zu erhalten, besteht darin, die Download -ZIP -Methode zu verwenden, die jede Referenz akzeptieren kann, z. B.: https://github.com/cirosantilli/myrepo/archive/sha.zip
Es ist möglich, die fehlenden SHAs zu holen, entweder durch:
- API -Ereignisse auflisten mit
type": "PushEvent"
. ZB MEINE: https://api.github.com/users/cirosantilli/events/public (Wayback -Maschine) - Manchmal bequemer, indem Sie die Shas von Pull -Anfragen betrachten, die versuchten, den Inhalt zu entfernen
- API -Ereignisse auflisten mit
Es gibt Scrapper wie http://ghtorrent.org/ und https://www.githubarchive.org/ Das bündelt regelmäßig Github -Daten und speichert sie an anderer Stelle.
Ich konnte nicht herausfinden, ob sie den tatsächlichen Festungsdifferenz kratzen, und das ist unwahrscheinlich, weil es zu viele Daten gibt, aber es ist technisch möglich, und die NSA und Freunde haben wahrscheinlich Filter, um nur Dinge zu archivieren, die mit Menschen oder Commits von Interesse verbunden sind.
Wenn Sie das Repository löschen, anstatt nur das Schieben zu erzwingen, verschwinden Commits sogar von der API sofort und geben 404, z. B. https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2d653f7a3824 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 tat:
git init
git remote add origin git@github.com:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
Siehe auch: Wie entfernen Sie einen baumelnden Commit von Github?
Um klar zu sein: Die akzeptierte Antwort ist korrekt. Versuchen Sie es zuerst. Für einige Anwendungsfälle kann es jedoch unnötig komplex sein, insbesondere wenn Sie widerwärtige Fehler wie „Fatal: Bad Revision-Prune-Leery“ oder die Geschichte Ihres Repos wirklich nicht interessieren.
Eine Alternative wäre:
- CD zur Basiszweig des Projekts
- Entfernen Sie den sensiblen Code / die sensible Code / den sensiblen Code / die Datei
- RM -rf .git/ # Entfernen Sie alle Git -Informationen aus Ihrem Code
- Gehen Sie zu Github und löschen Sie Ihr Repository
- Befolgen Sie diese Anleitung, um Ihren Code in ein neues Repository zu bringen, wie Sie es normalerweise tun würden -https://help.github.com/articles/adding-an-existing-project-t-github-using-the-command-line/
Dies wird natürlich alle Feststellungszweige und Themen sowohl aus Ihrem Github Repo als auch Ihrem lokalen Git -Repo entfernen. Wenn dies nicht akzeptabel ist, müssen Sie einen alternativen Ansatz verwenden.
Nennen Sie dies die nukleare Option.
Hier ist meine Lösung in Windows
Git Filter-Branch-Street-Filter "RM -f 'Farredir/Dateiname'" Kopf
Git Push -Force
Stellen Sie sicher, dass der Pfad korrekt ist, sonst funktioniert er nicht
Ich hoffe, es hilft
Verwenden Filter-Branch:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all
git push origin *branch_name* -f
Sie können verwenden git forget-blob
.
Die Verwendung ist ziemlich einfach git forget-blob file-to-forget
. Sie können hier weitere Informationen erhalten
https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-d-blob/
Es wird aus allen Commits in Ihrer Geschichte, Ihrem Reflog, den Tags usw. verschwinden
Ich bin ab und zu auf dasselbe Problem und jedes Mal, wenn ich zu diesem und anderen Beitrag zurückkehren muss, habe ich den Prozess automatisiert.
Credits an Mitwirkende von Stack Overflow, die es mir ermöglichten, dies zusammenzustellen
Ich musste das ein paar Mal zu tun. Beachten Sie, dass dies nur in 1 Datei gleichzeitig funktioniert.
Erhalten Sie eine Liste aller Commits, die eine Datei geändert haben. Der untere wird das erste Commit:
git log --pretty=oneline --branches -- pathToFile
Um die Datei aus dem Verlauf zu entfernen, verwenden Sie das erste Commit SHA1 und den Pfad zum Datei aus dem vorherigen Befehl und füllen Sie sie in diesen Befehl aus:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
Also sieht es so aus:
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
Entfernen Sie den Cache für verfolgte Datei von Git und fügen Sie diese Datei zu Hinzufügen zu
.gitignore
aufführen
In meinem Android -Projekt hatte ich admob_keys.xml als getrennte XML -Datei in app/src/main/res/values/ Mappe. Um diese sensible Datei zu entfernen, die ich unten verwendet und perfekt gearbeitet habe.
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch app/src/main/res/values/admob_keys.xml' \
--prune-empty --tag-name-filter cat -- --all