[PATCH 1 of 9 phases] config: have a way to backup and restore value in config

Pierre-Yves David pierre-yves.david at ens-lyon.org
Tue Jan 17 17:37:42 CST 2012


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1326838344 -3600
# Node ID 353d1385f6ff36fafb291c8bf46474d9b17bfc7d
# Parent  476a981fdf341f5bedbd958ca6c8e930fe35b5f9
config: have a way to backup and restore value in config

This is introduce to allow temporary overwriting of a config value while being
able to reinstall the old value once done. The main advantage over using
``config`` and ``setconfig`` is that backup and restore will properly restore
the lack of any config. Restoring the fact that there was no value is important
to allow config user to keep using meaniful default value.

A more naive approach will result in the following scenario::

  Before:
    config(section, item, my_default) --> my_default

  temporal overwrite
    old = config(section, item)
    …
    setconfig(section, item, old)

  After
    config(section, item, my_default) --> None

The first user of this feature should be mq to overwriting minimal phase of
future commit.

diff --git a/mercurial/config.py b/mercurial/config.py
--- a/mercurial/config.py
+++ b/mercurial/config.py
@@ -61,6 +61,19 @@
         self._source.update(src._source)
     def get(self, section, item, default=None):
         return self._data.get(section, {}).get(item, default)
+
+    def backup(self, section, item):
+        """return a tuple allowing restore to reinstall a previous valuesi
+
+        The main reason we need it is because it handle the "no data" case.
+        """
+        try:
+            value = self._data[section][item]
+            source = self.source(section, item)
+            return (section, item, value, source)
+        except KeyError:
+            return (section, item)
+
     def source(self, section, item):
         return self._source.get((section, item), "")
     def sections(self):
@@ -73,6 +86,20 @@
         self._data[section][item] = value
         self._source[(section, item)] = source
 
+    def restore(self, bckdata):
+        """restore data returned by self.backup"""
+        if len(bckdata) == 4:
+            # restore old data
+            section, item, value, source = bckdata
+            self._data[section][item] = value
+            self._source[(section, item)] = source
+        else:
+            # no data before, remove everything
+            section, item = bckdata
+            if section in self._data:
+                del self._data[section][item]
+            self._source.pop((section, item), None)
+
     def parse(self, src, data, sections=None, remap=None, include=None):
         sectionre = re.compile(r'\[([^\[]+)\]')
         itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -142,6 +142,15 @@
             self._trustusers.update(self.configlist('trusted', 'users'))
             self._trustgroups.update(self.configlist('trusted', 'groups'))
 
+    def backupconfig(self, section, item):
+        return (self._ocfg.backup(section, item),
+                self._tcfg.backup(section, item),
+                self._ucfg.backup(section, item),)
+    def restoreconfig(self, bckdata):
+        self._ocfg.restore(bckdata[0])
+        self._tcfg.restore(bckdata[1])
+        self._ucfg.restore(bckdata[2])
+
     def setconfig(self, section, name, value, overlay=True):
         if overlay:
             self._ocfg.set(section, name, value)


More information about the Mercurial-devel mailing list