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).
This maintains the previous behavior of expanding {latesttag} to a string
containing all of the tags, joined by ':'. But now it also allows list type
operations.
I'm unsure if the plural handling is correct (i.e. it seems like it is usually
"{foos % '{foo}'}"), but I guess we are stuck with this because the singular
form previously existed.
Archive is putting a value with the same name in the metadata file, to count all
of the changes not covered by the latest tag, instead of just along the longest
path. It seems that this would be useful to have on the command line as well.
It might be nice for the name to start with 'latesttag' so that it is grouped
with the other tag keywords, but I can't think of a better name.
The initial version of this counted a clean wdir() and '.' as the same value,
and a dirty wdir() as the same value after it is committed. Yuya objected on
the grounds of consistency [1]. Since revsets can be used to conditionally
select a dirty wdir() or '.' when clean, I can build the version string I need
and will defer to him on this.
[1] https://www.selenic.com/pipermail/mercurial-devel/2015-June/071588.html
This will be used in the next patch.
It also points out that the documentation for '{latesttag}' is not quite
accurate, since it says "most recent global tag" (singular). I assume it is too
radical of a change to convert it to a list of strings. At least ':' is
currently a reserved character in tag names.
Before this patch, template keywords `{file_mods}`, `{file_adds}` and
`{file_dels}` use values gotten by `repo.status(ctx.p1().node(),
ctx.node())`.
But this doesn't work as expected if `ctx` is `memctx` or
`workingcommitctx`. Typical case of templating with these contexts is
customization of the text shown in the commit message editor by
`[committemplate]` configuration.
In this case, `ctx.node()` returns None and it causes comparison
between `ctx.p1()` and `workingctx`. `workingctx` lists up all changed
files in the working directory even at selective committing.
BTW, `{files}` uses `ctx.files()` and it works as expected.
To compare target context and its parent exactly, this patch passes
`ctx.p1()` and `ctx` without `node()`-nize. This avoids unexpected
comparison with `workingctx`.
This patch uses a little redundant template configurations in
`test-commit.t`, but they are needed to avoid regression around
problems fixed by 17e2fda16f58 and 2b999bc2d89a: accessing on `ctx`
may break `ctx._status` field.
Previously, the template keyword '{activebookmark}' would only display the
active bookmark if it was also pointing to the working directory's parent.
Meanwhile, the '{active}' subkeyword of the '{bookmarks}' keyword displays
the active bookmark regardless of whether it also points to the working
directory's parent. This is confusing.
Consider the output of these two templates:
$ hg log -T '{activebookmark}\n' -r indent
$ hg log -T '{bookmarks % "{bookmark}"}\n' -r indent
indent
This is the current behavior that can arise after, eg, a pull moves a bookmark
out from under you. After this patch, the first template will also return the
active bookmark that points to a revision, even if it is not the current
parent of the working directory. A test has been added to show the new behavior.
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
Previously this function accepted two optional parameters that were unused by
any callers and complicated the function.
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
fffa7616be9d implies that the primary goal is to allow "{get(extras, key)}",
but it didn't work.
I'm not sure if _hybrid should forward all unknown attributes to values, so
only "get" is forwarded for now.
7678263f920c is fine for "{revset()}", but "i.values()[0]" does not work if
each item has more than one values such as "{bookmarks}".
This fixes the problem by using list.__contains__ or dict.__contains__
appropriately.