Size: 2670
Comment:
|
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].