Size: 4339
Comment: link to Branch
|
Size: 3824
Comment: update for Mercurial 1.0
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
== Tutorial - merging conflicting changes == | == Tutorial - Merging conflicting changes == ''(This page is part 8 of 9 of the [:Tutorial] series. Previous part is [:TutorialMerge], next part is [:TutorialConclusion])'' |
Line 12: | Line 14: |
updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
Line 55: | Line 59: |
abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes | abort: crosses branches (use 'hg merge' or 'hg update -C') |
Line 58: | Line 62: |
(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). |
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 67: | Line 68: |
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. | 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 69: | Line 70: |
Below is the sample conflicts shown in vim editor on a Linux system. | |
Line 85: | Line 85: |
<<<<<<< /home/motoko/project/my-hello-not-cvs/hello.c.orig.197516148 | <<<<<<< /home/adi/tmp/tutorial/my-hello-not-cvs/hello.c |
Line 87: | Line 87: |
||||||| /tmp/hello.c~base.aYR8Pf | |
Line 90: | Line 89: |
>>>>>>> /tmp/hello.c~other.F7OpXy | >>>>>>> /tmp/hello.c~other.2xAVqv |
Line 95: | Line 94: |
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) |
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 100: | Line 97: |
For more information about 3-way, see [http://revctrl.org/ThreeWayMerge ThreeWayMerge] on the [http://revctrl.org/ Revctrl wiki]. | {{{ Was the merge successful? [y/n] }}} |
Line 102: | Line 101: |
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. | Here, we answer "y". Mercurial now reports the summary of the manual merge process: |
Line 104: | Line 103: |
(~-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?-~). |
{{{ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) }}} |
Line 114: | Line 114: |
There shouldn't be any output from this command. | 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]. |
Line 116: | Line 118: |
Now let's continue and finish on to TutorialConclusion. See also: ImergeExtension |
Now let's continue and finish on to [:TutorialConclusion]. |
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 [: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 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].