LW IT Solutions
« Blog Overview /Web Entwicklung / Zwei GTM-Container-Exporte vergleichen: Normalisieren vor dem Diff...
This post in other languages:

Zwei GTM-Container-Exporte vergleichen: Normalisieren vor dem Diff und was ein Zeilenvergleich nicht zeigt

Zwei GTM-Container-Exporte vergleichen: Normalisieren vor dem Diff und was ein Zeilenvergleich nicht zeigt
Inhalt
  1. Wovon der Abstand gefüllt ist
  2. Erst normalisieren, dann vergleichen
  3. Drei Ebenen, drei verschiedene Antworten
  4. Was keine Ebene zeigt
  5. Was stattdessen zu vergleichen ist, wenn es auf die Antwort ankommt
  6. Quellen

Zwei Ausgaben derselben Konfiguration zu vergleichen ist der schnellste Weg herauszufinden, was jemand geändert hat, und der erste Versuch liefert fast immer ein unbrauchbares Ergebnis. Es sind mehrere hundert abweichende Zeilen, von denen eine zählt und der Rest das Dateiformat mit sich selbst reden lässt.

Alles Folgende handelt vom Abstand zwischen diesen beiden Zahlen – wovon er gefüllt ist, wie er verschwindet und was auch danach unsichtbar bleibt.

Dieselbe Änderung an einem Wort, gezeigt auf Zeilen-, Wort- und Zeichenebene, dazu ein viertes Zeilenpaar, das sich nur in der Schlüsselreihenfolge unterscheidet und dasselbe Objekt ist
Drei Ebenen für eine Änderung und ein viertes Paar, das ein Zeilenvergleich verschieden nennt und ein Parser gleich.

Wovon der Abstand gefüllt ist

Ausgaben werden erzeugt, und Erzeuger sind zu nichts verpflichtet. Dieselbe Konfiguration, zweimal ausgegeben, kann sich in der Reihenfolge der Objektschlüssel unterscheiden, in Kennungen, die beim Ausgeben vergeben werden, in einem Fingerabdruck, der ein Zeitstempel ist, und darin, ob die Datei mit einem Zeilenumbruch endet. Nichts davon ist eine Änderung; alles davon ist ein Unterschied.

Quelle des Rauschens Wie es aussieht Wie es verschwindet
Schlüsselreihenfolge ganze Blöcke gelten als geändert jq -S . sortiert die Schlüssel rekursiv
Fingerabdrücke, Zeitstempel eine geänderte Zeile je Objekt die Felder vor dem Vergleich löschen
Beim Ausgeben vergebene Kennungen jeder Verweis weicht ab ebenso – oder über Namen vergleichen
Einrückung alles weicht ab jq formatiert beide Seiten gleich
Zeilenenden jede Zeile weicht ab und sieht gleich aus dos2unix oder die Option des Vergleichswerkzeugs
Minimierung eine Zeile weicht ab und sagt nichts neu formatieren, dann vergleichen

Die Zeile mit den Zeilenenden kostet eine Stunde, weil die beiden Zeilen auf dem Bildschirm genau gleich aussehen. Eine Datei, die durch einen Windows-Editor gegangen ist, unterscheidet sich von ihrem Ursprung in jeder einzelnen Zeile, und jeder dieser Unterschiede ist unsichtbar.

Erst normalisieren, dann vergleichen

Die Abhilfe ist eine Verarbeitungskette und kein besseres Vergleichswerkzeug. Beide Dateien laufen durch dieselbe Normalisierung, die flüchtigen Felder werden entfernt, und erst danach werden die Ergebnisse verglichen – dann enthält der Vergleich, was sich geändert hat, und sonst nichts.

norm() {
  jq -S 'walk(if type == "object"
              then del(.fingerprint, .accountId, .containerVersionId)
              else . end)' "$1"
}

diff <(norm alt.json) <(norm neu.json)

walk steigt in jedes Objekt hinab, die Felder verschwinden also überall, wo sie vorkommen, und nicht nur auf der obersten Ebene. -S sortiert die Schlüssel jedes Objekts und beseitigt damit allein die größte Rauschquelle. Was beides übersteht, ist eine Änderung, die jemand gemacht hat.

Drei Ebenen, drei verschiedene Antworten

Zeile, Wort und Zeichen sind keine Güteklassen, sondern verschiedene Fragen. Ein Zeilenvergleich beantwortet, welche Zeilen nicht gleich sind, und das ist die richtige Frage für Quelltext, wo eine Zeile ungefähr eine Anweisung ist. Es ist die falsche Frage für eine JSON-Datei mit einem Objekt je Zeile und vollends unbrauchbar für eine minimierte, in der das ganze Dokument eine einzige Zeile ist.

Die Wortebene vergleicht Bausteine und macht eine Änderung an einem Wert lesbar. Die Zeichenebene ist feiner, als zum Lesen nötig wäre, und genau das Richtige, wenn die Zeile lang ist: In einer minimierten Containerausgabe kann nur ein Zeichenvergleich auf den einen umgekippten Wahrheitswert zeigen.

Was keine Ebene zeigt

Ein Textvergleich sieht Text. Drei Arten von Änderung bleiben deshalb unsichtbar, gleich wie fein die Auflösung wird. Ein verschobener Block erscheint als Löschung an einer und als Ergänzung an anderer Stelle, ohne dass etwas die beiden verbindet. Eine umbenannte Variable, die an zwölf Stellen vorkommt, erscheint als zwölf einzelne Änderungen statt als eine Absicht. Und ein Wert, der den Typ gewechselt hat, ohne das Aussehen zu wechseln – aus "1" wird 1 -, ist ein Unterschied von zwei Zeichen mit Folgen, die keine Hervorhebung vermittelt.

Der umgekehrte Fall steht in der vierten Zeile des Diagramms: zwei Dateien, die sich in jeder Zeile unterscheiden und dasselbe Objekt beschreiben. Ein Vergleich von Text kann immer nur Fragen über Text beantworten – und die Frage, die tatsächlich gestellt wird, ob sich die Konfiguration geändert hat, ist eine Frage über Struktur.

Was stattdessen zu vergleichen ist, wenn es auf die Antwort ankommt

Bei allem, was ein Schema hat, ist der ehrliche Vergleich der zwischen zerlegten Objekten und nicht der zwischen Dateien. jq kann das unmittelbar: Zwei Dokumente sind gleich oder sie sind es nicht, und die Antwort ist ein einzelner Wahrheitswert, den Formatierung, Reihenfolge und Leerraum nicht berühren.

# ist es überhaupt dasselbe Objekt?
jq -e --slurpfile b neu.json '. == $b[0]' alt.json >/dev/null && echo "gleich"

# welche Schlüssel der obersten Ebene weichen ab?
jq -n --slurpfile a alt.json --slurpfile b neu.json \
  '($a[0] | keys) as $ka | ($b[0] | keys) as $kb
   | { nur_alt: ($ka - $kb), nur_neu: ($kb - $ka) }'

Dem Zeilenvergleich bleibt damit die Aufgabe, die er gut kann: einem Menschen zu zeigen, was ein anderer getan hat, in einer Form, die sich liest wie die Datei, die er bearbeiten wird. Er beantwortet sehr gut, worauf zu schauen ist, und überhaupt nicht, ob etwas dasselbe ist – und der meiste Ärger mit ihm kommt daher, dass ihm die zweite Frage gestellt wird.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Kommentar schreiben

Die E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit einem Stern versehen.

ALL ARTICLES & CATEGORIES

CCTV

Diese Rubrik per RSS verfolgen

Cloud & AI

Diese Rubrik per RSS verfolgen

Data Privacy

Alle 12 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Digital Analytics

Alle 47 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Digital Marketing

Alle 26 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

IT & Networks

Alle 16 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Music Production

Diese Rubrik per RSS verfolgen

Raspberry Pi

Diese Rubrik per RSS verfolgen

Smart Home

Alle 17 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Web Entwicklung

Diese Rubrik per RSS verfolgen

WordPress-Plugins & Tricks

Diese Rubrik per RSS verfolgen