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.
--- 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
--- 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('<tweakdefaults>', tweakrc)
+ for section in tmpcfg:
+ for name, value in tmpcfg.items(section):
+ if not self.hasconfig(section, name):
+ self.setconfig(section, name, value, "<tweakdefaults>")
+
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
--- 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 <<EOF
@@ -128,6 +151,19 @@
? b/in_b (glob)
? in_root
+if relative paths are explicitly off, tweakdefaults doesn't change it
+ $ cat >> $HGRCPATH <<EOF
+ > [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