Binäre Dateien mit Mercurial behandeln

posted by Ryan Wilcox on November 30, 2009

Als Beispiel dient uns eine Webseite, bei der wir die Bilder im Mercurial Repository ablegen wollen. Irgendwann werden 2 Personen das gleiche Bild gleichzeitig bearbeiten und stehen vor einem Merge-Konflikt.

Ein anderes Merge Tool für Mercurial auswählen

In ihrer ~/.hgrc Datei sollten Sie die folgenden Zeilen einfügen:

[merge-tools]
diff_images.args = $output $other

[merge-patterns]
**.png = diff_images

Nun erzeugen Sie das diff_images Shell Script, machen es ausführbar und fügen es zu ihrem $PATH hinzu. Meines sieht so aus:

open -a GraphicConverter $1 $2 -W 
# opens the first and second parameter with GraphicConverter, waiting
# until same is quit before letting the shell continue.

Bei jedem Merge-Konflikt wo eine Datei mit der Endung .png betroffen ist wird nun GraphicConverter gestartet. Es werden 2 Bilder geöffnet: eines ist das derzeit in ihrem Arbeitsverzeichnis liegt und das von Mercurial. Sie können den Unterschied daran erkennen, da dasjenige von Mercurial als am Ende des Namens eine zufällig aussehende Aneinanderreihung von Buchstaben hat. Als Beispiel für einen Konflikt mit der Datei image.png wird GraphicConverter zwei Fenster öffnen: image.png und image.png~other.bQkQxd.

Sie müssen nun von Hand die Änderungen von der neuen Datei ins Original (image.png) übertragen. Speichern Sie die Datei und schliessen Sie GraphicConverter. Dies sind die Änderungen die Sie commiten müssen.

Wie dies funktioniert

Als erstes übergibt diff_images.args zwei Parameter ans Grafikprogramm:

Es gibt weitere Optionen die der .args Parameter bereitstellt:

Sie können dies für einen “Tree Way Merge” benutzen. Wenn gewünscht können Sie diff_images so abändern, dass es dem Benutzer den Inhalt der Datei zeigt bevor der Merge-Konflikt auftritt.

Als nächstes schauen wir uns den Abschnitt [merge-patterns] an der sich um das Verknüpfen von Dateiendung und Merge-Tool kümmert.

Ohne den merge-pattern Abschnitt würde diff_images als Kandidat für Diffs gelten, von Mercurial allerdings wegen vermeintlich fehlender Möglichkeit für binäre Dateien ignoriert. Erst das Hinzufügen der entsprechenden Zeile zu [merge-pattern] macht Mercurial klar, das diff_images binäre Dateien mit der entsprechenden Dateiendung behandeln kann.

Anstelle des merge-patterns Abschnittes können sie auch eine Zeile analog diff_images.args angeben, die Mercurial auf die Möglichkeit der Bearbeitung binäre Dateien hinweist: diff_images.binary = True

Allerdings führ dies dazu, das diff_images als Kandidat für alle binären Dateien gilt. (GraphicConverter kann aber nur mit Bildern umgehen. Ein Vergleich für mp3 Dateien wäre daher nutzlos.)

Wenn alles schief läuft: einen Merge abbrechen

Ein Merge kann nicht durch ein hg revert abgebrochen werden. Wenn Sie dies versuchen, werden Sie diese Fehlermeldung bekommen:

$ hg revert --all
abort: uncommitted merge - please provide a specific revision

Um nur ihre Arbeit am Merge zu verwerfen, können Sie hg update --clean verwenden.

Referenzen

Meistens behandeln wir Texte, Source Code oder sonstige Textdateien. Aber gelegentlich werden auch binäre Dateien in einem Repository abgelegt. Unausweichlich wird irgendwann ein Merge durchgeführt werden müssen, der nicht so einfach ist wie für Source Code.