it-swarm.com.de

Git - wie man Zusammenführungskonflikte und manuelle Zusammenführung der ausgewählten Datei erzwingt

Wir pflegen eine Webanwendung, die einen gemeinsamen Hauptzweig und viele parallele Zweige hat, einen für jede Installation, und jeder hat einige spezifische Änderungen. Der Quellcode wird in git verwaltet und ist ein hervorragendes Werkzeug, wenn wir Features und Bugfixes vom Hauptzweig in parallele übertragen müssen. Es gibt jedoch nur wenige Dateien, die empfindlich sind und das automatische Zusammenführen normalerweise zu schlechten Ergebnissen führt. Das Zusammenführen wäre also viel einfacher, wenn sie irgendwie markiert werden können und jedes Zusammenführen zu Konflikten führen würde, die ein manuelles Zusammenführen erfordern.

Ich habe nach einer Antwort gesucht:

  1. Ich verwende --no-commit und --no-ff Zusammenführungsoptionen, aber es ist nicht dasselbe.
  2. Hier und Hier jemand stellt dieselbe Frage, aber ohne Lösung.
  3. Ein ähnlicher Fall scheint zu sein: So verhindern Sie das Zusammenführen von Dateien Verwenden Sie .gitattributes, die Folgendes enthalten: somefile.php merge = ours. Ich habe versucht, eine Zusammenführungsoption zu finden, die Konflikte erzeugen oder eine manuelle Zusammenführung erzwingen kann, aber bisher keine gefunden.
  4. .gitattributes, die Folgendes enthalten: somefile.php -merge wird niemals automatisch zusammengeführt und erzwingt daher eine manuelle Zusammenführung. Es ist eine 90% ige Lösung, aber ich versuche, die automatische Zusammenführung zu versuchen und sie als Konflikt zu markieren, unabhängig davon, ob sie erfolgreich ist oder nicht. Dies ist jedoch der Lösung am nächsten.(... danke Charles Bailey für die Klarstellung ...)
  5. Jemand schlägt vor, einen benutzerdefinierten Merge-Treiber zu schreiben ( 1 , 2 ), aber wie es geht, ist mir bei weitem nicht klar. 

edit: variante 4. beschreibung

75
Stepan

Option 5, ein benutzerdefinierter Zusammenführungstreiber, ist wahrscheinlich der Weg, dem zu kommen, was Sie möchten. Das ist überraschend einfach. Im Folgenden finden Sie ein Beispiel, von dem ich denke, dass es Sie dem gewünschten Verhalten ziemlich nahe bringen sollte.

Erstellen Sie zunächst ein Zusammenführungstreiberskript mit dem Namen merge-and-verify-driver. Machen Sie es ausführbar und legen Sie es an einem geeigneten Ort ab (Sie können dieses Skript auch in das Repo einchecken, da die Konfigurationsdatei des Repos davon abhängt). Git führt dieses Shell-Skript aus, um die Zusammenführung der vertraulichen Dateien durchzuführen:

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

Dadurch wird nur das standardmäßige Zusammenführungsverhalten ausgeführt, das Git normalerweise selbst ausführt. Der Hauptunterschied besteht darin, dass das Skript immer ungleich Null zurückgibt (um anzuzeigen, dass ein Konflikt aufgetreten ist, auch wenn die Zusammenführung tatsächlich ohne Konflikte gelöst wurde).

Als Nächstes müssen Sie Git über die Existenz Ihres benutzerdefinierten Merge-Treibers informieren. Sie tun dies in der Konfigurationsdatei des Repos (.git/config):

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

In diesem Beispiel habe ich merge-and-verify-driver in das oberste Verzeichnis des Repos (./) gestellt. Sie müssen den Pfad zum Skript entsprechend angeben.

Jetzt müssen Sie den vertraulichen Dateien nur die richtigen Attribute zuweisen, damit beim Zusammenfügen der Dateien der benutzerdefinierte Merge-Treiber verwendet wird. Fügen Sie dies Ihrer .gitattributes-Datei hinzu:

*.sensitive merge=verify

Hier habe ich Git mitgeteilt, dass jede Datei, deren Name mit dem Muster *.sensitive übereinstimmt, den benutzerdefinierten Merge-Treiber verwenden soll. Natürlich müssen Sie ein Muster verwenden, das für Ihre Datei (en) geeignet ist.

54
Dan Moulding

Hinweis: In diesem Artikel " Schreiben eines Git-Merge-Treibers für PO-Dateien " wird die Art der Manipulation beschrieben, die Sie beim manuellen Zusammenführen einer Datei ausführen können: Sie können sie vorverarbeiten, damit für das manuelle Zusammenführen bestimmte Daten verfügbar sind.

git merge-file kann zum Beispiel verwendet werden, um DECRYPT (und erneut zu verschlüsseln) Dateien vor dem Zusammenführen von (!)

Wenn Sie Ihren Merge-Treiber mit einem Nicht-0-Status beenden, stellen Sie in diesem Fall sicher, dass die Zusammenführung manuell ist.

1
VonC

Diese beiden Befehle scheinen den gleichen Effekt zu haben wie die Verwendung des benutzerdefinierten Zusammenführungstreibers: 

git merge --no-commit your_target_branch
git checkout --conflict merge .   (do not forget the . and run it in the top dir of the repository)

Mit dem ersten Befehl wird die Zusammenführung vor der Erstellung des Zusammenführungs-Commits angehalten, und mit dem zweiten Befehl werden alle in den beiden Zweigen geänderten Dateien als zu lösende Konflikte markiert, auch wenn ursprünglich kein Konflikt aufgetreten ist.

0
louisiuol