Differences between revisions 1 and 25 (spanning 24 versions)
Revision 1 as of 2005-08-26 00:58:29
Size: 2670
Editor: waste
Comment:
Revision 25 as of 2008-08-08 10:16:29
Size: 3832
Comment: renamed Resolve to ResolveConflict
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== ["Tutorial"] - merging conflicting changes == == Tutorial - Merging conflicting changes ==
Line 3: Line 3:
We learned how to deal with simple ["Merge"]s in TutorialMerge. ''(This page is part 8 of 9 of the [:Tutorial] series. Previous part is [:TutorialMerge], next part is [:TutorialConclusion])''
Line 5: Line 5:
["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. We call these cases conflicts; figuring out what to do about a conflict is called resolving it. We learned how to deal with simple [:Merge:merges] in TutorialMerge.
Line 7: Line 7:
We need to create an artificial conflict situation. Let's start by making a ["Clone"] of ''my-hello'': 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 [:ResolveConflict: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}}}:
Line 10: Line 12:
 $ cd ..
 $ hg clone my-hello my-hello-not-cvs
$ cd ..
$ hg clone my-hello my-hello-not-cvs
updating working directory
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
Line 14: Line 18:
Now let's add a new line of output to ''hello.c'': Now let's add a new line of output to {{{hello.c}}}:
Line 17: Line 21:
 $ cd my-hello-not-cvs $ cd my-hello-not-cvs
$ vi hello.c
Line 20: Line 25:
We'll change ''main'' to read like this: We change {{{main}}} to read like this:

{{{#!cplusplus numbers=off
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:
Line 23: Line 39:
 int main(int argc, char **argv)
 {
     printf("hello, world!\n");
     printf("sure am glad I'm not using CVS!\n");
     return 0;
 }
$ hg commit -m "Give thanks for dodging bullet"
Line 31: Line 42:
And ["Commit"] the change: 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?
Line 34: Line 45:
 $ hg commit -t'Give thanks for dodging bullet' $ 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)
Line 37: Line 55:
Recall that in TutorialFirstChange, we created a ChangeSet in ''my-hello-new-output'' that /also/ added a second line of output. What happens when we try to ["Pull"] that change in here? So far, so good. Let's try an [:Update:update].
Line 40: Line 58:
 $ hg pull ../my-hello-new-output/
 pulling from ../my-hello-new-output/
 searching for changes
 adding changesets
 adding manifests
 adding file revisions
 modified 1 files, added 1 changesets and 1 new revisions
 (run 'hg update' to get a working copy)
$ hg update
abort: crosses branches (use 'hg merge' or 'hg update -C')
Line 50: Line 62:
So far, so good. Let's try an ["Update"]. As in [:TutorialMerge], we have to run {{{hg merge}}}. It will 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).
Line 53: Line 65:
 $ hg update
 this update spans a branch affecting the following files:
  hello.c (resolve)
 aborting update spanning branches!
 (use update -m to perform a branch merge)
$ hg merge
Line 60: Line 68:
As in TutorialMerge, we have to run ''update -m''. But here's where things change. ["Mercurial"] cannot now automatically ["Merge"], because the same line of the same source file has been modified in a different way by each ChangeSet (the one we just ["Commit"]ted, and the one we just ["Pull"]ed). At this point, what happens depends on how Mercurial is configured (see [:MergeToolConfiguration]). Per default, Mercurial drops into the editor marking the conflicts in the file for manual resolution:
Line 63: Line 71:
 ~/hg/my-hello-tmp $ hg update -m /*
 * 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/adi/tmp/tutorial/my-hello-not-cvs/hello.c
        printf("sure am glad I'm not using CVS!\n");
=======
        printf("sure am glad I'm using Mercurial!\n");
>>>>>>> /tmp/hello.c~other.2xAVqv
        return 0;
}
Line 66: Line 94:
At this point, what happens may be a matter of luck. If we are lucky, and have a MergeProgram installed, we will be dropped into the MergeProgram. Here, we will be able to see what conflicts there are between the two changes, and decide how to resolve them. In the editor, we delete the conflict markers and keep the "sure am glad I'm using Mercurial!\n" line,
deleting the line about CVS. When we leave the editor, Mercurial asks:
Line 68: Line 97:
If we are not lucky, and do not have a MergeProgram installed, we will be dropped into our 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 undo'' command to reverse the effect of the ["Pull"], then install a MergeProgram and try again. {{{
Was the merge successful? [y/n]
}}}
Line 70: Line 101:
Now let us continue on to TutorialConclusion. Here, we answer "y". Mercurial now reports the summary of the manual merge process:

{{{
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
}}}

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"
}}}

What we have seen here is the default behaviour of Mercurial. However, Mercurial can be configured
to call external three-way merge tools. Information about configuring three-way merge
tools can be found at [:MergeToolConfiguration].

Now let's continue and finish on to [:TutorialConclusion].

----
CategoryTutorial

Tutorial - Merging conflicting changes

(This page is part 8 of 9 of the [:Tutorial] series. Previous part is [:TutorialMerge], next part is [:TutorialConclusion])

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 [:ResolveConflict: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
updating working directory
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

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: crosses branches (use 'hg merge' or 'hg update -C')

As in [:TutorialMerge], we have to run hg merge. It will 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 how Mercurial is configured (see [:MergeToolConfiguration]). Per default, Mercurial drops into the editor marking the conflicts in the file for manual resolution:

/*
 * 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/adi/tmp/tutorial/my-hello-not-cvs/hello.c
        printf("sure am glad I'm not using CVS!\n");
=======
        printf("sure am glad I'm using Mercurial!\n");
>>>>>>> /tmp/hello.c~other.2xAVqv
        return 0;
}

In the editor, we delete the conflict markers and keep the "sure am glad I'm using Mercurial!\n" line, deleting the line about CVS. When we leave the editor, Mercurial asks:

Was the merge successful? [y/n]

Here, we answer "y". Mercurial now reports the summary of the manual merge process:

0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

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"

What we have seen here is the default behaviour of Mercurial. However, Mercurial can be configured to call external three-way merge tools. Information about configuring three-way merge tools can be found at [:MergeToolConfiguration].

Now let's continue and finish on to [:TutorialConclusion].


CategoryTutorial

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