Merging with Mercurial (was: Re: macosx stuff seeping into the ports?)

Giorgos Keramidas keramida at
Fri Jul 13 22:53:56 UTC 2007

On 2007-07-12 12:36, "Michael P. Soulier" <msoulier at> wrote:
> I just tried a merge with mercurial, built out of ports.
> /usr/local/bin/hgmerge:
> /Developer/Applications/Utilities/ not found
> Umm, why the hell would I have that on FreeBSD??

The default 'hgmerge' script distributed as part of the official
Mercurial tree tries FileMerge and a few other merge-tools before
giving up.

You can always replace the default merge-tool with one you like better,
by a variety of methods:


1. Setting in your ~/.hgrc file the ui.merge option:

    merge = kdiff3

Popular choices for [ui.merge] include kdiff3, meld and I've recently
started experimenting with Sun's "gpyfm" Python/GTK+ GUI merge tool.


2. Setting HGMERGE in the environment of the `hg' utility:

    $ env HGMERGE=true hg merge

When you use this sort of 'merge trickery', you can do things like:

    $ hg up -C localhead
    $ env HGMERGE=true hg merge [remotehead]

and then you can selectively "revert" files to their local head version,
or to their remote head version:

    $ hg revert --no-backup -r remotehead obj/lib/
    $ hg revert --no-backup -r localhead obj/bin/*

This tends to a bit error-prone and doesn't really help when you
_really_ want to do a 3-way merge of source code or text files.


Most of the available merge tools tend to create a varying level of mess
with binary files, like snapshots of build trees, so I'm looking at
alternative ways of merging.

Each time Mercurial invokes $HGMERGE or [ui.merge] there is a conflict
because both the local and remote branch has modified the same file.

Ideally, it should be possible to write a smarter merge wrapper script,
which is written in Python to hook into Mercurial as a backend, and
provide the user with more choices, like:

    $ export HGMERGE=smart-merge

    $ hg up -C localhead
    0 files updated, 0 files merged, 0 files removed, 0 files unresolved
    $ hg merge [remotehead]

    Merging file obj/lib/
      command:   (a)ccept, (d)iff, (e)dit, (h)istory, (m)erge, (q)uit
      changeset: (a)ncestor, (p)arent, (c)hild, (m)erged


At which point, you can run commands like:

    ? accept child
    ? acc ch
    ? diff parent
    ? h p

or any sort of command which can be auto-completed to something
meaningful using some sort of syntax like the one shown above.

This way it would be _much_ easier to merge binary files, and given a
sufficiently 'smart' HGMERGE application it could be easy to merge by
pressing RET RET RET a few times, and let the defaults apply :)

This may be tricky to write, and I don't trust my Python skills yet to
embark on such a project, so I'm just using a local wrapper around
gdiff3 and Sun's gpyfm GTK+-based merge tool (gpyfm) for now.  For
Mercurial workspaces which contain source code, this combination can
really work wonders :-)

If you need help with setting up something which supersedes the default
'hgmerge' script distributed with the Mercurial port, please feel free
to ask me for the merge scripts I am using locally, search for
"MergeProgram" in the Mercurial wiki[*], or hop into #mercurial on
Freenode IRC and chat with all the friendly folks there.


I hope all this helps a bit,

- Giorgos

More information about the freebsd-questions mailing list