tags:

views:

64

answers:

4

I'm trying to merge two branches together using mercurial and there are some conflicts. When working in Subversion, merge conflicts would result in the conflicted file being replaced by a unified diff, my own version of the file with the ".mine" extension added as well as the last checked in version of the file with the ".rxxx" extension added.

With mercurial, I only get the unified diff as well as my own version with the ".orig" extension added.

I'm used to editing the merges myself in my own time in eclipse using the "Compare With > Each Other" command or using FileMerge, however as the base revision is not available without manually going and fetching it I can't work this way any more.

I do not want to perform the merging during the hg merge command - I prefer to do it in my own time.

Is there a setting or extension I can use to make this possible?

A: 

You can set the HGMERGE environment variable.

Mercurial will usually attempt to merge the files using a simple merge algorithm first, to see if they can be merged without conflicts. Only if there are conflicting changes will hg actually execute the merge program.

You can set this to some GUI merge tool etc.

There are other options like internal:fail, internal:local, or internal:other

In hgrc:

[ui]
merge = your-merge-program

[merge-tools]
kdiff3.args = $base $local $other -o $output

So you should be able to specify merge program's arguments with all your needs. Probably, you can adopt this technique for Eclipse to be fired up.

To make merge fail immediately on conflict, try

export HGMERGE=false

In fact, if you want to know the conflict in advance, you could use the "preview" option for hg merge

-P --preview  review revisions to merge (no merge is performed)
pyfunc
I don't want to have to do the merging during the hg merge command - I prefer to do it in my own time rather than all at once. I'm really just interested in whether it's possible to get mercurial to work with my workflow, rather than my workflow to work with mercurial.
Shabbyrobe
@Shabbyrobe : See my edited reply. This should work for you.
pyfunc
Thanks for the update, but it still doesn't address the meat of the question. Subversion emits a file which contains the base revision on merge failure as well as the version with local edits. Mercurial only emits the latter. I want it to emit the former as well, or possibly find some hack that allows it to be easily accessible.
Shabbyrobe
+1  A: 

How about setting a merge tool that just saves the files mercurial is creating for the merge tool to operate on?

[ui]
merge = copy

[merge-tools]
copy.executable = /path/to/mycopy.sh
copy.args = $base $local $other $output

And then in mycopy.sh just do something like:

#!/bin/sh
cp $1 $4.base
cp $2 $4.mine
cp $3 $4.theirs

That should always succeed instantly and leave you with a .base a .mine and a .theirs for each file that conflicted. You can set that up once in your ~/.hgrc and be done with it.

Ry4an
Thanks Ry4an. That works great. What's the difference between $base and $other?
Shabbyrobe
`base` is the common ancestor of `mine` and `other` (`theirs`); the revision on which both were based. Subversion just gives you `mine` and `other`.
shambulator
Yeah, base a huge part of why merging in mercurial succeeds without help more often than in svn -- because ancestors are tracked so one can find $base.
Ry4an
I notice that this emits .base, .mine and .theirs even if mercurial succeeds at automatically merging the files. Is there a way to stop that from happening?
Shabbyrobe
Hmm, try adding the line `copy.premerge = True` to your config. Up until now I'd assumed it defaulted to true, but [the wiki](http://mercurial.selenic.com/wiki/MergeToolConfiguration) suggests that if the internal merge succeeds, a true value prevents the merge tool from running.
shambulator
A: 

Take a look at the hg resolve command. Once a merge has started, but before it's been committed, you can use resolve to list files with conflicts, as well as mark conflicts as resolved or unresolved, or restart the merging process, all at the granularity of individual files rather than changesets.

It doesn't give you the files you want (though see @Ry4an's answer), but it can fire up your merge tools for any particular file whenever you care to resolve it.

shambulator
+1  A: 

We have a built-in merge tool for this called internal:dump. So with

[ui]
merge = internal:dump

you will be brought back to the good old Subversion-days, or something close to it.

Martin Geisler