Clone wiki

hgext-mergebypatch / Home

MergeByPatch Extension -- yet another internal merge tools

(Japanese version of this page is available)

Motivation of this extension

Mercurial uses 'internal:merge' as merge tool by default, and it merges file contents of each revisions by 3-way merge.

But 3-way merge sometimes generates complicated result unexpectedly, because it puts contents of each revisions into result file side by side, as like below:

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;

This extension adds 'internal:patch2local' and 'internal:patch2other' as internal merge tools to Mercurial.

These merge file contents of revisions by the way like patch command.

When you merge revisons which cause conflicts, they will create '*.rej' file, which contains rejected hunks like as below, for each unresolved files.

--- hello.c
+++ hello.c
@@ -13,4 +13,4 @@

 int main(int argc, char **argv)
         printf("hello, world!\n");
+        printf("sure am glad I'm not using CVS!\n");
         return 0;

In some cases, rejected hunks are easier to examine conflicts than 3-way merge result.

You can resolve conflicts in each unresolved files with looking '*.rej' files.

Enabling this extension

This extension can be enabled on Mercurial 2.2 or later: you can also enable this on revisions after 14dc2bbba6d2, if you build Mercurial from source.

To enable this extension, save 'hgext/' of this repository into your system, then specify the full path to it in Mercurial configuration file as like below:

mergebypatch = /path/to/

Please see 'hg help extensions' and 'hg help config' for detail, too.

Difference between 'patch2other' and 'patch2local'

After enabling this extension, you can choose 'internal:patch2other' and 'internal:patch2other' as internal merge tool.

'internal:patch2other' merges two revision LOCAL and OTHER which derive from BASE in steps shown below:

  1. create diff between BASE and LOCAL
  2. apply above diff as patch on OTHER
  3. store rejected changes on LOCAL side into '*.rej'

On the other hand, 'internal:patch2other' applies diff between BASE and OTHER on LOCAL.

'internal:patch2lcoal' may be usually familier than 'internal:patch2other', because it causes merge target file mainly containing contents of LOCAL revisoin which may be familier than one of OTHER for you.

But in linear-update merge (which occurs in 'hg update' with un-commited modify in working directory), 'internal:patch2other' may be better, because OTHER is already commited in history, even though LOCAL is just un-commited modification in working directory.

In addition to it, you can't choose merge tool by command line option for 'hg update'.

So, what about below usage ?

  • choose 'internal:patch2other' by Mercurial configuration file for linear-update merge
  • choose 'internal:patch2local' by command line option for 'hg merge' or 'hg resolve', if you want

Please see 'hg help merge-tools' for detail about choosing/configuring merge tool.