Question

I created a new repository, test-backout, and added a new file in it, file. I then made 4 commits, each time, appending the number of the commit to file using

echo [manually entered number] >> file
hg commit -m '[manually entered number]'

In effect, file had:

init
1
2
3

According to the hg book, if I run hg backout --merge 2, I should have:

init
1
3

but instead, it fails to merge and opens up my difftool (vimdiff), and I get 3 options:

init          | init          | init
1             | 1             |
2             |               |
3             |               |

I initially tried it with the --merge option, then again without it. My question now is, is there still a way for me to get:

init
1
3

did I just make a mistake or miss something, or am I stuck with those options?

Was it helpful?

Solution

A big factor in why you got the 3-way merge is that your context is too artificial, and I will get to that.

If I take a 50-line text file and change a different part and commit each change, I won't have to resolve conflicts. And what I mean is I have 4 changesets: rev 0 adds the file, revs 1, 2, and 3 each change one area of the file: the beginning, middle, or end.

In this situation, when I do hg backout 2, it makes a reverse of rev 2 and merges those changes to my working directory, and when I commit, the graph is linear:

@  backout 2
|
o  3
|
o  2
|
o  1
|
o  initial

If I instead do hg backout 2 --merge, it automatically commits the backout as a child of the revision it is backing out, and then merges that with the tip, producing a branched graph after I commit the merge:

@    merge
|\
| o  backout 2
| |
o |  3
|/
o    2
|    
o    1
|    
o    initial

In both situations, I didn't have to do any 3-way merging. The reason you don't automatically get

init
1
3

and instead have to do a 3-way merge is that the changes are too close together. The context and changes in each changeset are completely overlapped (default number of lines of context for a diff chunk is 3 lines, which encompasses the entire file still in your 4th changeset).

A similar example is if you had 3 changesets that each modified the same line. If you backed out the middle change like you're doing here, you would still be presented with a 3-way merge that you'll likely have to manually edit to get correct.

By the way, behavior did change in 1.7, as attested by hg help backout:

Before version 1.7, the behavior without --merge was equivalent to specifying --merge followed by "hg update --clean ." to cancel the merge and leave the child of REV as a head to be merged separately.

However, I don't think that's quite what you suspected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top