diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -184,6 +184,10 @@ coreconfigitem('color', 'pagermode', default=dynamicdefault, ) +coreconfigitem('commands', '.*\.default\..*', + generic=True, + default=dynamicdefault, +) coreconfigitem('commands', 'show.aliasprefix', default=list, ) diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -611,6 +611,37 @@ args = pycompat.maplist( util.expandpath, pycompat.shlexsplit(defaults)) + args c = list(entry[1]) + + # Apply new-style defaults from config file by actually changing the + # option defaults. We still let old-style defaults trump these (since + # those are added to the command line). + for idx, opt in enumerate(c): + optname = opt[1] + olddefault = opt[2] + defaulttype = type(olddefault) + cfgitem = "%s.default.%s" % (cmd, optname) + + # parse the new default as the same type as the original. + newdefault = ui.configtyped("commands", cfgitem, defaulttype, + olddefault) + if isinstance(olddefault, fancyopts.customopt): + def badvalue(s): + raise error.Abort( + _('invalid value %r for config option %s: %s') % ( + newdefault, cfgitem, s)) + + # If it's a custom option, then configtyped must have parsed it + # as string - ask the customopt to parse its new default. + # Notice this does have limitations - since we have no way to + # start with a "clean" old state, this is not overriding the + # default, but rather adding to it - e.g. a non-empty list + # default will be appended to. + olddefault.defaultvalue = olddefault.newstate( + olddefault.defaultvalue, newdefault, badvalue) + elif olddefault != newdefault: + # override the default in the flag declaration. + c[idx] = (opt[0], opt[1], newdefault, opt[3]) + else: cmd = None c = [] diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -545,7 +545,8 @@ return main, sub - def configtyped(self, section, name, itemtype, default=_unset, untrusted=False): + def configtyped(self, section, name, itemtype, default=_unset, + untrusted=False): """Get a config item as the given type.""" if itemtype is type(False) or itemtype is type(None): return self.configbool(section, name, default, untrusted) diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t --- a/tests/test-dispatch.t +++ b/tests/test-dispatch.t @@ -8,8 +8,10 @@ $ hg -v log -v x $ echo a > a + $ echo b > b $ hg ci -Ama adding a + adding b Missing arg: @@ -52,10 +54,10 @@ Parsing of early options should stop at "--": $ hg cat -- --config=hooks.pre-cat=false - --config=hooks.pre-cat=false: no such file in rev cb9a9f314b8b + --config=hooks.pre-cat=false: no such file in rev 0cd96de13884 [1] $ hg cat -- --debugger - --debugger: no such file in rev cb9a9f314b8b + --debugger: no such file in rev 0cd96de13884 [1] Unparsable form of early options: @@ -155,11 +157,11 @@ abort: pre-log hook exited with status 1 [255] $ HGPLAIN=+strictflags hg --cwd .. -q -Ra log -b default - 0:cb9a9f314b8b + 0:0cd96de13884 $ HGPLAIN=+strictflags hg --cwd .. -q --repository a log -b default - 0:cb9a9f314b8b + 0:0cd96de13884 $ HGPLAIN=+strictflags hg --cwd .. -q --repo a log -b default - 0:cb9a9f314b8b + 0:0cd96de13884 For compatibility reasons, HGPLAIN=+strictflags is not enabled by plain HGPLAIN: @@ -167,12 +169,13 @@ abort: pre-log hook exited with status 1 [255] $ HGPLAINEXCEPT= hg log --cwd .. -q -Ra -b default - 0:cb9a9f314b8b + 0:0cd96de13884 [defaults] $ hg cat a a + $ cp $HGRCPATH hgrc.bak $ cat >> $HGRCPATH < [defaults] > cat = -r null @@ -180,6 +183,49 @@ $ hg cat a a: no such file in rev 000000000000 [1] + $ cp -f hgrc.bak $HGRCPATH + +new-style [commands] defaults and overrides + + $ hg cat a + a + $ cat >> $HGRCPATH < [commands] + > cat.default.rev = null + > EOF + $ hg cat a + a: no such file in rev 000000000000 + [1] + + $ mv -f hgrc.bak $HGRCPATH + $ echo foo >> a + $ hg rm b + $ echo bar > c + $ hg add c + $ hg status + M a + A c + R b + ? bad.py + ? bad.pyc + $ cat >> $HGRCPATH < [commands] + > status.default.removed = 1 + > EOF + $ hg status + R b + $ hg status --modified + M a + R b + $ hg status --modified --no-removed + M a + $ hg status --no-removed + M a + A c + R b + ? bad.py + ? bad.pyc + $ hg revert a b c $ cd "$TESTTMP"