Git Merge: parallele identische Zusätze werden ohne Konflikt zusammengeführt, indem der gleiche Codeblock TWICE in die zusammengeführte Datei ohne Beanstandung eingefügt wird. Warum?

9

Ich habe eine etwas schwierige Geschichte in meinem Git Log, die ich versuche, vollständig zu verstehen.

Bevor ich die Reihenfolge der Commits erkläre, lassen Sie mich Bilder des Git-Logs (mit SmartGit zur Visualisierung des Verlaufs) für eine fragliche Datei einfügen:

...

Gezeigt ist die für meine Frage relevante Git-Geschichte, wobei der irrelevante mittlere Abschnitt weggeschnitten wurde.

Zwei Entwickler haben Codeänderungen an der betreffenden Datei, Entwickler 1 und Entwickler 2, vorgenommen.

Entwickler 1

  • checkt den Zweig mit der Bezeichnung Herkunft / Staging im Bild aus (der aber zum Zeitpunkt des Auscheckens auch ' Herkunft / Entwicklung war)
  • fügt einen kleinen Codeblock hinzu (siehe unten)
  • commits und pushes - Dieser Push ist mit jon-dev-test-merge 'oben
  • gekennzeichnet
  • ändert den Code aus dem vorherigen Commit um eine einfache Whitespace-Änderung und schreibt / schiebt diese Whitespace-Änderung mit der Bezeichnung jon-dev-test-merge-2 über
  • erkennt, dass er an einem separaten Zweig gearbeitet haben sollte , sodass von aus neu gestartet wird und origing / staging (zu diesem Zeitpunkt << em> Ursprung / Entwicklung '), in einen neuen Zweig mit dem Namen jons_dev , an den er schiebt und für den er
  • eingerichtet hat
  • fügt dem neuen Zweig (blaue Linie) den gleichen kleinen Codeblock hinzu (KEINE Whitespace-Änderung) (in einen Commit vor dem mit ' test-merge-sales ' bezeichneten)
  • später, da Developer 2 eine Änderung am Zweig Herkunft / Entwicklung vorgenommen hat, führt Ursprung / Entwicklung in seine jons_dev 'Zweigstelle

Inzwischen ...

Entwickler 2

  • checkt den Zweig mit der Bezeichnung Herkunft / Staging im Bild aus (der aber zum Zeitpunkt des Auscheckens auch ' Herkunft / Entwicklung war)
  • macht eine Codeänderung in eine andere Datei (die völlig unabhängig von der Codeänderung von Entwickler 1 ist, oben) - das ist in seiner Arbeitskopie auf seiner lokalen Entwicklungsmaschine
  • zieht die Codeänderungen von Developer 1 in den Zweig Ursprung / Entwicklung auf seinen lokalen Computer und wird in eine lokale Zweigstelle / Arbeitskopie zusammengeführt; Die Zusammenführung ist ohne Konflikt erfolgreich. Beachten Sie, dass Entwickler 2 nicht in seinen lokalen Zweig eingebunden wird (weil er diesen Zweig nicht zum Ursprung verschoben hat), sondern nur die Zusammenführung (siehe nächsten Aufzählungspunkt) von seinem lokalen Zweig zurück in das, was das ' war Ursprung / Entwicklung 'zu dieser Zeit.
  • fügt sich vom Ursprung seiner lokalen Maschine in den verfolgten Entwicklungszweig ein und schiebt die Zusammenführung zurück in den Ursprungsbuchstaben vladimir-test-merge 'über

So weit, so gut.

Hier ist meine Frage.

Beim Verstehen der obigen Abfolge ist mir etwas Seltsames aufgefallen - keine Änderungen vom Ursprung / Entwicklung Zweig für die fragliche Datei in die Zusammenführung mit der Bezeichnung Herkunft / Entwicklung aufgenommen werden - deren Erklärung sich herausstellte, dass in dieser Datei die identischen Änderungen an dieser Datei parallel vorgenommen wurden, die keine Whitespaces enthielten in beiden Dateien vorhanden , so dass nur die Änderungen aus dem Zweig jons_dev erforderlich waren (und so wurde die Zusammenführung durchgeführt).

Allerdings habe ich etwas aus der Zusammenführung bemerkt, das Git 'Methode zum Verschmelzen und Bestimmen von Konflikten beinhaltet, die ich nicht erklären kann.

Um das Problem auf die einfachste Art und Weise für meine Frage zu demonstrieren, habe ich zuerst die in den Screenshots angegebenen Testzweige erstellt - ' test-merge-sales ' und ' jon-dev- test-merge '/' jon-dev-test-merge-2 '. Ich habe dann den Zweig ' test-merge-sales ' ausgecheckt und zwei separate Zusammenführungen in diesem Zweig durchgeführt (die Zusammenführung zwischen den beiden Tests wurde aufgehoben).

Die relevanten Ergebnisse aus diesen beiden Zusammenführungen sind nachstehend aufgeführt. (Nachtrag: Aufgrund von Kommentaren unter der Frage ist das zweite Zusammenführungsszenario leicht zu erklären. Das FIRST Zusammenführungsszenario ist jedoch immer noch eine Frage.)

(0) BASE-Datei

Bevor Sie einen 3-Wege-Screenshot aus den beiden Zusammenführungen zeigen, ist hier ein Screenshot des relevanten Abschnitts der Datei , wie er im Zweig Herkunft / Staging vor den Zweigen vorhanden war divergierte :

Die Basisdatei:

Das Bild zeigt, wie die Datei nach BEIDE Entwicklern gesucht hat, BEVOR irgendwelche Änderungen von beiden Entwicklern vorgenommen wurden.

Es sind auch Kommentare vorhanden, die genau erklären, welche Codeänderungen von jedem Entwickler vorgenommen wurden, um zu dem in Fall (1) unten gezeigten Zustand vor dem Zusammenführen zu gelangen.

Wie Sie den Kommentaren entnehmen können, fügt Entwickler 1 eine Funktion - print_customer_part_order_history , gefolgt von einer zweiten Funktion, print_sales_analysis_page , zu einer bestimmten Stelle in der Datei hinzu. Parallel dazu hat der andere Zweig eine einzige Funktion - print_customer_part_order_history - an genau derselben Stelle in der Datei hinzugefügt. Der Code ist identisch, einschließlich Leerzeichen.

Dies ist der Status der Datei, die in den Merge-Fall (1) weitergeht.

(1) Zusammenführung von ' jon-dev-test-merge ' in den Zweig ' test-merge-sales '

Hinweis: Dieses Zusammenführungsszenario ist meine Hauptfrage. Aufgrund von Kommentaren unter der Frage ist die Frage zu dem anderen Zusammenführungsszenario (# 2, unten) bereits beantwortet.

Diese Zusammenführung führte nicht zu einem Konflikt . Öffnen Sie einen Diff-Viewer für die zusammengeführte Datei, hier ist ein Screenshot aus den relevanten (zusammengeführten) Zeilen:

(Klicken Sie auf Link zum Bild in voller Größe )

Beachten Sie, dass Git die Dateien zusammengeführt hat, indem BEIDE identische Funktionen (parallel hinzugefügt) 'print_customer_part_order_history ()' - ohne Zusammenführungskonflikt hinzugefügt wurden. (Dies ist das Codefragment, das Developer 1 parallel zu den beiden Zweigen hinzugefügt hat.) Daher wird diese Funktion im zusammengeführten Code zweimal angezeigt.

Hinweis: Der Zweig ' test-merge-sales ' hat die gleichen Leerräume - führende Leerzeichen - im hervorgehobenen Codeblock in beiden Zweigen.

Frage 1: Warum hat Git entschieden, dass es keinen Mergekonflikt gab? Zwei Codeblöcke wurden parallel am selben Ort in der Datei hinzugefügt. Obwohl die Code-Blöcke identisch sind, würde ich denken, dass dies ein Merge-Konflikt sein sollte.

(2) Zusammenführen von ' jon-dev-test-merge-2 ' in den Zweig ' test-merge-sales '

Hinweis: Aufgrund von Kommentaren unterhalb dieser Frage ist die mit diesem Zusammenführungsszenario verbundene Frage bereits beantwortet.

(Klicken Sie auf Link zum Bild in voller Größe )

Der einzige Unterschied in dem Code, der zusammengeführt wird, ist, dass Entwickler 1 führende Leerzeichen in Registerkarten geändert hat. In diesem Fall hat Git jedoch nur den Leerraumunterschied festgestellt, und es wurde ein Zusammenführungskonflikt festgestellt .

Frage 2: Warum - mit nur einem Unterschied in Leerzeichen - würde Git entscheiden, dass es in einem Fall keinen Merge-Konflikt gibt, und in dem anderen Fall, dass ein Merge-Konflikt ist? / p>

Meine beiden Fragen sind oben aufgeführt, in Bezug darauf, wie Git Konflikte zusammenführt und zusammenführt.

Danke!

ANHANG Ich habe einen zusätzlichen Screenshot hinzugefügt - der relevante Text der Datei BEFORE die zwei Zweige divergierten - zusammen mit beschreibendem Text, im Abschnitt " (0) Base File ". Danke!

    
Dan Nissenbaum 26.02.2014, 22:08
quelle

1 Antwort

4

Es ist ziemlich einfach: Wenn du merge machst, analysiere git die Zeilen, die sich in beiden Größen geändert haben:

  • Wenn die Änderungen weniger als 2 Zeilen auseinander liegen (Referenz folgt in Kürze) wird dies zu einem Konflikt führen, da die Änderungen sehr wahrscheinlich über die gleiche Sache sind;
  • Wenn die Änderungen mehr als 2 Zeilen voneinander entfernt sind, wird der Inhalt von beiden Seiten als zwei verschiedene Dinge betrachtet und der hinzugefügte Inhalt wird nicht analysiert , nur zur resultierenden Datei hinzugefügt.

Da LHS die Funktion für line 79 hinzugefügt hat und RHS es hinzugefügt hat, hat line 69 git gedacht, dass es sich um einen anderen Inhalt handelt, da er mehr als nur ein paar Zeilen auseinander liegt.

Wie vermeide ich das in Zukunft?

  • Gehen Sie zu einem diff zwischen den beiden Zweigen über, dies wird sichtbar, wenn Sie Ihre Diff sorgfältig lesen und dann in der Zusammenführung bearbeiten;
  • Kommunizieren Sie mehr innerhalb Ihres Teams (wenn möglich), ist das normal, dass zwei Entwickler die Funktion exakt gleich in zwei getrennten Zweigen geschrieben haben?

Von git merge doc (Schwerpunkt ist mein)

  

WIE KONFLIKTE VORGESEHEN WERDEN

     

Während einer Zusammenführung werden die Arbeitsbaumdateien aktualisiert, um die   Ergebnis der Zusammenführung. Unter den Änderungen, die zum gemeinsamen Vorfahren gemacht sind   Version, nicht überlappende Version (das heißt, Sie haben einen Bereich der   Datei, während die andere Seite diesen Bereich intakt gelassen hat, oder umgekehrt)   in das endgültige Ergebnis wörtlich übernommen . Wenn beide Seiten gemacht haben   ändert sich jedoch in den gleichen Bereich, kann Git nicht zufällig eine Seite auswählen   über den anderen und bittet dich, es zu lösen, indem du beide Seiten verlässt   habe zu diesem Bereich gemacht.

    
Thomas Ayoub 18.03.2016, 14:40
quelle

Tags und Links