rewrite: simplify the `retained_extras` extra logic
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 25 May 2023 00:23:05 +0200
changeset 50643 cbcbf63b6dbf
parent 50641 5460424092e2
child 50644 89556caf3c66
rewrite: simplify the `retained_extras` extra logic First, we move the definition of value outside of the rebase extensions, as this apply to all rebase-like operation and some live in other place (like evolve). Second we make it a simple set, so that it is easy for an extension to add a new value in it. Third, we move the associated logic in core too. That make it easily available to other extensions. Fourth we simplify it usage, as the verbose version of the filtering is just a handful on line long, we are just going to test all the value for updates, so the Projection overlay is not bringing much here. Note that, we make it a module level set, is a key is worth preserving it is probably worth preserving in all cases. This was already the behavior prior to this change.
hgext/rebase.py
mercurial/rewriteutil.py
mercurial/thirdparty/jaraco/__init__.py
mercurial/thirdparty/jaraco/collections.py
setup.py
--- a/hgext/rebase.py	Mon May 29 18:41:58 2023 +0200
+++ b/hgext/rebase.py	Thu May 25 00:23:05 2023 +0200
@@ -24,7 +24,6 @@
     wdirrev,
 )
 from mercurial.pycompat import open
-from mercurial.thirdparty.jaraco.collections import Projection
 from mercurial import (
     bookmarks,
     cmdutil,
@@ -86,19 +85,6 @@
     return 1
 
 
-def retained_extras():
-    """
-    Yield the names of the extras to be retained.
-    """
-    # graft
-    yield b'source'
-    yield b'intermediate-source'
-
-
-def _save_extras(ctx, extra):
-    extra.update(Projection(retained_extras(), ctx.extra()))
-
-
 def _savebranch(ctx, extra):
     extra[b'branch'] = ctx.branch()
 
@@ -199,7 +185,7 @@
         self.date = opts.get('date', None)
 
         e = opts.get('extrafn')  # internal, used by e.g. hgsubversion
-        self.extrafns = [_save_extras]
+        self.extrafns = [rewriteutil.preserve_extras_on_rebase]
         if e:
             self.extrafns = [e]
 
--- a/mercurial/rewriteutil.py	Mon May 29 18:41:58 2023 +0200
+++ b/mercurial/rewriteutil.py	Thu May 25 00:23:05 2023 +0200
@@ -27,6 +27,21 @@
 
 NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
 
+# set of extra entry that should survive a rebase-like operation, extensible by extensions
+retained_extras_on_rebase = {
+    b'source',
+    b'intermediate-source',
+}
+
+
+def preserve_extras_on_rebase(old_ctx, new_extra):
+    """preserve the relevant `extra` entry from old_ctx on rebase-like operation"""
+    new_extra.update(
+        (key, value)
+        for key, value in old_ctx.extra().items()
+        if key in retained_extras_on_rebase
+    )
+
 
 def _formatrevs(repo, revs, maxrevs=4):
     """returns a string summarizing revisions in a decent size
--- a/mercurial/thirdparty/jaraco/collections.py	Mon May 29 18:41:58 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-# adapted from jaraco.collections 3.9
-
-import collections
-
-
-class Projection(collections.abc.Mapping):
-    """
-    Project a set of keys over a mapping
-
-    >>> sample = {'a': 1, 'b': 2, 'c': 3}
-    >>> prj = Projection(['a', 'c', 'd'], sample)
-    >>> prj == {'a': 1, 'c': 3}
-    True
-
-    Keys should only appear if they were specified and exist in the space.
-
-    >>> sorted(list(prj.keys()))
-    ['a', 'c']
-
-    Attempting to access a key not in the projection
-    results in a KeyError.
-
-    >>> prj['b']
-    Traceback (most recent call last):
-    ...
-    KeyError: 'b'
-
-    Use the projection to update another dict.
-
-    >>> target = {'a': 2, 'b': 2}
-    >>> target.update(prj)
-    >>> target == {'a': 1, 'b': 2, 'c': 3}
-    True
-
-    Also note that Projection keeps a reference to the original dict, so
-    if you modify the original dict, that could modify the Projection.
-
-    >>> del sample['a']
-    >>> dict(prj)
-    {'c': 3}
-    """
-
-    def __init__(self, keys, space):
-        self._keys = tuple(keys)
-        self._space = space
-
-    def __getitem__(self, key):
-        if key not in self._keys:
-            raise KeyError(key)
-        return self._space[key]
-
-    def __iter__(self):
-        return iter(set(self._keys).intersection(self._space))
-
-    def __len__(self):
-        return len(tuple(iter(self)))
--- a/setup.py	Mon May 29 18:41:58 2023 +0200
+++ b/setup.py	Thu May 25 00:23:05 2023 +0200
@@ -1303,7 +1303,6 @@
     'mercurial.templates',
     'mercurial.thirdparty',
     'mercurial.thirdparty.attr',
-    'mercurial.thirdparty.jaraco',
     'mercurial.thirdparty.zope',
     'mercurial.thirdparty.zope.interface',
     'mercurial.upgrade_utils',