@@ -40,6 +40,7 @@ from . import (
error,
exchange,
extensions,
+ filemerge,
fileset,
formatter,
hg,
@@ -1502,6 +1503,84 @@ def debugpathcomplete(ui, repo, *specs,
ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
ui.write('\n')
+@command('debugpickmergetool',
+ [('r', 'rev', '', _('check for files in this revision'), _('REV')),
+ ('', 'changedelete', None, _('emulate merging change and delete')),
+ ] + commands.walkopts + commands.mergetoolopts,
+ _('[PATTERN]...'),
+ inferrepo=True)
+def debugpickmergetool(ui, repo, *pats, **opts):
+ """examine which merge tool is chosen for specified file
+
+ As described in :hg:`help merge-tools`, Mercurial examines
+ configurations below in this order to decide which merge tool is
+ chosen for specified file.
+
+ 1. ``--tool`` option
+ 2. ``HGMERGE`` environment variable
+ 3. configurations in ``merge-patterns`` section
+ 4. configuration of ``ui.merge``
+ 5. configurations in ``merge-tools`` section
+ 6. ``hgmerge`` tool (for historical reason only)
+ 7. default tool for fallback (``:merge`` or ``:prompt``)
+
+ This command writes out examination result in the style below::
+
+ FILE = MERGETOOL
+
+ By default, all files known in the first parent context of the
+ working directory are examined. Use file patterns and/or -I/-X
+ options to limit target files. -r/--rev is also useful to examine
+ files in another context without actual updating to it.
+
+ With --debug, this command shows warning messages while matching
+ against ``merge-patterns`` and so on, too. It is recommended to
+ use this option with explicit file patterns and/or -I/-X options,
+ because this option increases amount of output per file according
+ to configurations in hgrc.
+
+ With -v/--verbose, this command shows configurations below at
+ first (only if specified).
+
+ - ``--tool`` option
+ - ``HGMERGE`` environment variable
+ - configuration of ``ui.merge``
+
+ If merge tool is chosen before matching against
+ ``merge-patterns``, this command can't show any helpful
+ information, even with --debug. In such case, information above is
+ useful to know why a merge tool is chosen.
+ """
+ overrides = {}
+ if opts['tool']:
+ overrides[('ui', 'forcemerge')] = opts['tool']
+ ui.note(('with --tool %r\n') % (opts['tool']))
+
+ with ui.configoverride(overrides, 'debugmergepatterns'):
+ hgmerge = encoding.environ.get("HGMERGE")
+ if hgmerge is not None:
+ ui.note(('with HGMERGE=%r\n') % (hgmerge))
+ uimerge = ui.config("ui", "merge")
+ if uimerge:
+ ui.note(('with ui.merge=%r\n') % (uimerge))
+
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
+ m = scmutil.match(ctx, pats, opts)
+ changedelete = opts['changedelete']
+ for path in ctx.walk(m):
+ fctx = ctx[path]
+ try:
+ if not ui.debugflag:
+ ui.pushbuffer(error=True)
+ tool, toolpath = filemerge._picktool(repo, ui, path,
+ fctx.isbinary(),
+ 'l' in fctx.flags(),
+ changedelete)
+ finally:
+ if not ui.debugflag:
+ ui.popbuffer()
+ ui.write(('%s = %s\n') % (path, tool))
+
@command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
'''access the pushkey key/value protocol
@@ -99,6 +99,7 @@ Show debug commands if there are no othe
debugnamecomplete
debugobsolete
debugpathcomplete
+ debugpickmergetool
debugpushkey
debugpvec
debugrebuilddirstate
@@ -272,6 +273,7 @@ Show all commands + options
debugnamecomplete:
debugobsolete: flags, record-parents, rev, index, delete, date, user, template
debugpathcomplete: full, normal, added, removed
+ debugpickmergetool: rev, changedelete, include, exclude, tool
debugpushkey:
debugpvec:
debugrebuilddirstate: rev, minimal
@@ -912,6 +912,8 @@ Test list of internal help commands
debugoptEXP (no help text available)
debugpathcomplete
complete part or all of a tracked path
+ debugpickmergetool
+ examine which merge tool is chosen for specified file
debugpushkey access the pushkey key/value protocol
debugpvec (no help text available)
debugrebuilddirstate
@@ -1281,3 +1281,68 @@ Verify naming of temporary files and tha
*/f~base.?????? $TESTTMP/f.txt.orig */f~other.??????.txt $TESTTMP/f.txt (glob)
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
+
+Check that debugpicktool examines which merge tool is chosen for
+specified file as expected
+
+ $ beforemerge
+ [merge-tools]
+ false.whatever=
+ true.priority=1
+ true.executable=cat
+ # hg update -C 1
+
+(default behavior: checking files in the working parent context)
+
+ $ hg manifest
+ f
+ $ hg debugpickmergetool
+ f = true
+
+(-X/-I and file patterns limmit examination targets)
+
+ $ hg debugpickmergetool -X f
+ $ hg debugpickmergetool unknown
+ unknown: no such file in rev ef83787e2614
+
+(--changedelete emulates merging change and delete)
+
+ $ hg debugpickmergetool --changedelete
+ f = :prompt
+
+(-r REV causes checking files in specified revision)
+
+ $ hg manifest -r tip
+ f.txt
+ $ hg debugpickmergetool -r tip
+ f.txt = true
+
+#if symlink
+
+(symlink causes chosing :prompt)
+
+ $ hg debugpickmergetool -r 6d00b3726f6e
+ f = :prompt
+
+#endif
+
+(--verbose shows some configurations)
+
+ $ hg debugpickmergetool --tool foobar -v
+ with --tool 'foobar'
+ f = foobar
+
+ $ HGMERGE=false hg debugpickmergetool -v
+ with HGMERGE='false'
+ f = false
+
+ $ hg debugpickmergetool --config ui.merge=false -v
+ with ui.merge='false'
+ f = false
+
+(--debug shows errors detected intermediately)
+
+ $ hg debugpickmergetool --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool --debug f
+ couldn't find merge tool true (for pattern f)
+ couldn't find merge tool true
+ f = false