# HG changeset patch # User Augie Fackler # Date 1497488194 14400 # Node ID 9fcb6df413c9ca475e705ecc15df07584dadb0c1 # Parent 6fa245f80b6f84deb3345bda2e096925e2372f4b ui: add support for a tweakdefaults knob We've been talking for years about a one-stop config knob to opt in to better behavior. There have been a lot of ideas thrown around, but they all seem to be too complicated to get anyone to actually do the work.. As such, this patch is the stupidest thing that can possibly work in the name of getting a good feature to users. Right now it's just three config settings that I think are generally uncontroversial, but I expect to add more soon. That will likely include adding new config knobs for the express purpose of adding them to tweakdefaults. diff -r 6fa245f80b6f -r 9fcb6df413c9 mercurial/help/config.txt --- a/mercurial/help/config.txt Thu Jun 15 15:13:18 2017 -0700 +++ b/mercurial/help/config.txt Wed Jun 14 20:56:34 2017 -0400 @@ -2093,6 +2093,15 @@ on all exceptions, even those recognized by Mercurial (such as IOError or MemoryError). (default: False) +``tweakdefaults`` + + By default Mercurial's behavior changes very little from release + to release, but over time the recommended config settings + shift. Enable this config to opt in to get automatic tweaks to + Mercurial's behavior over time. This config setting will have no + effet if ``HGPLAIN` is set or ``HGPLAINEXCEPT`` is set and does + not include ``tweakdefaults``. (default: False) + ``username`` The committer of a changeset created when running "commit". Typically a person's name and email address, e.g. ``Fred Widget diff -r 6fa245f80b6f -r 9fcb6df413c9 mercurial/ui.py --- a/mercurial/ui.py Thu Jun 15 15:13:18 2017 -0700 +++ b/mercurial/ui.py Wed Jun 14 20:56:34 2017 -0400 @@ -43,6 +43,20 @@ _keepalnum = ''.join(c for c in map(pycompat.bytechr, range(256)) if not c.isalnum()) +# The config knobs that will be altered (if unset) by ui.tweakdefaults. +tweakrc = """ +[ui] +# The rollback command is dangerous. As a rule, don't use it. +rollback = False + +[commands] +# Make `hg status` emit cwd-relative paths by default. +status.relative = yes + +[diff] +git = 1 +""" + samplehgrcs = { 'user': """# example user config (see 'hg help config' for more info) @@ -182,6 +196,7 @@ self.fin = src.fin self.pageractive = src.pageractive self._disablepager = src._disablepager + self._tweaked = src._tweaked self._tcfg = src._tcfg.copy() self._ucfg = src._ucfg.copy() @@ -205,6 +220,7 @@ self.fin = util.stdin self.pageractive = False self._disablepager = False + self._tweaked = False # shared read-only environment self.environ = encoding.environ @@ -241,8 +257,29 @@ u.fixconfig(section=section) else: raise error.ProgrammingError('unknown rctype: %s' % t) + u._maybetweakdefaults() return u + def _maybetweakdefaults(self): + if not self.configbool('ui', 'tweakdefaults'): + return + if self._tweaked or self.plain('tweakdefaults'): + return + + # Note: it is SUPER IMPORTANT that you set self._tweaked to + # True *before* any calls to setconfig(), otherwise you'll get + # infinite recursion between setconfig and this method. + # + # TODO: We should extract an inner method in setconfig() to + # avoid this weirdness. + self._tweaked = True + tmpcfg = config.config() + tmpcfg.parse('', tweakrc) + for section in tmpcfg: + for name, value in tmpcfg.items(section): + if not self.hasconfig(section, name): + self.setconfig(section, name, value, "") + def copy(self): return self.__class__(self) @@ -387,6 +424,7 @@ for cfg in (self._ocfg, self._tcfg, self._ucfg): cfg.set(section, name, value, source) self.fixconfig(section=section) + self._maybetweakdefaults() def _data(self, untrusted): return untrusted and self._ucfg or self._tcfg diff -r 6fa245f80b6f -r 9fcb6df413c9 tests/test-status.t --- a/tests/test-status.t Thu Jun 15 15:13:18 2017 -0700 +++ b/tests/test-status.t Wed Jun 14 20:56:34 2017 -0400 @@ -107,6 +107,29 @@ ? a/in_a ? b/in_b +tweaking defaults works + $ hg status --cwd a --config ui.tweakdefaults=yes + ? 1/in_a_1 + ? in_a + ? ../b/1/in_b_1 + ? ../b/2/in_b_2 + ? ../b/in_b + ? ../in_root + $ HGPLAIN=1 hg status --cwd a --config ui.tweakdefaults=yes + ? a/1/in_a_1 (glob) + ? a/in_a (glob) + ? b/1/in_b_1 (glob) + ? b/2/in_b_2 (glob) + ? b/in_b (glob) + ? in_root + $ HGPLAINEXCEPT=tweakdefaults hg status --cwd a --config ui.tweakdefaults=yes + ? 1/in_a_1 + ? in_a + ? ../b/1/in_b_1 + ? ../b/2/in_b_2 + ? ../b/in_b + ? ../in_root + relative paths can be requested $ cat >> $HGRCPATH <> $HGRCPATH < [commands] + > status.relative = False + > EOF + $ hg status --cwd a --config ui.tweakdefaults=yes + ? a/1/in_a_1 (glob) + ? a/in_a (glob) + ? b/1/in_b_1 (glob) + ? b/2/in_b_2 (glob) + ? b/in_b (glob) + ? in_root + $ cd .. $ hg init repo2