English ▾ Themen ▾ Neueste Version ▾ gitdiffcore zuletzt aktualisiert in 2.44.0

NAME

gitdiffcore - Tweaken der Diff-Ausgabe

SYNOPSIS

git diff *

BESCHREIBUNG

Die Diff-Befehle git diff-index, git diff-files und git diff-tree können angewiesen werden, Unterschiede, die sie finden, auf unkonventionelle Weise zu manipulieren, bevor die diff-Ausgabe angezeigt wird. Die Manipulation wird kollektiv als "Diffcore-Transformation" bezeichnet. Diese kurze Notiz beschreibt, was sie sind und wie man sie verwendet, um eine diff-Ausgabe zu erzeugen, die leichter zu verstehen ist als die herkömmliche.

Die Operationskette

Die Familie git diff-* arbeitet, indem sie zunächst zwei Dateisätze vergleicht

  • git diff-index vergleicht den Inhalt eines "tree"-Objekts und des Arbeitsverzeichnisses (wenn das Flag --cached nicht verwendet wird) oder eines "tree"-Objekts und der Indexdatei (wenn das Flag --cached verwendet wird);

  • git diff-files vergleicht den Inhalt der Indexdatei und des Arbeitsverzeichnisses;

  • git diff-tree vergleicht den Inhalt zweier "tree"-Objekte;

In all diesen Fällen begrenzen die Befehle selbst zunächst optional die beiden Dateisätze anhand von Pathspecs, die auf ihren Befehlszeilen angegeben sind, und vergleichen entsprechende Pfade in den beiden resultierenden Dateisätzen.

Die Pathspecs werden verwendet, um die Welt, in der Diff operiert, einzuschränken. Sie entfernen die Dateipaare außerhalb der angegebenen Satz von Pfadnamen. Z. B. wenn der Eingabesatz von Dateipaaren

:100644 100644 bcd1234... 0123456... M junkfile

enthielt, die Befehlsinvokation aber git diff-files myfile lautete, dann würde der Eintrag "junkfile" aus der Liste entfernt, da nur "myfile" berücksichtigt wird.

Das Ergebnis des Vergleichs wird von diesen Befehlen an das intern "diffcore" genannte übergeben, in einem Format, das dem ähnelt, was ausgegeben wird, wenn die Option -p nicht verwendet wird. Z.B.:

in-place edit  :100644 100644 bcd1234... 0123456... M file0
create         :000000 100644 0000000... 1234567... A file4
delete         :100644 000000 1234567... 0000000... D file5
unmerged       :000000 000000 0000000... 0000000... U file6

Der Diffcore-Mechanismus erhält eine Liste solcher Vergleichsergebnisse (jedes davon wird "Dateipaar" genannt, obwohl jedes davon zu diesem Zeitpunkt über eine einzelne Datei spricht) und transformiert eine solche Liste in eine andere Liste. Derzeit gibt es 5 solche Transformationen:

  • diffcore-break

  • diffcore-rename

  • diffcore-merge-broken

  • diffcore-pickaxe

  • diffcore-order

  • diffcore-rotate

Diese werden nacheinander angewendet. Der Satz von Dateipaaren, den die Befehle git diff-* finden, wird als Eingabe für diffcore-break verwendet, und die Ausgabe von diffcore-break wird als Eingabe für die nächste Transformation verwendet. Das Endergebnis wird dann an die Ausgaberoutine übergeben und erzeugt entweder das Diff-Rohformat (siehe Abschnitte zur Ausgabeformatierung im Handbuch für git diff-* Befehle) oder das Diff-Patch-Format.

diffcore-break: Zum Aufteilen vollständiger Neufassungen

Die zweite Transformation in der Kette ist diffcore-break und wird durch die Option -B der git diff-* Befehle gesteuert. Dies wird verwendet, um ein Dateipaar zu erkennen, das eine "vollständige Neufassung" darstellt, und ein solches Dateipaar in zwei Dateipaare zu zerlegen, die Löschung und Erstellung darstellen. Z.B. wenn die Eingabe dieses Dateipaar enthielt:

:100644 100644 bcd1234... 0123456... M file0

und wenn erkannt wird, dass die Datei "file0" vollständig neu geschrieben wurde, wird sie in

:100644 000000 bcd1234... 0000000... D file0
:000000 100644 0000000... 0123456... A file0

umgewandelt. Zum Zerlegen eines Dateipaares untersucht diffcore-break das Ausmaß der Änderungen zwischen den Inhalten der Dateien vor und nach der Änderung (d.h. die Inhalte, die "bcd1234…" und "0123456…" als ihre SHA-1 Inhalts-ID haben, im obigen Beispiel). Die Menge der gelöschten Originalinhalte und die Menge der eingefügten neuen Materialien werden addiert, und wenn sie den "Break-Score" überschreiten, wird das Dateipaar in zwei geteilt. Der Break-Score ist standardmäßig 50% der Größe des kleineren der Original- und Ergebnisdatei (d.h. wenn die Bearbeitung die Datei verkleinert, wird die Größe des Ergebnisses verwendet; wenn die Bearbeitung die Datei vergrößert, wird die Größe des Originals verwendet), und kann durch Angabe einer Zahl nach der Option "-B" angepasst werden (z. B. "-B75", um 75% zu verwenden).

diffcore-rename: Zum Erkennen von Umbenennungen und Kopien

Diese Transformation wird zum Erkennen von Umbenennungen und Kopien verwendet und wird durch die Option -M (zum Erkennen von Umbenennungen) und die Option -C (zum Erkennen von Kopien) der git diff-* Befehle gesteuert. Wenn die Eingabe diese Dateipaare enthielt:

:100644 000000 0123456... 0000000... D fileX
:000000 100644 0000000... 0123456... A file0

und der Inhalt der gelöschten Datei fileX dem Inhalt der erstellten Datei file0 ausreichend ähnlich ist, dann werden diese Dateipaare durch Umbenennungserkennung zusammengeführt und es wird

:100644 100644 0123456... 0123456... R100 fileX file0

erzeugt. Wenn die Option "-C" verwendet wird, werden die Originalinhalte von geänderten Dateien, gelöschten Dateien (und auch unveränderten Dateien, wenn die Option "--find-copies-harder" verwendet wird) als Kandidaten für die Quelldateien bei Umbenennungs-/Kopieroperationen betrachtet. Wenn die Eingabe wie diese Dateipaare aussah, die über eine geänderte Datei fileY und eine neu erstellte Datei file0 sprechen:

:100644 100644 0123456... 1234567... M fileY
:000000 100644 0000000... bcd3456... A file0

werden die Originalinhalte von fileY und die resultierenden Inhalte von file0 verglichen, und wenn sie ausreichend ähnlich sind, werden sie in

:100644 100644 0123456... 1234567... M fileY
:100644 100644 0123456... bcd3456... C100 fileY file0

geändert. Sowohl bei der Umbenennungs- als auch bei der Kopiererkennung wird derselbe "Umfang der Änderungen"-Algorithmus wie bei diffcore-break verwendet, um festzustellen, ob zwei Dateien "ausreichend ähnlich" sind, und kann durch Angabe einer Zahl nach der Option "-M" oder "-C" angepasst werden, um einen anderen Ähnlichkeitswert als den Standardwert von 50% zu verwenden (z. B. "-M8", um 8/10 = 80% zu verwenden).

Beachten Sie, dass bei aktivierter Umbenennungserkennung, aber deaktivierter Kopier- und Break-Erkennung, die Umbenennungserkennung einen vorbereitenden Schritt hinzufügt, der zuerst prüft, ob Dateien über Verzeichnisse hinweg verschoben werden, wobei ihr Dateiname beibehalten wird. Wenn eine Datei zu einem Verzeichnis hinzugefügt wird, deren Inhalt einer Datei mit demselben Namen, die aus einem anderen Verzeichnis gelöscht wurde, ausreichend ähnlich ist, wird sie als umbenannt markiert und vom späteren quadratischen Schritt ausgeschlossen (dem, der alle nicht übereinstimmenden Dateien paarweise vergleicht, um die "besten" Übereinstimmungen zu finden, die durch die höchste Inhaltsähnlichkeit bestimmt werden). Wenn also z. B. eine gelöschte docs/ext.txt und eine hinzugefügte docs/config/ext.txt ausreichend ähnlich sind, werden sie als Umbenennung markiert und verhindern, dass eine hinzugefügte docs/ext.md, die vielleicht sogar ähnlicher zur gelöschten docs/ext.txt ist, als Umbenennungsziel im späteren Schritt berücksichtigt wird. Aus diesem Grund verwendet der vorbereitende Schritt "gleicher Dateiname" einen etwas höheren Schwellenwert, um ein Dateipaar als Umbenennung zu markieren und andere Kandidaten für bessere Übereinstimmungen nicht weiter zu berücksichtigen. Höchstens ein Vergleich wird pro Datei in diesem vorbereitenden Durchlauf durchgeführt; wenn also nach der exakten Umbenennungserkennung mehrere verbleibende ext.txt-Dateien in der Verzeichnishierarchie vorhanden sind, kann dieser vorbereitende Schritt für diese Dateien übersprungen werden.

Hinweis. Wenn die Option "-C" zusammen mit der Option --find-copies-harder verwendet wird, übergibt die Befehle git diff-* auch unveränderte Dateipaare an den Diffcore-Mechanismus, nicht nur veränderte. Dies ermöglicht es dem Kopierdetektor, unveränderte Dateien als Kopierquellenkandidaten zu berücksichtigen, allerdings auf Kosten einer Verlangsamung. Ohne --find-copies-harder können die Befehle git diff-* Kopien nur dann erkennen, wenn die kopierte Datei im selben Changeset modifiziert wurde.

diffcore-merge-broken: Zum Wiederzusammenfügen vollständiger Neufassungen

Diese Transformation wird verwendet, um von diffcore-break gebrochene und von diffcore-rename nicht in umbenannte/kopierte transformierte Dateipaare wieder zu einer einzigen Änderung zusammenzuführen. Dies läuft immer, wenn diffcore-break verwendet wird.

Zum Wiederzusammenfügen von gebrochenen Dateipaaren verwendet sie eine andere "Umfang der Änderungen"-Berechnung als die von diffcore-break und diffcore-rename verwendeten. Sie zählt nur die Löschung aus dem Original und zählt keine Einfügung. Wenn Sie nur 10 Zeilen aus einem 100-Zeilen-Dokument entfernt haben, auch wenn Sie 910 neue Zeilen hinzugefügt haben, um ein neues 1000-Zeilen-Dokument zu erstellen, haben Sie keine vollständige Neufassung vorgenommen. diffcore-break zerlegt einen solchen Fall, um diffcore-rename zu helfen, solche Dateipaare als Kandidaten für die Umbenennungs-/Kopiererkennung zu betrachten, aber wenn auf diese Weise gebrochene Dateipaare nicht mit anderen Dateipaaren abgeglichen wurden, um Umbenennungen/Kopien zu erstellen, dann führt diese Transformation sie wieder zur ursprünglichen "Änderung" zusammen.

Der Parameter "Umfang der Änderungen" kann vom Standardwert 80% abweichen (d. h., wenn nicht mehr als 80% des Originalmaterials gelöscht werden, werden die gebrochenen Paare wieder zu einer einzigen Änderung zusammengeführt), indem eine zweite Zahl zur Option -B angegeben wird, wie diese:

  • -B50/60 (gibt 50% "Break-Score" für diffcore-break, verwendet 60% für diffcore-merge-broken).

  • -B/60 (dasselbe wie oben, da diffcore-break standardmäßig 50% hat).

Beachten Sie, dass frühere Implementierungen ein gebrochenes Paar als separate Erstellungs- und Löschungspatches hinterließen. Dies war ein unnötiger Hack, und die neueste Implementierung fügt alle gebrochenen Paare immer wieder zu Änderungen zusammen, aber die resultierende Patch-Ausgabe wird anders formatiert, um die Überprüfung im Falle einer solchen vollständigen Neufassung zu erleichtern, indem der gesamte Inhalt der alten Version, der mit - vorangestellt ist, gefolgt vom gesamten Inhalt der neuen Version, der mit + vorangestellt ist, angezeigt wird.

diffcore-pickaxe: Zum Erkennen von Hinzufügen/Löschen eines bestimmten Strings

Diese Transformation beschränkt den Satz von Dateipaaren auf diejenigen, die bestimmte Strings zwischen dem Vorher- und Nachbild auf eine bestimmte Weise ändern. Die Optionen -S<Textblock> und -G<regulärer Ausdruck> werden verwendet, um verschiedene Arten zu spezifizieren, wie diese Strings gesucht werden.

"-S<Textblock>" erkennt Dateipaare, deren Vorher- und Nachbild eine unterschiedliche Anzahl von Vorkommen des angegebenen Textblocks haben. Per Definition werden keine In-File-Verschiebungen erkannt. Auch wenn ein Changeset eine Datei im Ganzen verschiebt, ohne den interessanten String zu beeinträchtigen, greift diffcore-rename wie gewohnt, und -S lässt das Dateipaar weg (da die Anzahl der Vorkommen dieses Strings in diesem umbenannten Dateipaar nicht geändert wurde). Wenn sie mit --pickaxe-regex verwendet wird, wird der <Textblock> als erweiterter POSIX-Regulärer Ausdruck behandelt, anstatt als literaler String.

"-G<regulärer Ausdruck>" (Merkwort: grep) erkennt Dateipaare, deren textueller Diff eine hinzugefügte oder gelöschte Zeile hat, die dem gegebenen regulären Ausdruck entspricht. Das bedeutet, dass In-File-Verschiebungen (oder was die Umbenennungserkennung als dieselbe Datei betrachtet) erkannt werden, was Rauschen verursacht. Die Implementierung führt den Diff zweimal aus und grept, was sehr aufwendig sein kann. Um die Dinge zu beschleunigen, werden Binärdateien ohne Textconv-Filter ignoriert.

Wenn -S oder -G ohne --pickaxe-all verwendet werden, werden nur Dateipaare, die ihren jeweiligen Kriterien entsprechen, in der Ausgabe beibehalten. Wenn --pickaxe-all verwendet wird, wird der gesamte Changeset beibehalten, wenn auch nur ein Dateipaar seinen Kriterien entspricht. Dieses Verhalten soll die Überprüfung von Änderungen im Kontext des gesamten Changesets erleichtern.

diffcore-order: Zum Sortieren der Ausgabe nach Dateinamen

Dies wird verwendet, um die Dateipaare nach dem Geschmack des Benutzers (oder Projekts) neu anzuordnen, und wird durch die Option -O der git diff-* Befehle gesteuert.

Dies nimmt eine Textdatei, von der jede Zeile ein Shell-Glob-Muster ist. Dateipaare, die mit einem Glob-Muster in einer früheren Zeile der Datei übereinstimmen, werden vor denen ausgegeben, die mit einer späteren Zeile übereinstimmen, und Dateipaare, die mit keinem Glob-Muster übereinstimmen, werden zuletzt ausgegeben.

Als Beispiel würde eine typische Orderfile für den Kern von Git wahrscheinlich so aussehen:

README
Makefile
Documentation
*.h
*.c
t

diffcore-rotate: Zum Ändern des Startpfades der Ausgabe

Diese Transformation nimmt einen Pfadnamen und dreht den Satz von Dateipaaren so, dass das Dateipaar für den angegebenen Pfadnamen zuerst kommt, optional werden die Pfade verworfen, die davor kommen. Dies wird verwendet, um die Optionen --skip-to und --rotate-to zu implementieren. Es ist ein Fehler, wenn der angegebene Pfadname nicht im Satz von Dateipaaren vorhanden ist, aber es ist nicht sinnvoll, einen Fehler auszugeben, wenn er mit der "git log" Familie von Befehlen verwendet wird, da es unzumutbar ist, zu erwarten, dass ein gegebener Pfad bei jedem einzelnen Commit, der vom "git log" Befehl angezeigt wird, modifiziert wird. Aus diesem Grund, wenn mit "git log" verwendet, beginnt die Ausgabe bei dem Dateipaar, das dasselbe sortiert wie der angegebene Pfadname oder das erste, das danach sortiert.

Die Verwendung dieser Transformation in Kombination mit diffcore-order führt zu unerwarteten Ergebnissen, da die Eingabe für diese Transformation wahrscheinlich nicht sortiert ist, wenn diffcore-order in Kraft ist.

GIT

Teil der git[1] Suite