790 lines · 30.5 KB · Markdown
RawDownload

Templates

Jujutsu supports a functional language to customize output of commands. The language consists of literals, keywords, operators, functions, and methods.

A couple of jj commands accept a template via -T/--template option.

Keywords

Keywords represent objects of different types; the types are described in a follow-up section. In addition to context-specific keywords, the top-level object can be referenced as self.

Commit keywords

In jj log templates, all 0-argument methods of the Commit type are available as keywords. For example, commit_id is equivalent to self.commit_id().

Operation keywords

In jj op log templates, all 0-argument methods of the Operation type are available as keywords. For example, current_operation is equivalent to self.current_operation().

Operators

The following operators are supported. x and y below can be any expression.

Operators are listed in order of binding power from strongest to weakest, e.g. x ++ y * z is interpreted as x ++ (y * z) since * has stronger binding power than ++. Infix operators of the same binding power are parsed from left to right, e.g. x * y / z is interpreted as (x * y) / z.

As seen above, parentheses can be used to control evaluation order, e.g. (x + y) * z.

    • x.f(): Method call.
    • f(x): Function call.
    • -x: Negate integer value.
    • !x: Logical not.
    • p:x: String pattern or pattern alias named p.
    • x * y, x / y, x % y: Multiplication/division/remainder. Operands must be Integers.
    • x + y, x - y: Addition/subtraction. Operands must be Integers.
    • x >= y, x > y, x <= y, x < y: Greater than or equal/greater than/ lesser than or equal/lesser than. Operands must be Integers.
    • x == y, x != y: Equal/not equal. Operands must be either Boolean, Integer, or String.
    • x && y: Logical and, short-circuiting.
    • x || y: Logical or, short-circuiting.
    • x ++ y: Concatenate x and y templates.

Global functions

The following functions are defined.

  • fill(width: Integer, content: Template) -> Template: Fill lines at the given width.
  • indent(prefix: Template, content: Template) -> Template: Indent non-empty lines by the given prefix.
  • pad_start(width: Integer, content: Template, [fill_char: Template]): Pad (or right-justify) content by adding leading fill characters. The content shouldn't have newline character.
  • pad_end(width: Integer, content: Template, [fill_char: Template]): Pad (or left-justify) content by adding trailing fill characters. The content shouldn't have newline character.
  • pad_centered(width: Integer, content: Template, [fill_char: Template]): Pad content by adding both leading and trailing fill characters. If an odd number of fill characters are needed, the trailing fill will be one longer than the leading fill. The content shouldn't have newline characters.
  • truncate_start(width: Integer, content: Template, [ellipsis: Template]): Truncate content by removing leading characters. The content shouldn't have newline character. If ellipsis is provided and content was truncated, prepend the ellipsis to the result.
  • truncate_end(width: Integer, content: Template, [ellipsis: Template]): Truncate content by removing trailing characters. The content shouldn't have newline character. If ellipsis is provided and content was truncated, append the ellipsis to the result.
  • hash(content: Stringify) -> String: Hash the input and return a hexadecimal string representation of the digest.
  • label(label: Stringify, content: Template) -> Template: Apply a custom color label to the content. The label is evaluated as a space-separated string.
  • hyperlink(url: Stringify, text: Template, [fallback: Template]) -> Template: Render text as a hyperlink to url using OSC 8 escape sequences when outputting with color enabled. Otherwise, renders fallback instead, which defaults to text. Use --color=always to force hyperlinks when piping output to a terminal emulator that supports OSC 8.
  • raw_escape_sequence(content: Template) -> Template: Preserves any escape sequences in content (i.e., bypasses sanitization) and strips labels. Note: This function is intended for escape sequences and as such, its output is expected to be invisible / of no display width. Outputting content with nonzero display width may break wrapping, indentation etc.
  • stringify(content: Stringify) -> String: Format content to string. This effectively removes color labels.
  • json(value: Serialize) -> String: Serialize value in JSON format.
  • if(condition: Boolean, then: Any, [else: Any]) -> Any: Conditionally evaluates to then/else content.
  • coalesce(content: Template...) -> Template: Returns the first non-empty content.
  • concat(content: Template...) -> Template: Same as content_1 ++ ... ++ content_n.
  • join(separator: Template, content: Template...) -> Template: Insert separator between contents.
  • separate(separator: Template, content: Template...) -> Template: Insert separator between non-empty contents.
  • surround(prefix: Template, suffix: Template, content: Template) -> Template: Surround non-empty content with texts such as parentheses.
  • config(name: StringLiteral) -> Option<ConfigValue>: Look up configuration value by name.
  • git_web_url([remote: String]) -> String: Best-effort conversion of a git remote URL to an HTTPS web URL. Defaults to the "origin" remote. Returns an empty string on failure. SSH host alias resolution is currently unsupported.

Types

AnnotationLine type

Conversion: Boolean: no, Serialize: no, Template: no

The following methods are defined.

  • .commit() -> Commit: Commit responsible for changing the relevant line.
  • .content() -> Template: Line content including newline character.
  • .line_number() -> Integer: 1-based line number.
  • .original_line_number() -> Integer: 1-based line number in the original commit.
  • .first_line_in_hunk() -> Boolean: False when the directly preceding line references the same commit.

Any type

Conversion: Boolean: no, Serialize: maybe, Template: maybe

All types can be implicitly converted to Any. No methods are defined.

AnyList type

Conversion: Boolean: no, Serialize: maybe, Template: maybe

The following methods are defined.

  • .join(separator: Template) -> Template: Concatenate elements with the given separator.

Boolean type

Conversion: Boolean: yes, Serialize: yes, Template: yes

No methods are defined. Can be constructed with false or true literal.

ChangeId type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .normal_hex() -> String: Normal hex representation (0-9a-f) instead of the canonical "reversed" (z-k) representation.
  • .short([len: Integer]) -> String
  • .shortest([min_len: Integer]) -> ShortestIdPrefix: Shortest unique prefix.

Commit type

Conversion: Boolean: no, Serialize: yes, Template: no

This type cannot be printed. The following methods are defined.

  • .description() -> String: Usually ends with a trailing \n, if non-blank.
  • .trailers() -> List<Trailer>: The trailers at the end of the commit description that are formatted as <key>: <value>. These are returned in the same order as they appear in the description, and there may be multiple Trailers with the same key.
  • .change_id() -> ChangeId
  • .commit_id() -> CommitId
  • .parents() -> List<Commit>
  • .author() -> Signature
  • .committer() -> Signature
  • .signature() -> Option<CryptographicSignature>: Cryptographic signature if the commit was signed.
  • .mine() -> Boolean: Commits where the author's email matches the email of the current user.
  • .working_copies() -> List<WorkspaceRef>: For multi-workspace repositories, returns a list of workspace references for each workspace whose working-copy commit matches the current commit.
  • .current_working_copy() -> Boolean: True for the working-copy commit of the current workspace.
  • .bookmarks() -> List<CommitRef>: Local and remote bookmarks pointing to the commit. A tracked remote bookmark will be included only if its target is different from the local one.
  • .local_bookmarks() -> List<CommitRef>: All local bookmarks pointing to the commit.
  • .remote_bookmarks() -> List<CommitRef>: All remote bookmarks pointing to the commit.
  • .tags() -> List<CommitRef>: Local and remote tags pointing to the commit. A tracked remote tag will be included only if its target is different from the local one.
  • .local_tags() -> List<CommitRef>: All local tags pointing to the commit.
  • .remote_tags() -> List<CommitRef>: All remote tags pointing to the commit.
  • .divergent() -> Boolean: True if the commit's change ID corresponds to multiple visible commits.
  • .hidden() -> Boolean: True if the commit is not visible (a.k.a. abandoned).
  • .change_offset() -> Option<Integer>: The change offset of this commit. May not be available for some commits.
  • .immutable() -> Boolean: True if the commit is included in the set of immutable commits.
  • .contained_in(revset: StringLiteral) -> Boolean: True if the commit is included in the provided revset.
  • .conflict() -> Boolean: True if the commit contains merge conflicts.
  • .empty() -> Boolean: True if the commit modifies no files.
  • .diff([files: StringLiteral]) -> TreeDiff: Changes from the parents within the files expression. All files are compared by default, but it is likely to change in future version to respect the command line path arguments.
  • .files([files: StringLiteral]) -> List<TreeEntry>: Files that exist in this commit, matching the files expression. Use .diff().files() to list changed files.
  • .conflicted_files() -> List<TreeEntry>: Conflicted files in this commit.
  • .root() -> Boolean: True if the commit is the root commit.

CommitEvolutionEntry type

Conversion: Boolean: no, Serialize: yes, Template: no

This type cannot be printed. The following methods are defined.

  • .commit() -> Commit: New commit.
  • .operation() -> Operation: Operation where the commit was created or rewritten.
  • .predecessors() -> List<Commit>: Predecessor commits of this entry.
  • .inter_diff([files: StringLiteral]) -> TreeDiff: Changes between this commit and its predecessor version(s), rebased onto the parents of this commit to avoid unrelated changes (similar to jj evolog -p).

CommitId type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .short([len: Integer]) -> String
  • .shortest([min_len: Integer]) -> ShortestIdPrefix: Shortest unique prefix.

CommitRef type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .name() -> RefSymbol: Local bookmark or tag name.
  • .remote() -> Option<RefSymbol>: Remote name if this is a remote ref.
  • .present() -> Boolean: True if the ref points to any commit.
  • .conflict() -> Boolean: True if the bookmark or tag is conflicted.
  • .normal_target() -> Option<Commit>: Target commit if the ref is not conflicted and points to a commit.
  • .removed_targets() -> List<Commit>: Old target commits if conflicted.
  • .added_targets() -> List<Commit>: New target commits. The list usually contains one "normal" target.
  • .tracked() -> Boolean: True if the ref is tracked by a local ref. The local ref might have been deleted (but not pushed yet.)
  • .tracking_present() -> Boolean: True if the ref is tracked by a local ref, and if the local ref points to any commit.
  • .tracking_ahead_count() -> SizeHint: Number of commits ahead of the tracking local ref.
  • .tracking_behind_count() -> SizeHint: Number of commits behind of the tracking local ref.
  • .synced() -> Boolean: For a local bookmark, true if synced with all tracked remotes. For a remote bookmark, true if synced with the tracking local bookmark.

ConfigValue type

Conversion: Boolean: no, Serialize: yes, Template: yes

This type can be printed in TOML syntax. The following methods are defined.

  • .as_boolean() -> Boolean: Extract boolean.
  • .as_integer() -> Integer: Extract integer.
  • .as_string() -> String: Extract string. This does not convert non-string value (e.g. integer) to string.
  • .as_string_list() -> List<String>: Extract list of strings.

CryptographicSignature type

Conversion: Boolean: no, Serialize: no, Template: no

The following methods are defined.

  • .status() -> String: The signature's status ("good", "bad", "unknown", "invalid").
  • .key() -> String: The signature's key id representation (for GPG and SSH, this is the public key fingerprint).
  • .display() -> String: The signature's display string (for GPG, this is the formatted primary user ID; for SSH, this is the principal).

!!! warning

Calling any of `.status()`, `.key()`, or `.display()` is slow, as it incurs
the performance cost of verifying the signature (for example shelling out
to `gpg` or `ssh-keygen`). Though consecutive calls will be faster, because
the backend caches the verification result.

!!! info

As opposed to calling any of `.status()`, `.key()`, or `.display()`,
checking for signature presence through boolean coercion is fast:
```
if(commit.signature(), "commit has a signature", "commit is unsigned")
```

DiffStatEntry type

Conversion: Boolean: no, Serialize: no, Template: no

This type holds the diff stats per file. The following methods are defined.

  • .bytes_delta() -> Integer: The difference in size of the file, in bytes.
  • .lines_added() -> Integer: Number of lines added.
  • .lines_removed() -> Integer: Number of lines deleted.
  • .path() -> RepoPath: Path to the entry. If the entry is a copy/rename, this points to the target (or right) entry.
  • .display_diff_path() -> String: Format path for display, taking into account copy/rename information.
  • .status() -> String: One of "modified", "added", "removed", "copied", or "renamed".
  • .status_char() -> String: One of "M" (modified), "A" (added), "D" (removed), "C" (copied), or "R" (renamed).

DiffStats type

Conversion: Boolean: no, Serialize: no, Template: yes

This type can be printed as a histogram of the changes. The following methods are defined.

  • .files() -> List<DiffStatEntry>: Per-file stats for changed files.
  • .total_added() -> Integer: Total number of insertions.
  • .total_removed() -> Integer: Total number of deletions.

Email type

Conversion: Boolean: yes, Serialize: yes, Template: yes

The email field of a signature may or may not look like an email address. It may be empty, may not contain the symbol @, and could in principle contain multiple @s.

The following methods are defined.

  • .local() -> String: the part of the email before the first @, usually the username.
  • .domain() -> String: the part of the email after the first @ or the empty string.

Integer type

Conversion: Boolean: no, Serialize: yes, Template: yes

No methods are defined.

List type

Conversion: Boolean: yes, Serialize: maybe, Template: maybe

A list can be implicitly converted to Boolean. The following methods are defined.

  • .len() -> Integer: Number of elements in the list.
  • .join(separator: Template) -> Template: Concatenate elements with the given separator.
  • .filter(|item| expression) -> List: Filter list elements by predicate expression. Example: description.lines().filter(|s| s.contains("#"))
  • .map(|item| expression) -> AnyList: Apply template expression to each element. Example: parents.map(|c| c.commit_id().short())
  • .any(|item| expression) -> Boolean: Returns true if any element satisfies the predicate expression. Example: parents.any(|c| c.description().contains("fix"))
  • .all(|item| expression) -> Boolean: Returns true if all elements satisfy the predicate expression. Example: parents.all(|c| c.mine())
  • .first() -> T: Returns the first element. Errors if the list is empty.
  • .last() -> T: Returns the last element. Errors if the list is empty.
  • .get(index: Integer) -> T: Returns the element at index (0-based). Errors if the index is out of bounds.
  • .reverse() -> List: Returns the list in reverse order.
  • .skip(count: Integer) -> List: Skips the first count elements and returns the rest.
  • .take(count: Integer) -> List: Returns only the first count elements.

List<Trailer> type

The following methods are defined. See also the List type.

  • .contains_key(key: Stringify) -> Boolean: True if the commit description contains at least one trailer with the key key.

Operation type

Conversion: Boolean: no, Serialize: yes, Template: no

This type cannot be printed. The following methods are defined.

  • .current_operation() -> Boolean
  • .description() -> String
  • .id() -> OperationId
  • .tags() -> String
  • .time() -> TimestampRange
  • .user() -> String
  • .snapshot() -> Boolean: True if the operation is a snapshot operation.
  • .root() -> Boolean: True if the operation is the root operation.
  • .parents() -> List<Operation>

OperationId type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .short([len: Integer]) -> String

Option type

Conversion: Boolean: yes, Serialize: maybe, Template: maybe

An option can be implicitly converted to Boolean denoting whether the contained value is set. If set, all methods of the contained value can be invoked. If not set, an error will be reported inline on method call.

On comparison between two optional values or optional and non-optional values, unset value is not an error. Unset value is considered less than any set values.

RefSymbol type

Conversion: Boolean: no, Serialize: yes, Template: yes

A String type, but is formatted as revset symbol by quoting and escaping if necessary. Unlike strings, this cannot be implicitly converted to Boolean.

RepoPath type

Conversion: Boolean: no, Serialize: yes, Template: yes

A slash-separated path relative to the repository root. The following methods are defined.

  • .absolute() -> String: Format as absolute path using platform-native separator.
  • .display() -> String: Format path for display. The formatted path uses platform-native separator, and is relative to the current working directory.
  • .parent() -> Option<RepoPath>: Parent directory path.

Serialize type

An expression that can be serialized in machine-readable format such as JSON.

!!! note

Field names and value types in the serialized output are usually stable
across jj versions, but the backward compatibility isn't guaranteed. If the
underlying data model is updated, the serialized output may change.

ShortestIdPrefix type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .prefix() -> String
  • .rest() -> String
  • .upper() -> ShortestIdPrefix
  • .lower() -> ShortestIdPrefix

Signature type

Conversion: Boolean: no, Serialize: yes, Template: yes

The following methods are defined.

  • .name() -> String
  • .email() -> Email
  • .timestamp() -> Timestamp

SizeHint type

Conversion: Boolean: no, Serialize: yes, Template: no

This type cannot be printed. The following methods are defined.

  • .lower() -> Integer: Lower bound.
  • .upper() -> Option<Integer>: Upper bound if known.
  • .exact() -> Option<Integer>: Exact value if upper bound is known and it equals to the lower bound.
  • .zero() -> Boolean: True if upper bound is known and is 0. Equivalent to

Lines 1–500 of 790.