diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -504,6 +504,10 @@ class templateresources(templater.resour 'ui': ui, } + def availablekeys(self, context, mapping): + return {k for k, g in self._gettermap.iteritems() + if g(self, context, mapping, k) is not None} + def knownkeys(self): return self._knownkeys diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -563,6 +563,10 @@ class resourcemapper(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod + def availablekeys(self, context, mapping): + """Return a set of available resource keys based on the given mapping""" + + @abc.abstractmethod def knownkeys(self): """Return a set of supported resource keys""" @@ -571,6 +575,9 @@ class resourcemapper(object): """Return a resource for the key if available; otherwise None""" class nullresourcemapper(resourcemapper): + def availablekeys(self, context, mapping): + return set() + def knownkeys(self): return set() @@ -616,10 +623,23 @@ class engine(object): def overlaymap(self, origmapping, newmapping): """Create combined mapping from the original mapping and partial mapping to override the original""" - mapping = origmapping.copy() + # do not copy symbols which overrides the defaults depending on + # new resources, so the defaults will be re-evaluated (issue5612) + knownres = self._resources.knownkeys() + newres = self._resources.availablekeys(self, newmapping) + mapping = {k: v for k, v in origmapping.iteritems() + if (k in knownres # not a symbol per self.symbol() + or newres.isdisjoint(self._defaultrequires(k)))} mapping.update(newmapping) return mapping + def _defaultrequires(self, key): + """Resource keys required by the specified default symbol function""" + v = self._defaults.get(key) + if v is None or not callable(v): + return () + return getattr(v, '_requires', ()) + def symbol(self, mapping, key): """Resolve symbol to value or function; None if nothing found""" v = None diff --git a/tests/test-identify.t b/tests/test-identify.t --- a/tests/test-identify.t +++ b/tests/test-identify.t @@ -63,6 +63,16 @@ test template keywords and functions whi $ hg id -T '{parents % "{rev} {node|shortest} {desc}\n"}' 0 cb9a a +test nested template: '{tags}'/'{node}' constants shouldn't override the +default keywords, but '{id}' persists because there's no default keyword +for '{id}' (issue5612) + + $ hg id -T '{tags}\n' + tip + $ hg id -T '{revset("null:.") % "{rev}:{node|short} {tags} {id}\n"}' + -1:000000000000 cb9a9f314b8b + 0:cb9a9f314b8b tip cb9a9f314b8b + with modifications $ echo b > a