It seemed silly to convert ctx.hex() back to binary to use node.hex/short(),
or to use [:12] instead of node.short() because ctx.node() could be None.
Eventually I want to change wctx.rev() and wctx.node() to return wdirrev and
wdirid respectively, but that's quite big API breakage and can't be achieved
without some compatibility wrappers.
This makes it slightly easier to sort basectx objects by key=scmutil.intrev.
We're most likely to have ctx objects where changectx/workingctx abstraction
is necessary, so this won't increase the abstraction overhead.
See the previous commit for why.
splitlines() does not pass a mapping dict, which would probably mean the
legacy template didn't work from the beginning.
This is convenient for new template keyword, which doesn't need to support
the legacy list hack (provided by _showlist()), but still wants to have
a string representation.
The goal is to fix "{hybrid_obj|json}" output.
A _hybrid object must act as a list or a dict as well as a generator of
legacy template strings. Before, _hybrid.__iter__() was assigned for legacy
template, which conflicted with list.__iter__() API.
This patch drops _hybrid.__iter__() and makes stringify/flatten functions
unwrap a generator instead.
My initial expectation was that the list would be empty, and therefore
detectable with {if()}. The map for {latesttag()} is populated with real values
in this case (except {tag}), so it probably doesn't make any sense to change
this to an empty list.
This was originally written for JSON templating where we would have to be
careful to not add extra comma, but seems generally useful.
Inner loop started by % operator has its own counter.
Since extras may contain blob, the default template escapes its values:
'extra': '{key}={value|stringescape}'
join() should follow the output style of the default template.
These templates are used when rendering inner lists of some template keywords,
so it makes sense to define them in templatekw. This allows us to reuse them
to create a templateformatter knowing changectx.
The result of diffstatdata should not depend on having noprefix set or not, as
was reported in issue 4755. Forcing noprefix to false on call makes sure the
parser receives the diff in the correct format and returns the proper result.
Another way to fix this would have been to change the regular expressions in
path.diffstatdata(), but that would have introduced many unecessary special
cases.
The "troubles" template keyword returns a list of evolution troubles.
It is EXPERIMENTAL, as anything else related to changeset evolution.
Test it in test-obsolete.t which has troubled changesets.
Now that all the functionality has been moved to manifestlog/manifestrevlog/etc,
we can finally change all the uses of repo.manifest to use the new versions. A
future diff will then delete repo.manifest.
One additional change in this commit is to change repo.manifestlog to be a
@storecache property instead of @property. This is required by some uses of
repo.manifest require that it be settable (contrib/perf.py and the static http
server). We can't do this in a prior change because we can't use @storecache on
this until repo.manifest is no longer used anywhere.
We've fixed several bugs caused by the misuse of the default joinfmt. Make
it more explicit to prevent future bugs.
dict.values()[0] is replaced by dict[element] as showlist() knows what the
key is.
Since the default joinfmt() can't process a dict of multiple keywords, we
need a dedicated joinfmt for showparents().
Unlike revset(), parents are formatted as '{rev}:{node|formatnode}' by default.
We copy the default formatting just like showextras() and showfilecopies() do.
It's been broken since eef3c19484ca, which made makemap() return a dict of
multiple keywords. Because the default joinfmt() randomly picks one item
from a dict, we have to make revset() select d[name] explicitly.
Using decorator can localize changes for adding (or removing) a
template keyword function in source code.
This patch also removes leading ":KEYWORD:" part in help document of
each keywords, because using templatekeyword makes it useless.
For similarity to decorator introduced by subsequent patches, this
patch uses 'templatekeyword' instead of 'keyword' as a decorator name,
even though the former is a little redundant in 'templatekw.py'.
file name reason
=================== ================= ==================================
templatekw.py templatekeyword for similarity to others
templatefilters.py templatefilter 'filter' hides Python built-in one
templaters.py templatefunc 'func' is too generic
_templateregistrarbase is defined as a super class of templatekeyword,
for ease of adding template common features between "keyword",
"filter" and "function".
This patch also adds loadkeyword() to templatekw, because this
combination helps to figure out how they cooperate with each other.
Listing up loadkeyword() in dispatch.extraloaders causes implicit
loading template keyword functions at loading (3rd party) extension.
This change requires that "templatekeyword" attribute of (3rd party)
extension is registrar.templatekeyword or so.
This is the same semantics as revset() introduced at eef3c19484ca. Before
this patch, {parents} provided nothing useful in new-style template. For
example, '{parents % "{parent}"}' generated cryptic string like
"rev12345node0123abcdef...".
This patch drops {parent} variable since it was useless. We can get a revision
number by '{parents % "{rev}"}'.
Because templater.revset() returns a list of strings, repo["-1"] was mapped to
the tipmost revision. Ideally, we should make revset() return a list of integer
revisions, but it turned out not simple. If revset() is a list of integers,
"{ifcontains(rev, revset(), ...)}" would fail because "ifcontains" casts "rev"
to a string.
So this patch just converts a string back to an integer revision.
This provides a general-purpose interface to all custom namespaces.
The {namespaces} keyword honors the definition order of namespaces as they
are kept by sortdict.
In templater, a callable symbol exists for lazy evaluation, which should have
f(**mapping) signature. On the other hand, _hybrid.__call__(), which was
introduced by 4e182fb53989, generates mapping for each element.
This patch renames _hybrid.__call__() to _hybrid.itermaps() so that a _hybrid
object can be a value of a mapping dict.
{namespaces % "{namespace}: {names % "{name }"}\n"}
~~~~~
a _hybrid object
This mitigates the minor perf regression introduced by the previous patch.
% hg log -G -R mozilla-central -l10000 --time > /dev/null
(original) real 2.200 secs
(previous) real 2.590 secs
(this) real 2.280 secs
This provides a default node symbol. Tests will be added later.
"showparents" variable is renamed to "wpnodes" to avoid confusion with the
existing showparents() function.
The keywords {changes}, {distance} and {tag} will be available on a future
template method that will allow pattern matching against tag names. For
consistency, these should be available on the existing {latesttag} keyword as
well.
I debated whether or not to add {tag} instead of just continuing with the
existing {latesttag}. But it seems clearer not to have the same name for two
distinct things (a list in the LHS of %, and an individual tag value on the
right).
The value of latesttags[0] is the date of commit for the cset to which the tag
is applied (i.e. not the date the tag was applied), and therefore isn't made
visible because it doesn't seem interesting. It appears that this is merely an
internal implementation detail for sorting csets in a stable manner when there
are different branches.
This will allow the latest class of tag to be found, such as a release candidate
or final build, instead of just the absolute latest. It will be exposed in a
future patch.
It's unfortunate that the original 'latesttags' cache can't be used to determine
the proper values, but it isn't fully populated for the entire repo. For
example, the {latesttagdistance} keyword on the Mecurial repo builds the cache
up back to the revision for 1.4. If the pattern was 're:^0\.\d$', that wouldn't
be in the cache. Maybe this can be optimized some other way, but for now, this
is the simpliest implementation.
It isn't cool, but we can peek at ui flag via repo.ui. So, it is possible
to implement showparents() in templatekw, and therefore we can eliminate the
dockeywords hack.
Because revset() function generates a list of revisions, it seems sensible
to switch the ctx as well where a list expression will be evaluated. I think
"{revset(...) % "..."}" expression wasn't considered well when it was
introduced at 45e0e191755f.
wdirrev/wdirnode identifiers are still experimental, but {node} is mapped to
wdirnode. So {rev} should do the same for consistency.
I'm not sure if templatekw can import scmutil. If not, we should move intrev()
to node module.
This will prevent crash by "hg log -r 'wdir()' -Tdefault". We could use the
pseudo ff... hash introduced by 187c3ec3d83f, but it isn't proven idea yet.
For now, I want to make "hg log" just works in order to test 'wdir()' revset.
Note that unlike its name, "{manifest}" is not a list of files in that
revision, but a pair of (manifestrev, manifestnode).