Size: 4339
Comment: link to Branch
|
← Revision 42 as of 2019-03-28 10:43:14 ⇥
Size: 3912
Comment: Revert vandalism
|
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 of the [[Tutorial]] series. Previous part is TutorialMerge, next part is TutorialConclusion)'' |
Line 3: | Line 4: |
We learned how to deal with simple [:Merge:merges] in TutorialMerge. | We learned how to deal with simple [[Merge|merges]] in TutorialMerge. |
Line 5: | Line 6: |
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. | 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 resolving it. |
Line 7: | Line 8: |
Let's first create an artificial conflict situation. As we did previously, let's start by making a [:Clone:clone] of {{{my-hello}}}: | Let's first create an artificial conflict situation. As we did previously, let's start by making a clone of {{{my-hello}}}: |
Line 12: | Line 13: |
updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
Line 13: | Line 16: |
Line 20: | Line 22: |
Line 31: | Line 32: |
And we [:Commit:commit] the change: |
And we commit the change: |
Line 37: | Line 37: |
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? |
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 that change in here? |
Line 50: | Line 49: |
So far, so good. Let's try an [:Update:update]. |
So far, so good. Let's try an [[Update|update]]. |
Line 55: | Line 53: |
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 57: | Line 55: |
(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 committed, and the one we just pulled). |
Line 66: | Line 60: |
At this point, what happens depends on how Mercurial is configured (see MergeToolConfiguration). Per default, Mercurial inserts a set of markers into the files to be merged in your working copy: | |
Line 67: | Line 62: |
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. |
|
Line 85: | Line 77: |
<<<<<<< /home/motoko/project/my-hello-not-cvs/hello.c.orig.197516148 | <<<<<<< local |
Line 87: | Line 79: |
||||||| /tmp/hello.c~base.aYR8Pf | |
Line 90: | Line 81: |
>>>>>>> /tmp/hello.c~other.F7OpXy | >>>>>>> other |
Line 94: | Line 85: |
You can find these files using the 'hg status' command, as before, noting that Mercurial has saved a copy of the original file before inserting the conflict markers: | |
Line 95: | Line 87: |
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) |
{{{ $ hg status M hello.c ? hello.c.orig }}} To resolve the conflict, we open 'hello.c' in an editor, delete the conflict markers and keep the "sure am glad I'm using Mercurial!\n" line, deleting the line about CVS. We can then save and quit the editor. |
Line 100: | Line 94: |
For more information about 3-way, see [http://revctrl.org/ThreeWayMerge ThreeWayMerge] on the [http://revctrl.org/ Revctrl wiki]. | Then, we let Mercurial know that we have resolved the conflict using the {{{hg resolve}}} command: |
Line 102: | Line 96: |
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?-~). |
{{{ $ hg resolve -m hello.c }}} Mercurial accepts the resolution without any output. |
Line 113: | Line 106: |
There shouldn't be any output from this command. |
What we have seen here is the default behaviour of Mercurial. You can, if you want, configure Mercurial to open the editor automatically. Mercurial can also be configured to call external three-way merge tools. Information about both of these can be found at MergeToolConfiguration. |
Line 118: | Line 110: |
See also: ImergeExtension |
Tutorial - Merging conflicting Changes
(This page is part of the Tutorial series. Previous part is TutorialMerge, next part is TutorialConclusion)
We learned how to deal with simple 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 conflicts; figuring out what to do about a conflict is called resolving it.
Let's first create an artificial conflict situation. As we did previously, let's start by making a 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 the change:
$ hg commit -m "Give thanks for dodging bullet"
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?
$ 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.
$ 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 committed, and the one we just pulled).
$ hg merge
At this point, what happens depends on how Mercurial is configured (see MergeToolConfiguration). Per default, Mercurial inserts a set of markers into the files to be merged in your working copy:
/* * 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"); <<<<<<< local printf("sure am glad I'm not using CVS!\n"); ======= printf("sure am glad I'm using Mercurial!\n"); >>>>>>> other return 0; }
You can find these files using the 'hg status' command, as before, noting that Mercurial has saved a copy of the original file before inserting the conflict markers:
$ hg status M hello.c ? hello.c.orig
To resolve the conflict, we open 'hello.c' in an editor, delete the conflict markers and keep the "sure am glad I'm using Mercurial!\n" line, deleting the line about CVS. We can then save and quit the editor.
Then, we let Mercurial know that we have resolved the conflict using the hg resolve command:
$ hg resolve -m hello.c
Mercurial accepts the resolution without any output.
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. You can, if you want, configure Mercurial to open the editor automatically. Mercurial can also be configured to call external three-way merge tools. Information about both of these can be found at MergeToolConfiguration.
Now let's continue and finish on to TutorialConclusion.