Dies ist der Befehl git-filter-branch, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann
PROGRAMM:
NAME/FUNKTION
git-filter-branch – Zweige neu schreiben
ZUSAMMENFASSUNG
git Filter-Zweig [--env-filter ] [--tree-filter ]
[--index-filter ] [--parent-filter ]
[--msg-filter ] [--commit-filter ]
[--tag-name-filter ] [--subdirectory-filter ]
[--prune-empty]
[--Original ] [-D ] [-f | --Gewalt]
[--] [ ...]
BESCHREIBUNG
Ermöglicht Ihnen das Umschreiben des Git-Revisionsverlaufs, indem Sie die in erwähnten Zweige neu schreiben
Optionen> und wendet benutzerdefinierte Filter auf jede Revision an. Diese Filter können jeden Baum ändern
(z. B. Entfernen einer Datei oder Ausführen eines Perl-Rewrites für alle Dateien) oder Informationen zu jeder Datei
begehen. Ansonsten alle Informationen (einschließlich ursprünglicher Festschreibungszeiten oder Zusammenführungsinformationen)
wird erhalten bleiben.
Der Befehl schreibt nur die um positiv Refs, die in der Befehlszeile erwähnt werden (z. B. wenn Sie
passieren a..b, nur b wird neu geschrieben). Wenn Sie keine Filter angeben, erfolgen die Commits
ohne Änderungen, die normalerweise keine Auswirkungen hätten, erneut übernommen. Dennoch ist dies
kann in Zukunft nützlich sein, um einige Git-Fehler oder ähnliches zu kompensieren
Die Nutzung ist gestattet.
HINWEIS: Dieser Befehl berücksichtigt die Datei .git/info/grafts und Refs im Namespace refs/replace/.
Wenn Sie Transplantate oder Ersatzrefs definiert haben, werden diese durch Ausführen dieses Befehls erstellt
dauerhaft.
WARNUNG! Der neu geschriebene Verlauf hat unterschiedliche Objektnamen für alle Objekte und
konvergiert nicht mit dem ursprünglichen Zweig. Sie werden nicht in der Lage sein, leicht zu schieben und
Verteilen Sie den umgeschriebenen Zweig über dem ursprünglichen Zweig. Bitte verwenden Sie dies nicht
Befehl, wenn Sie die vollständigen Auswirkungen nicht kennen, und vermeiden Sie es trotzdem, wenn es sich um einen einfachen Befehl handelt
Ein einziges Commit würde ausreichen, um Ihr Problem zu beheben. (Siehe Abschnitt „WIEDERHERSTELLUNG VON STROMAUFWÄRTS“)
Abschnitt „REBASE“ in Git-Rebase(1) Weitere Informationen zum Umschreiben veröffentlicht
Geschichte.)
Stellen Sie immer sicher, dass die neu geschriebene Version korrekt ist: Die Originalreferenzen, falls abweichend von
die umgeschriebenen werden im Namensraum gespeichert refs/original/.
Beachten Sie, dass es eine gute Idee sein könnte, eine Umleitung vorzunehmen, da dieser Vorgang sehr I/O-aufwändig ist
das temporäre Verzeichnis außerhalb der Festplatte mit dem -d Option, zB auf tmpfs. Berichten zufolge die Beschleunigung
ist sehr auffällig.
Filter
Die Filter werden in der unten aufgeführten Reihenfolge angewendet. Der Argument ist immer
im Shell-Kontext mit ausgewertet eval Befehl (mit der bemerkenswerten Ausnahme von
Commit-Filter, aus technischen Gründen). Davor die Umgebungsvariable $GIT_COMMIT
wird so eingestellt, dass es die ID des neu geschriebenen Commits enthält. Außerdem GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL und
GIT_COMMITTER_DATE werden aus dem aktuellen Commit übernommen und in die Umgebung exportiert
um die Autoren- und Committer-Identitäten des von erstellten Ersatz-Commits zu beeinflussen
Git-Commit-Baum(1) nachdem die Filter gelaufen sind.
Wenn eine Bewertung von Gibt einen Exit-Status ungleich Null zurück, der gesamte Vorgang wird ausgeführt
abgebrochen.
A Karte Es ist eine Funktion verfügbar, die ein „original sha1 id“-Argument annimmt und a ausgibt
„umgeschriebene SHA1-ID“, wenn der Commit bereits umgeschrieben wurde, und „ursprüngliche SHA1-ID“
ansonsten; Die Karte Die Funktion kann mehrere IDs in separaten Zeilen zurückgeben, wenn Ihr Commit-Filter vorhanden ist
mehrere Commits ausgegeben.
OPTIONAL
--env-filter
Dieser Filter kann verwendet werden, wenn Sie nur die Umgebung ändern müssen, in der der Commit ausgeführt wird
wird aufgeführt. Insbesondere möchten Sie möglicherweise den Autor/Committer neu schreiben
Name/E-Mail/Zeit-Umgebungsvariablen (siehe Git-Commit-Baum(1) für Einzelheiten). Unterlassen Sie
Vergessen Sie, die Variablen erneut zu exportieren.
--tree-filter
Dies ist der Filter zum Umschreiben des Baums und seines Inhalts. Das Argument wird ausgewertet
in der Shell, wobei das Arbeitsverzeichnis auf das Stammverzeichnis des ausgecheckten Baums festgelegt ist. Das neue
Der Baum wird dann unverändert verwendet (neue Dateien werden automatisch hinzugefügt, verschwundene Dateien werden automatisch entfernt).
- weder .gitignore-Dateien noch andere Ignorierregeln HABEN JEDEM BEWIRKEN!).
--index-filter
Dies ist der Filter zum Umschreiben des Index. Er ähnelt dem Baumfilter, ist aber so
Überprüfen Sie den Baum nicht, was ihn viel schneller macht. Wird häufig mit git rm verwendet
--cached --ignore-unmatch ..., siehe BEISPIELE unten. Für haarige Fälle siehe Git-Update-
Index(1).
--parent-filter
Dies ist der Filter zum Umschreiben der übergeordneten Liste des Commits. Es wird vom Elternteil empfangen
string auf stdin und soll den neuen übergeordneten String auf stdout ausgeben. Die übergeordnete Zeichenfolge ist
in dem in beschriebenem Format Git-Commit-Baum(1): leer für den ersten Commit, „-p
parent“ für einen normalen Commit und „-p parent1 -p parent2 -p parent3 ...“ für eine Zusammenführung
verpflichten.
--msg-filter
Dies ist der Filter zum Umschreiben der Commit-Nachrichten. Das Argument wird im ausgewertet
Shell mit der ursprünglichen Commit-Nachricht in der Standardeingabe; seine Standardausgabe wird verwendet
als neue Commit-Nachricht.
--commit-filter
Dies ist der Filter zum Durchführen des Commits. Wenn dieser Filter angegeben ist, wird dies der Fall sein
namens anstelle der git Commit-Baum Befehl, mit Argumenten der Form „
[(-P )...]“ und die Protokollmeldung auf stdin. Die Commit-ID wird erwartet
auf stdout.
Als besondere Erweiterung kann der Commit-Filter mehrere Commit-IDs ausgeben; In diesem Fall,
Die umgeschriebenen Kinder des ursprünglichen Commits werden alle als Eltern haben.
Sie können die Verwendung Karte Komfortfunktion in diesem Filter und andere Annehmlichkeiten
Funktionen auch. Zum Beispiel anrufen überspringen_commit "$@" wird den Strom weglassen
commit (aber nicht seine Änderungen! Wenn Sie das wollen, verwenden Sie git zurückweisen stattdessen).
Sie können auch git_commit_non_empty_tree „$@“ anstelle von git commit-tree „$@“ verwenden, wenn
Sie möchten keine Verpflichtungen mit einem alleinerziehenden Elternteil eingehen, und das ändert nichts daran
Baum.
--tag-name-filter
Dies ist der Filter zum Umschreiben von Tag-Namen. Wenn es übergeben wird, wird es für jeden aufgerufen
Tag-Referenz, die auf ein umgeschriebenes Objekt zeigt (oder auf ein Tag-Objekt, das auf a zeigt
umgeschriebenes Objekt). Der ursprüngliche Tag-Name wird über die Standardeingabe und das neue Tag übergeben
name wird in der Standardausgabe erwartet.
Die Original-Tags werden nicht gelöscht, können aber überschrieben werden; Verwenden Sie „--tag-name-filter cat“
um einfach die Tags zu aktualisieren. Seien Sie in diesem Fall sehr vorsichtig und stellen Sie sicher, dass Sie das haben
Alte Tags werden gesichert, falls die Konvertierung fehlgeschlagen ist.
Ein nahezu korrektes Umschreiben von Tag-Objekten wird unterstützt. Wenn das Tag eine Nachricht enthält
angehängt, wird ein neues Tag-Objekt mit derselben Nachricht, demselben Autor und demselben erstellt
Zeitstempel. Wenn dem Tag eine Signatur beigefügt ist, wird die Signatur entfernt. Es ist
Per Definition ist es unmöglich, Signaturen aufzubewahren. Der Grund, warum dies „fast“ richtig ist,
liegt daran, dass sich das Tag im Idealfall nicht geändert hat (auf dasselbe Objekt zeigt, dasselbe hat).
Name usw.) sollte jede Unterschrift erhalten bleiben. Das ist nicht der Fall, Unterschriften werden es tun
immer entfernt werden, Käufer aufgepasst. Es gibt auch keine Unterstützung für das Ändern des Autors oder
Zeitstempel (oder die Tag-Nachricht). Tags, die auf andere Tags verweisen, werden angezeigt
umgeschrieben, um auf den zugrunde liegenden Commit zu verweisen.
--subdirectory-filter
Sehen Sie sich nur den Verlauf an, der das angegebene Unterverzeichnis berührt. Das Ergebnis enthält
dieses Verzeichnis (und nur dieses) als Projektstammverzeichnis. Impliziert den Abschnitt „Remap“.
zum Vorfahren“.
--prune-leer
Einige Filter erzeugen leere Commits, die den Baum unberührt lassen. Das
Mit dem Schalter kann Git-Filter-Branch solche Commits ignorieren. Allerdings nur dieser Schalter
gilt für Commits, die ein und nur ein übergeordnetes Element haben, daher werden Zusammenführungen beibehalten
Punkte. Außerdem ist diese Option nicht mit der Verwendung von kompatibel --commit-filter. Obwohl
Sie müssen nur die Funktion verwenden git_commit_non_empty_tree "$@" statt des Idioten
commit-tree „$@“ Idiom in Ihrem Commit-Filter, um dies zu erreichen.
--Original
Verwenden Sie diese Option, um den Namespace festzulegen, in dem die ursprünglichen Commits gespeichert werden. Der
Standardwert ist Referenzen/Original.
-D
Mit dieser Option legen Sie den Pfad zum temporären Verzeichnis fest, das zum Umschreiben verwendet wird. Wann
Durch Anwenden eines Baumfilters muss der Befehl den Baum vorübergehend auf einige überprüfen
Verzeichnis, das bei großen Projekten viel Platz beanspruchen kann. Standardmäßig
es tut dies in der .git-rewrite/ Verzeichnis, aber Sie können diese Auswahl dadurch überschreiben
Parameters.
-f, --force
git Filter-Zweig weigert sich, mit einem vorhandenen temporären Verzeichnis zu beginnen oder wenn dort
sind bereits Schiedsrichter, beginnend mit refs/original/, sofern nicht erzwungen.
...
Argumente für git Drehzahlliste. Alle in diesen Optionen enthaltenen positiven Referenzen werden neu geschrieben.
Sie können auch Optionen angeben, z --alle, aber Sie müssen verwenden -- um sie zu trennen
git Filter-Zweig Optionen. Impliziert den Abschnitt „Neuzuordnung zum Vorfahren“.
Neu zuordnen zu Vorfahr
Durch die Nutzung Drehzahlliste(1) Argumente, z. B. Pfadbegrenzer, können Sie die Menge der Revisionen einschränken
die umgeschrieben werden. Positive Refs auf der Kommandozeile werden jedoch unterschieden: we
Lassen Sie nicht zu, dass sie durch solche Begrenzer ausgeschlossen werden. Zu diesem Zweck werden sie stattdessen neu geschrieben
auf den nächsten Vorfahren hinweisen, der nicht ausgeschlossen wurde.
Beispiele:
Angenommen, Sie möchten eine Datei entfernen (die vertrauliche Informationen oder Urheberrechte enthält).
Verstoß) aus allen Commits:
git filter-branch --tree-filter 'rm filename' HEAD
Wenn die Datei jedoch im Baum eines Commits fehlt, wird ein einfacher rm-Dateiname verwendet
Scheitern Sie für diesen Baum und begehen Sie einen Commit. Daher möchten Sie möglicherweise stattdessen rm -f Dateiname als verwenden
Skripte.
Verwenden von --index-filter mit git rm ergibt eine deutlich schnellere Version. Wie bei der Verwendung von rm
filename, git rm --cached filename schlägt fehl, wenn die Datei nicht im Baum von a vorhanden ist
begehen. Wenn Sie eine Datei „komplett vergessen“ möchten, spielt es keine Rolle, wann sie eingegeben wurde
Verlauf, also fügen wir auch --ignore-unmatch hinzu:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
Jetzt wird der neu geschriebene Verlauf in HEAD gespeichert.
Um das Repository so umzuschreiben, dass es so aussieht, als wäre foodir/ sein Projektstamm gewesen, und alles verwerfen
andere Geschichte:
git filter-branch --subdirectory-filter foodir -- --all
So können Sie beispielsweise ein Bibliotheksunterverzeichnis in ein eigenes Repository verwandeln. Beachten Sie das --
das trennt Filter-Zweig Optionen aus Revisionsoptionen und --all, um alle neu zu schreiben
Zweige und Tags.
Um einen Commit (der normalerweise an der Spitze eines anderen Verlaufs steht) als übergeordnetes Element festzulegen
aktuelles anfängliches Commit, um den anderen Verlauf hinter dem aktuellen Verlauf einzufügen:
git filter-branch --parent-filter 'sed "s/^\$/-p /"' KOPF
(Wenn die übergeordnete Zeichenfolge leer ist – was passiert, wenn wir uns mit dem ersten Commit befassen
- graftcommit als übergeordnetes Element hinzufügen). Beachten Sie, dass dies einen Verlauf mit einer einzigen Wurzel voraussetzt (das
Das heißt, es kam zu keiner Verschmelzung ohne gemeinsame Vorfahren. Ist dies nicht der Fall, verwenden Sie:
git filter-branch --parent-filter \
'test $GIT_COMMIT = && echo "-p " || Katzenkopf
oder noch einfacher:
echo „$commit-id $graft-id“ >> .git/info/grafts
git filter-branch $graft-id..HEAD
So entfernen Sie von „Darl McBribe“ verfasste Commits aus dem Verlauf:
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
dann
skip_commit "$@";
sonst
git commit-tree „$@“;
fi' KOPF
Die Funktion überspringen_commit ist wie folgt definiert:
skip_commit()
{
Schicht;
while [ -n "$1" ];
do
Schicht;
Karte „$1“;
Schicht;
getan;
}
Die Shift-Magie verwirft zuerst die Baum-ID und dann die -p-Parameter. Beachten Sie, dass dies
Behandelt Zusammenführungen richtig! Falls Darl eine Zusammenführung zwischen P1 und P2 vorgenommen hat, wird dies der Fall sein
ordnungsgemäß weitergegeben und alle untergeordneten Elemente der Zusammenführung werden zu Zusammenführungs-Commits mit P1, P2 als
ihre Eltern anstelle des Merge-Commits.
HINWEIS die durch die Commits eingeführten Änderungen, die durch nachfolgende Commits nicht rückgängig gemacht werden
Commits befinden sich weiterhin im neu geschriebenen Zweig. Wenn Sie wegwerfen wollen Änderungen gemeinsam
Bei den Commits sollten Sie den interaktiven Modus von verwenden git zurückweisen.
Sie können die Commit-Log-Meldungen mit --msg-filter umschreiben. Zum Beispiel, git svn-id
Zeichenfolgen in einem Repository, erstellt von git svn kann folgendermaßen entfernt werden:
git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'
Wenn Sie hinzufügen müssen Bestätigt von Zeilen zu beispielsweise den letzten 10 Commits (von denen keines eine Zusammenführung ist),
Verwenden Sie diesen Befehl:
git filter-branch --msg-filter '
Katze &&
echo „Bestätigt von: Bugs Bunny[E-Mail geschützt] >"
' KOPF~10..KOPF
Die Option --env-filter kann verwendet werden, um die Identität des Committers und/oder Autors zu ändern. Für
Wenn Sie beispielsweise feststellen, dass Ihre Commits aufgrund einer Fehlkonfiguration die falsche Identität haben
user.email können Sie vor der Veröffentlichung des Projekts eine Korrektur vornehmen, etwa so:
git filter-branch --env-filter '
if test „$GIT_AUTHOR_EMAIL“ = „root@localhost“
dann
GIT_AUTHOR_EMAIL=[E-Mail geschützt]
GIT_AUTHOR_EMAIL exportieren
fi
if test „$GIT_COMMITTER_EMAIL“ = „root@localhost“
dann
GIT_COMMITTER_EMAIL=[E-Mail geschützt]
GIT_COMMITTER_EMAIL exportieren
fi
' -- --alle
Um das Neuschreiben nur auf einen Teil des Verlaufs zu beschränken, geben Sie zusätzlich einen Revisionsbereich an
der neue Filialname. Der neue Zweigname verweist auf die oberste Revision, die a git
Drehzahlliste aus diesem Bereich wird gedruckt.
Betrachten Sie diese Geschichte:
D--E--F--G--H
/ /
ABC
Um nur die Commits D, E, F, G, H umzuschreiben, A, B und C jedoch in Ruhe zu lassen, verwenden Sie:
git filter-branch ... C..H
Um die Commits E,F,G,H neu zu schreiben, verwenden Sie eines davon:
git filter-branch ... C..H – nicht D
git filter-branch ... D..H – nicht C
Um den gesamten Baum in ein Unterverzeichnis zu verschieben oder von dort zu entfernen:
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
CHECKLISTE FÜR SCHRUMPFUNG A REPOSITORY
git-filter-branch kann verwendet werden, um eine Teilmenge von Dateien zu entfernen, normalerweise einige
Kombination aus --index-filter und --subdirectory-filter. Die Menschen erwarten das Ergebnis
Das Repository muss kleiner als das Original sein, es sind jedoch noch ein paar weitere Schritte erforderlich, um es tatsächlich durchzuführen
es kleiner, weil Git sich sehr bemüht, Ihre Objekte nicht zu verlieren, bis Sie es ihm sagen. Erste
Stelle sicher das:
· Sie haben tatsächlich alle Varianten eines Dateinamens entfernt, wenn ein Blob im Laufe seiner Lebensdauer verschoben wurde.
git log --name-only --follow --all --filename kann Ihnen bei der Suche nach Umbenennungen helfen.
· Sie haben wirklich alle Refs gefiltert: Verwenden Sie beim Aufrufen --tag-name-filter cat -- --all
Git-Filter-Zweig.
Dann gibt es zwei Möglichkeiten, ein kleineres Repository zu erhalten. Eine sicherere Methode ist das Klonen, das bleibt erhalten
Ihr Original intakt.
· Klonen Sie es mit git clone file:///path/to/repo. Der Klon wird nicht entfernt
Objekte. Sehen Git-Klon(1). (Beachten Sie, dass das Klonen mit einem einfachen Pfad nur Hardlinks darstellt
alles!)
Wenn Sie es aus welchen Gründen auch immer wirklich nicht klonen möchten, überprüfen Sie die folgenden Punkte
stattdessen (in dieser Reihenfolge). Das ist also ein sehr destruktiver Ansatz um a Sicherungskopie oder geh zurück
um es zu klonen. Du wurdest gewarnt.
· Entfernen Sie die ursprünglichen Refs, die von git-filter-branch gesichert wurden: sagen Sie git for-each-ref
--format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d.
· Lassen Sie alle Reflogs mit git reflog expire --expire=now --all ablaufen.
· Garbage Collection aller nicht referenzierten Objekte mit git gc --prune=now (oder wenn Ihr git-gc ist
nicht neu genug, um Argumente für --prune zu unterstützen, verwenden Sie git repack -ad; Git Prune
stattdessen).
ANMERKUNG
Mit Git-Filter-Branch können Sie komplexe Shell-Skript-Umschreibungen Ihres Git-Verlaufs durchführen.
Aber Sie brauchen diese Flexibilität wahrscheinlich nicht, wenn Sie einfach sind Entfernen unerwünscht die Datenerfassung Gefällt mir
große Dateien oder Passwörter. Für diese Vorgänge sollten Sie vielleicht in Betracht ziehen Das BFG
Repo-Cleaner[1], eine JVM-basierte Alternative zu Git-Filter-Branch, typischerweise mindestens 10-50x
schneller für diese Anwendungsfälle und mit ganz anderen Eigenschaften:
· Jede bestimmte Version einer Datei wird genau bereinigt einmal. Die BFG hingegen
git-filter-branch bietet Ihnen nicht die Möglichkeit, eine Datei anders zu behandeln
basierend darauf, wo oder wann es in Ihrer Geschichte begangen wurde. Diese Einschränkung ergibt die
Kernleistungsvorteil des BFG und eignet sich gut für die Aufgabe, schlechtes zu reinigen
Daten - es ist Ihnen egal woher Die schlechten Daten sind, dass Sie es einfach wollen weg.
· Standardmäßig nutzt die BFG die Vorteile von Multi-Core-Maschinen voll aus und bereinigt das Commit
Dateibäume parallel. git-filter-branch bereinigt Commits nacheinander (d. h. in a
Single-Threaded-Methode), obwohl es is Es ist möglich, Filter zu schreiben, die ihre eigenen enthalten
Parallelität in den Skripten, die für jedes Commit ausgeführt werden.
· Das Befehl Optionen[2] sind viel restriktiver als der Git-Filter-Zweig und dediziert
nur zu den Aufgaben des Entfernens unerwünschter Daten, z. B.: --strip-blobs-bigger-than 1M.
GIT
Ein Teil des git(1) Suite
ANMERKUNG
1. Der BFG Repo-Cleaner
http://rtyley.github.io/bfg-repo-cleaner/
2. Befehlsoptionen
http://rtyley.github.io/bfg-repo-cleaner/#Beispiele
Verwenden Sie git-filter-branch online über die Dienste von onworks.net