The primary benefit of this change is that it splits
"lines_added()" and "lines_removed()" into separate fields,
which will be useful for tools.
Many tools use "status()", "lines_added()", "lines_removed()",
"source()" and "target()" to show useful information about
every file modified in a commit.
The existing diff stats summary shows only the combined
number of lines modified, along with a "percentage" representation
of line additions vs. deletions. This is lossy and not
useful for tools, since it is impossible to arrive at
the exact number of lines added and deleted.
Since we can now update tags internally, local and remote tags may be out of
sync in non-colocated Git repositories. "tags" template should indicate that.
Functionality remains the same; this only affects the docs. This change
points users to supported formats for the `Timestamp.after()` and
`Timestamp.before()` methods, which can already be found in the revset
"Date pattern" type.
Remote names are potentially sensitive? Unsure, so better to redact them.
For getting the "*": This could have been done without modifying the
Rust side, with e.g. `stringify(bookmark).ends_with("*")`. However, this
feels brittle.
With adding `.synced()` to the template language, bookmark formatting
_could_ be done entirely in templates now. I don't know if that's
desired, so leaving for a potential future commmit.
This is a basic implementation of the same string pattern system as in
the revset language. It's currently only used for `string.matches`, so
you can now do:
```
"foo".matches(regex:'[a-f]o+')
```
In the future this could be added to more string functions (and e.g.
the ability to parse things out of strings could be added).
CC: https://github.com/jj-vcs/jj/issues/6893
We could instead implement serde::Serialize wrapper manually, but it would be
tedious to process recursive data structure. Let's just rely on the toml crate.
The cost of conversion wouldn't matter.
This patch doesn't add builtin_evolog_redacted template because I'm not sure if
we want to collect evolution log for debugging purpose. The redacted template
can be added later if needed.
I don't have a strong feeling whether we should add "entry.commit() -> Commit"
method or forward method calls to the Commit object, but this patch implements
the former because:
a. evolution_entry.diff() should return inter diff, whereas commit.diff()
doesn't.
b. auto-labeling works if self.commit() is an explicit method call.
c. the implementation and documentation can be simple.
Tests will be added by the next patch.
This allows checking whether "any" or "all" elements in a list satisfy a given
predicate, similar to Python's native `any()` and `all()` functions, but
instead as list methods that take lambda predicates.
These new methods follow the same pattern as existing `filter` and `map`
operations, i.e. taking a lambda that receives each item and must return a
boolean.
I was initially planning to try adding an `nth` keyword argument to
`parents()` instead of adding `first_parent()`, and I noticed that based
on the current style, it would have been shown as one of the following
in the revset documentation:
* `parents(x[, depth[, [nth=]index]])`
* `parents(x[, depth][, [nth=]index])`
These both seem difficult to read to me, so I'm proposing changing the
style to something more like this:
* `parents(x, [depth], [[nth=]index])`
I also added a brief section explaining the syntax in case it isn't
immediately obvious what the square brackets mean.
I think this can be useful in CLI tests. I noticed there are lots of "jj file
list" calls in https://github.com/jj-vcs/jj/pull/6141 which could be combined
with "jj log" outputs.
Add a parents() method for `Operation` template objects, copied from the
implementation for `Commit`s.
The test case added in test_operations.rs was heavily inspired by
test_commit_templates.rs:test_log_parents().
Fixes#6979
Since the goal of this pseudo type is to get a String value, it can be called a
ToString or Stringify. I chose the latter because Stringify sounds similar to
Serialize (verb), and I don't want to rename the internal functions to
.try_into_to_string().
https://github.com/jj-vcs/jj/pull/6840#discussion_r2173076763
This was discussed in #3219 and #3262, and apparently, people don't agree
whether we should implement machine-readable formatting by using templater.
However, there are recurring requests about JSON output, and "jj api" is still
vaporware. So I think it's good to add some support for JSON output.
I'm not going to add syntax to build custom JSON object/list for now. Instead,
property types such as Commit will implement fixed serialization output. The
user might have to write ad-hoc JSON constructs to concatenate the default JSON
output and their custom JSON fields.
We'll need a documentation about which types are serializable. I think this can
be added later when more types get serialization support.
This is the last part of the series 02722eae54 "view: port bookmark/tag name
types to RefName/RemoteName." Templater doesn't use these name types internally
because we wouldn't gain much type safety in template language.
The return type of .remote() is changed to Option<RefSymbol>. An empty symbol is
rendered with quotes, so it would be weird if local_bookmark.remote() returned
an empty RefSymbol.
I'm going to add RefSymbol(String) type to format bookmark/remote name in revset
syntax. Since an empty symbol will be rendered differently from an empty string,
bookmark.remote() -> String will be changed to -> Option<RefSymbol>. Then, we'll
need to add support for comparison between optional and non-optional values.
In template language, method call on None produces an error. If we followed this
rule, comparison would have to be expressed as `opt && opt == lit`. I feel this
would be too verbose, and wouldn't help eliminate user error caused by
unintended comparison between Option<T> and T anyway. So this patch implements
comparison by lifting T to Option<T> implicitly.
In docs/templates.md, the Commit type and Operation type looked like:
`method() -> ReturnType`
rather than everything else, which looks like:
`.method() -> ReturnType`
This commit changes the Commit and Operation types to look more like the
rest of the documentation.
I'm thinking of adding RefName(str) and RemoteName(str) newtypes, and the
templater type name would conflict with that. Since the templater RefName type
is basically a (name, target) pair, I think it should be called a "Ref", and I
added "Commit" prefix for disambiguation.
This isn't a breaking change since template type names only appear in docs and
error messages.
Allows:
* self.commit()
* self.line_number()
* self.first_line_in_hunk()
Certain pagers (like `delta`), when used for `git blame`, only show the
commit information for the first line in a hunk. This would be a nice
addition to `jj file annotate`.
`jj file annotate` already uses a template to control the rendering of
commit information --- `templates.annotate_commit_summary`. Instead of
a custom CLI flag, the tools necessary to do this should be available in
the template language.
If `1 % 2` or `1.is_even()` was available in the template language, this
would also allow alternating colors (using `raw_escape_sequence`).
Example:
```toml
[templates]
# only show commit info for the first line of each hunk
annotate_commit_summary = '''
if(first_line_in_hunk,
show_commit_info(commit),
pad_end(20, " "),
)
'''
```