Gibt es eine Möglichkeit, zwei Diffs oder Patches zu vergleichen?
Lesezeit: 2 Minuten
Markus Canlas
Gibt es eine Möglichkeit zu testen, ob zwei Diffs oder Patches gleichwertig sind?
Nehmen wir an, Sie haben den folgenden Git-Commit-Verlauf, in dem die Features F und G sauber auf E rebasierbar sind:
G
/
A--B--C--D--E
F
Wegen Einschränkungen in unserem aktuellen Bereitstellungsprozesshaben wir das folgende, etwas verwandte Diagramm (es ist nicht versioniert)
G'
/
------------E'
F'
F’ und G’ werden schließlich in einer noch zu bestimmenden Reihenfolge auf den Kopf E’ angewendet, so dass es enden würde
------------E'--G'--F'
Gibt es eine Möglichkeit zu testen, ob der Unterschied von E’ zu G’ derselbe ist wie der Patch, der durch das Git-Commit von G von B erzeugt wird?
Mir ist völlig klar, dass in einer idealen Welt die Revisionskontrolle dieses Problem lösen würde, und wir kommen dorthin, aber dort sind wir derzeit nicht.
Sie könnten im Wesentlichen beide Patches an separaten Kassen spielen und die Ausgaben vergleichen, aber das scheint etwas klobig zu sein. Und ich gehe davon aus, dass das Vergleichen der Unterschiede selbst nicht funktionieren würde, da sich die Zeilennummern ändern könnten. Selbst wenn G’ und F’ auf E’ umbasiert würden, würde der Patch für F’ letztendlich auf G’ angewendet, wodurch der Diff-Kontext des Patches anders würde.
Hast du ein Diff an den Diffs probiert?
– Geoffroy
20. Dezember 11 um 1:35 Uhr
Gnu diff hat einen Befehlszeilenschalter zum Angeben von Regex für Zeilen, die beim Generieren des Diffs ignoriert werden sollen.
– Heiliggeist
20. Dezember 11 um 1:37 Uhr
Für Chargen, git patch-id und git cherry (siehe auch --cherry* options for git log) könnte als schnelle Antwort verwendet werden, aber es ist zu streng und kann einige geringfügige Änderungen als wichtig betrachten. Diff of Diffs ist der richtige Weg, wenn Sie eine bestimmte Antwort benötigen
– max630
11. August 16 um 9:18 Uhr
diff <(git show COMMIT1SHA) <(git show COMMIT2SHA)
Können Sie etwas Kontext hinzufügen, wie dies die Frage beantwortet?
– Weihnachten007
23. Januar 15 um 19:48 Uhr
Es vergleicht (diffs) zwei Diffs (in diesem Fall die Diffs von zwei verschiedenen Commits).
– Mrbrdo
20. Februar 15 um 20:21 Uhr
Es unterscheidet die tatsächlichen Änderungen, die die Commits vorgenommen haben, sowie die Metadaten der Commits (sha, Autor, Datum, Commit-Nachricht usw.). Ich habe dies verwendet, um zu prüfen, ob zwei Commits in verschiedenen Zweigen dieselbe Änderung einführen, um sicherzugehen, dass ich einen von ihnen für eine Rosinenpickerei verwenden kann.
– Amedée Van Gasse
3. Juli 15 um 7:15 Uhr
Für alle, die sich fragen, was das ist <(...) Marken sind, das Google-Schlüsselwort ist Substitution verarbeiten. Sehen tldp.org/LDP/abs/html/process-sub.html
– Linus Arver
7. Juni 16 um 21:59 Uhr
Ich habe diesen Ansatz in der Vergangenheit verwendet und fand ihn ziemlich schwach. Heute wurde ich jedoch dazu inspiriert, die Option –ignore-matching-lines hinzuzufügen, um nutzlose Hunks zu überspringen, bei denen der Diff nur Unterschiede in den Zeilennummern anzeigt (was eine unvermeidliche Ablenkung beim Vergleich mit ansonsten sehr ähnlichen Commits darstellt. Versuchen Sie also eine Variante wie dies: % diff -U3 –ignore-matching-lines=”^@@ ” <(git show b7f9f919) <(git show 8ce6b2af)
–Ted
23. April 18 um 13:14 Uhr
Uwe Kleine-König
Seit git 2.19 gibt es dafür ein extra Tool: git range-diff
Sie möchten also wahrscheinlich:
git range-diff E..G E'..G'
Dies sollte sogar für mehr als einen Patch in jedem Bereich funktionieren.
Sollte das sein git range-diff E..G E'..G'?
– mkrieger1
23. Mai 21 um 10:15 Uhr
@mkrieger1 Tatsächlich habe ich nicht bemerkt, dass es eine gibt E'. Mit einem ausreichend aktuellen Git können Sie auch Folgendes tun: git range-diff G^! G'^!, dann spielt die eigentliche Basis keine Rolle. Ich korrigiere meine Antwort. Danke für den Hing
– Uwe Kleine-König
25. Mai 21 um 5:45 Uhr
Was bedeutet hier einfache Anführungszeichen E'..G' ? :Denken:
– Lajos
1. September 21 um 15:07 Uhr
@Lajos Das gleiche wie in der ursprünglichen Frage: E' ist eine Variante von E (z. B. umbasiert). Es ist also nur ein Name für eine Revision, die Sie anpassen müssen, wenn Sie an einem tatsächlichen Projektarchiv arbeiten.
– Uwe Kleine-König
28. September 21 um 10:23 Uhr
Tino
Für den Leser ist hier ein Update der Antwort von @mrbrdo mit einer kleinen Änderung:
Fügt hinzu git sdiff Alias für den einfachen Zugriff darauf. sdiff steht für show diff.
Ignorieren Sie annotierte Tag-Header mit dem ^{} Suffix.
Erlauben diff Optionen wie verwendet werden -u etc.
Führen Sie dies einmal in jedem Ihrer Konten aus, die Sie verwenden git:
git config --global alias.sdiff '!'"bash -c 'O=(); A=(); while x="$1"; shift; do case $x in -*) O+=("$x");; *) A+=("$x^{}");; esac; done; g(){ git show "${A[$1]}" && return; echo FAIL ${A[$1]}; git show "${A[$2]}"; }; diff "${O[@]}" <(g 0 1) <(g 1 0)' --"
Danach können Sie dies verwenden:
git sdiff F G
Bitte beachten Sie, dass dies erforderlich ist bash Version 3 oder höher.
Erklärt:
git config --global alias.sdiff fügt einen Alias namens hinzu git sdiff ins Globale ~/.gitconfig.
! führt den Alias als Shell-Befehl aus
bash -c wir brauchen bash (oder ksh), wie <(..) funktioniert nicht drin dash (aka. /bin/sh).
O=(); A=(); while x="$1"; shift; do case $x in -*) O+=("$x");; *) A+=("$x^{}");; esac; done; trennt Optionen (-something) und Argumente (alles andere). Optionen sind im Array O während Argumente im Array sind A. Beachten Sie, dass alle Argumente erhalten werden ^{} angehängt, wodurch Anmerkungen übersprungen werden (so dass Sie annotierte Tags verwenden können).
g(){ git show "${A[$1]}" && return; echo FAIL ${A[$1]}; git show "${A[$2]}"; }; erstellt eine Hilfsfunktion, die funktioniert git show für das erste argument. Wenn dies fehlschlägt, gibt es “FAIL first-argument” aus und gibt dann das zweite Argument aus. Dies ist ein Trick, um den Aufwand zu reduzieren, falls etwas fehlschlägt. (Ein ordentliches Fehlermanagement wäre zu viel.)
diff "${O[@]}" <(g 0 1) <(g 1 0) läuft diff mit den gegebenen Optionen gegen das erste Argument und das zweite Argument (bei besagtem FAIL-Error Fallback auf das andere Argument um die diff).
-- passieren lässt diff-Optionen (-something) zu diesem Alias/Skript.
Fehler:
Anzahl der Argumente wird nicht geprüft. Alles hinter dem 2. Argument wird ignoriert, und wenn Sie zu wenig davon geben, sehen Sie einfach FAIL oder gar nichts.
Fehler verhalten sich etwas seltsam und verunreinigen die Ausgabe. Wenn Ihnen das nicht gefällt, führen Sie es mit aus 2>/dev/null (oder das Skript entsprechend ändern).
Es gibt keinen Fehler zurück, wenn etwas kaputt geht.
Sie möchten dies wahrscheinlich standardmäßig in einen Pager einspeisen.
Bitte beachten Sie, dass es einfach ist, weitere Aliase zu definieren, wie zum Beispiel:
Hast du ein Diff an den Diffs probiert?
– Geoffroy
20. Dezember 11 um 1:35 Uhr
Gnu diff hat einen Befehlszeilenschalter zum Angeben von Regex für Zeilen, die beim Generieren des Diffs ignoriert werden sollen.
– Heiliggeist
20. Dezember 11 um 1:37 Uhr
Für Chargen,
git patch-id
undgit cherry
(siehe auch--cherry*
options for git log) könnte als schnelle Antwort verwendet werden, aber es ist zu streng und kann einige geringfügige Änderungen als wichtig betrachten. Diff of Diffs ist der richtige Weg, wenn Sie eine bestimmte Antwort benötigen– max630
11. August 16 um 9:18 Uhr