Tutorial - Änderungen zusammenführen

GermanTutorialExport hat uns gezeigt, wie man Änderungen untereinander austauschen kann. import kann allerdings seit Mercurial-Version 0.7 nicht mehrere Email-Exports zusammenführen, deswegen gehen wir den Weg über pull, um aus einem anderen Repository eine Änderung einzupflegen, die mit unseren eigenen Änderungen kollidiert.

Zuerst brauchen wir eine Situation, wo es etwas zum zusammenführen gibt. Wir klonen das my-hello Repository ein weiteres Mal:

$ cd ..
$ hg clone my-hello my-hello-desc

Wir ergänzen den C-Code-Kommentar in hello.c:

$ cd my-hello-desc
$ vi hello.c

Und zwar ändern wir Zeile 2 mit dem Inhalt

 * hello.c

in folgende:

 * hello.c - hello, world

Abspeichern, Editor verlassen, und unsere Änderung committen. Diesmal wollen wir etwas Zeit sparen und geben den Kommentar für das commit-Kommando gleich auf der Shell an. Das geht mit der -m-Option, dann bringt uns Mercurial nicht in den Editor.

$ hg commit -m "Add description of hello.c"

Nun haben wir eine Änderung in hello.c im my-hello-new-output Repository, und eine weitere Änderung in hello.c im my-hello-desc Repository (vgl. Branch).

Wie bringen wir die Änderungen in den gleichen Quellcodezeilen wieder zusammen (merge)? Gibt es Probleme, wenn wir ein pull-Kommando benutzen, um wieder Änderungen zwischen Repositories auszutauschen?

Kein Problem, Mercurial wird uns helfen. Wir sind immer noch im Verzeichnis my-hello-desc, und holen die Änderungen aus dem anderen Repository my-hello-new-output, und sehen, was passiert:

$ hg pull ../my-hello-new-output
pulling from ../my-hello-new-output
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

Sieht genauso aus wie die Meldung, die pull in GermanTutorialShareChange anzeigt hat! Also brauchen wir jetzt einfach noch ein update-Kommando, oder?

$ hg update
abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes

Nein, jetzt ist was anders. Mercurial sagt uns, daß wir die Änderungen, die wir in jedem Repository gemacht haben, zusammenführen sollen. Klingt schmerzhafter als es ist! Folgen wir einfach dem Vorschlag, der auf der letzten Zeile ausgegeben wurde:

$ hg merge
merging hello.c
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

(Hinweis für Windows Anwender: Mercurial hat dort kein merge-Programm, wenn eine Fehlermeldung hgmerge is not recognized as an internal or external command. erscheint. MergeProgram beschreibt, wie das gelöst werden kann.)

Das war alles! Mercurial konnte die Änderungen automatisch für uns zusammenführen, und hat dabei das hgmerge script benutzt (oder was wir als merge-Programm eingestellt haben. Abhängig von unserer Arbeitsumgebung ruft hgmerge auch ein GUI-Tool auf.) Wenn wir uns jetzt hello.c anzeigen lassen, sehen wir beide Änderungen aus den Zweigen my-hello-new-output und my-hello-desc.

(Hinweis: Vor der Mercurial-Version 0.9 ist hg update -m statt hg merge zu verwenden).

Wenn wir mit anderen Leuten zusammenarbeiten, die auch Änderungen machen, ist die eben beschriebene Vorgehensweise die häufigste. Wir dürfen dabei aber nicht vergessen, die zusammengeführten Änderungen wieder ins Repository einzupflegen, wie uns das hg merge-Kommando auf der letzten Zeile auch vorgeschlagen hat:

$ hg commit -m "Merged changes from my-hello-new-output"

Dieser Befehl sollte keine Ausgabe erzeugen.

Um uns die Änderungen anzuzeigen, die bei unserem Merge passiert sind, können wir das annotate-Kommando benutzen. Es gibt pro Zeile aus, in welchem changeset die Zeile geändert wurde. Wir sehen, daß die Revision 2 die Änderungen in unserem my-hello-desc Repository, und die Revision 3 die Änderungen sind, die wir aus dem Repository my-hello-new-output ins my-hello-desc Repository herübergezogen und zusammengeführt haben!

$ hg annotate hello.c
0: /*
2:  * hello.c - hello, world
0:  *
0:  * Placed in the public domain by Bryan O'Sullivan
0:  *
0:  * This program is not covered by patents in the United States or other
0:  * countries.
0:  */
0:
0: #include <stdio.h>
0:
0: int main(int argc, char **argv)
0: {
0:      printf("hello, world!\n");
3:      printf("sure am glad I'm using Mercurial!\n");
0:      return 0;
0: }

Es gibt natürlich Fälle, wo die Änderungen nicht automatisch zusammengeführt werden können! Schauen wir uns diesen Fall mal an, und was wir in der Situation machen können, wenn Änderungen zu Konflikten führen: GermanTutorialConflict.


CategoryTutorial

GermanTutorialMerge (last edited 2012-11-06 15:41:44 by abuehl)