@@ -449,8 +449,8 @@ def showlatesttagdistance(context, mappi
@templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
def showchangessincelatesttag(context, mapping):
"""Integer. All ancestors not in the latest tag."""
- mapping = mapping.copy()
- mapping['tag'] = getlatesttags(context, mapping)[2][0]
+ tag = getlatesttags(context, mapping)[2][0]
+ mapping = context.overlaymap(mapping, {'tag': tag})
return _showchangessincetag(context, mapping)
def _showchangessincetag(context, mapping):
@@ -480,8 +480,7 @@ def showmanifest(context, mapping):
return
mrev = repo.manifestlog._revlog.rev(mnode)
mhex = hex(mnode)
- mapping = mapping.copy()
- mapping.update({'rev': mrev, 'node': mhex})
+ mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
f = context.process('manifest', mapping)
# TODO: perhaps 'ctx' should be dropped from mapping because manifest
# rev and node are completely different from changeset's.
@@ -613,6 +613,13 @@ class engine(object):
self._aliasmap = _aliasrules.buildmap(aliases)
self._cache = {} # key: (func, data)
+ def overlaymap(self, origmapping, newmapping):
+ """Create combined mapping from the original mapping and partial
+ mapping to override the original"""
+ mapping = origmapping.copy()
+ mapping.update(newmapping)
+ return mapping
+
def symbol(self, mapping, key):
"""Resolve symbol to value or function; None if nothing found"""
v = None
@@ -202,8 +202,8 @@ def _showcompatlist(context, mapping, na
startname = 'start_' + plural
if context.preload(startname):
yield context.process(startname, mapping)
- vmapping = mapping.copy()
def one(v, tag=name):
+ vmapping = {}
try:
vmapping.update(v)
# Python 2 raises ValueError if the type of v is wrong. Python
@@ -216,6 +216,7 @@ def _showcompatlist(context, mapping, na
vmapping[a] = b
except (TypeError, ValueError):
vmapping[name] = v
+ vmapping = context.overlaymap(mapping, vmapping)
return context.process(tag, vmapping)
lastname = 'last_' + name
if context.preload(lastname):
@@ -399,10 +400,9 @@ def runmap(context, mapping, data):
raise error.ParseError(_("%r is not iterable") % d)
for i, v in enumerate(diter):
- lm = mapping.copy()
- lm['index'] = i
if isinstance(v, dict):
- lm.update(v)
+ lm = context.overlaymap(mapping, v)
+ lm['index'] = i
lm['originalnode'] = mapping.get('node')
yield evalrawexp(context, lm, targ)
else:
@@ -415,8 +415,7 @@ def runmember(context, mapping, data):
darg, memb = data
d = evalrawexp(context, mapping, darg)
if util.safehasattr(d, 'tomap'):
- lm = mapping.copy()
- lm.update(d.tomap())
+ lm = context.overlaymap(mapping, d.tomap())
return runsymbol(context, lm, memb)
if util.safehasattr(d, 'get'):
return getdictitem(d, memb)