Differences between revisions 22 and 23
Revision 22 as of 2008-01-12 14:37:25
Size: 4315
Editor: abuehl
Comment: lowercase links
Revision 23 as of 2008-02-09 17:51:15
Size: 4339
Editor: abuehl
Comment: link to Branch
Deletions are marked like this. Additions are marked like this.
Line 57: Line 57:

(see also [:Branch])

Tutorial - merging conflicting changes

We learned how to deal with simple [:Merge:merges] in TutorialMerge.

Mercurial handles more complex merge cases, too. It is not all that uncommon for two people to edit the exact same lines of a file, and then have to figure out what to do. These cases are called [:Conflict:conflicts]; figuring out what to do about a conflict is called [:Resolve:resolving] it.

Let's first create an artificial conflict situation. As we did previously, let's start by making a [:Clone:clone] of my-hello:

$ cd ..
$ hg clone my-hello my-hello-not-cvs

Now let's add a new line of output to hello.c:

$ cd my-hello-not-cvs
$ vi hello.c

We change main to read like this:

int main(int argc, char **argv)
{
        printf("hello, world!\n");
        printf("sure am glad I'm not using CVS!\n");
        return 0;
}

And we [:Commit:commit] the change:

$ hg commit -m "Give thanks for dodging bullet"

Recall that in TutorialFirstChange, we created a [:ChangeSet:changeset] in my-hello-new-output that also added a second line of output. What happens when we try to [:Pull:pull] that change in here?

$ 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)

So far, so good. Let's try an [:Update:update].

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

(see also [:Branch])

As in TutorialMerge, we have to run hg merge. As before, the [:MergeProgram:merge program] will be started under cover. It will usually not be able to merge automatically, because the same line of the same source file has been modified in a different way by each changeset (the one we just [:Commit:commited], and the one we just pulled).

$ hg merge

At this point, what happens depends on what programs are installed on our computer. If we are provident or lucky, and have a graphical merge program installed, we will be able to see what conflicts there are between the two changes, and decide how to resolve them.

Below is the sample conflicts shown in vim editor on a Linux system.

/*
 * hello.c
 *
 * Placed in the public domain by Bryan O'Sullivan
 *
 * This program is not covered by patents in the United States or other
 * countries.
 */

#include <stdio.h>

int main(int argc, char **argv)
{
        printf("hello, world!\n");
<<<<<<< /home/motoko/project/my-hello-not-cvs/hello.c.orig.197516148
        printf("sure am glad I'm not using CVS!\n");
||||||| /tmp/hello.c~base.aYR8Pf
=======
        printf("sure am glad I'm using Mercurial!\n");
>>>>>>> /tmp/hello.c~other.F7OpXy
        return 0;
}

Mercurial is using a per-file 3-way merge. This means that there are 3 input files for merging process, and those are:

  • Local file (from current repository)
  • Other file (from repository being merged)
  • Base file (last version of file before branches separated)

For more information about 3-way, see [http://revctrl.org/ThreeWayMerge ThreeWayMerge] on the [http://revctrl.org/ Revctrl wiki].

Else, if we do not have a graphical merge program installed, we will be dropped into a text editor, which will be visiting the file we need to merge. Doing this by hand is highly error-prone and tedious. It is best to exit the editor and use the hg rollback command to reverse the effect of the pull, then install a merge program, and then try again.

(Note: before Mercurial version 0.9, hg update -m should have been used in place of hg merge and hg undo should have been used instead of hg rollback).

(Note: what do we do with the remaining unnecessary additional file hello.c.orig?).

As before, be sure to commit this change to the repository once the merge is complete:

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

There shouldn't be any output from this command.

Now let's continue and finish on to TutorialConclusion.

See also: ImergeExtension


CategoryTutorial

TutorialConflict (last edited 2019-03-28 10:43:14 by IanMoody)