config: track "source" along side value
authorPierre-Yves David <pierre-yves.david@octobus.net>
Fri, 29 Jan 2021 10:28:03 +0100
changeset 46621 d3df397e7a59
parent 46620 7621ab4005bf
child 46622 a3dced4b7b04
config: track "source" along side value Currently the source is stored in a entirely different way than the data. This is impractical. Especially if we are about to add more of such metadata. So lets put them back together. Differential Revision: https://phab.mercurial-scm.org/D9925
mercurial/config.py
--- a/mercurial/config.py	Sat Jan 30 00:32:42 2021 +0100
+++ b/mercurial/config.py	Fri Jan 29 10:28:03 2021 +0100
@@ -27,9 +27,6 @@
         if data:
             for k in data._data:
                 self._data[k] = data[k].copy()
-            self._source = data._source.copy()
-        else:
-            self._source = util.cowdict()
 
     def copy(self):
         return config(self)
@@ -48,13 +45,11 @@
             yield d
 
     def update(self, src):
-        self._source = self._source.preparewrite()
         for s, n in src._unset:
             ds = self._data.get(s, None)
             if ds is not None and n in ds:
                 self._data[s] = ds.preparewrite()
                 del self._data[s][n]
-                del self._source[(s, n)]
         for s in src:
             ds = self._data.get(s, None)
             if ds:
@@ -62,31 +57,40 @@
             else:
                 self._data[s] = util.cowsortdict()
             self._data[s].update(src._data[s])
-        self._source.update(src._source)
+
+    def _get(self, section, item):
+        return self._data.get(section, {}).get(item)
 
     def get(self, section, item, default=None):
-        return self._data.get(section, {}).get(item, default)
+        result = self._get(section, item)
+        if result is None:
+            return default
+        return result[0]
 
-    def backup(self, section, item):
+    def backup(self, section, key):
         """return a tuple allowing restore to reinstall a previous value
 
         The main reason we need it is because it handles the "no data" case.
         """
         try:
-            value = self._data[section][item]
-            source = self.source(section, item)
-            return (section, item, value, source)
+            item = self._data[section][key]
         except KeyError:
-            return (section, item)
+            return (section, key)
+        else:
+            return (section, key) + item
 
     def source(self, section, item):
-        return self._source.get((section, item), b"")
+        result = self._get(section, item)
+        if result is None:
+            return b""
+        return result[1]
 
     def sections(self):
         return sorted(self._data.keys())
 
     def items(self, section):
-        return list(pycompat.iteritems(self._data.get(section, {})))
+        items = pycompat.iteritems(self._data.get(section, {}))
+        return [(k, v) for (k, (v, s)) in items]
 
     def set(self, section, item, value, source=b""):
         if pycompat.ispy3:
@@ -103,10 +107,7 @@
             self._data[section] = util.cowsortdict()
         else:
             self._data[section] = self._data[section].preparewrite()
-        self._data[section][item] = value
-        if source:
-            self._source = self._source.preparewrite()
-            self._source[(section, item)] = source
+        self._data[section][item] = (value, source)
 
     def alter(self, section, key, new_value):
         """alter a value without altering its source or level
@@ -120,19 +121,17 @@
 
     def restore(self, data):
         """restore data returned by self.backup"""
-        self._source = self._source.preparewrite()
-        if len(data) == 4:
+        if len(data) != 2:
             # restore old data
-            section, item, value, source = data
+            section, key = data[:2]
+            item = data[2:]
             self._data[section] = self._data[section].preparewrite()
-            self._data[section][item] = value
-            self._source[(section, item)] = source
+            self._data[section][key] = item
         else:
             # no data before, remove everything
             section, item = data
             if section in self._data:
                 self._data[section].pop(item, None)
-            self._source.pop((section, item), None)
 
     def parse(self, src, data, sections=None, remap=None, include=None):
         sectionre = util.re.compile(br'\[([^\[]+)\]')