2.4 KiB
2.4 KiB
JJ Templating Language
Source: https://docs.jj-vcs.dev/latest/templates/
Use templates only when plain jj log output is insufficient: machine-readable output, conditional formatting, scripting pipelines.
Invocation
jj log -r @ --template '...' # Single commit
jj log -r 'trunk()..@' --template '...' # Range
jj log --no-pager --template '...' | jq ... # Pipe to tools
Commit Fields
| Field | Description |
|---|---|
commit_id / .short() |
Full/short commit id |
change_id / .short() |
Change identity |
description / subject |
Full message / first line |
author.email / author.name |
Author metadata |
timestamp |
Commit timestamp |
bookmarks / tags |
Lists |
conflict |
Boolean |
is_empty |
Boolean |
divergent |
Boolean |
parents |
List of parent commits |
Functions
| Function | Example |
|---|---|
format() |
format("[", change_id.short(), "] ", subject) |
if(cond, a, b) |
if(conflict, "⚠", "") |
short() |
commit_id.short() |
json() |
author.email.json() |
contains() |
subject.contains("WIP") |
truncate(n) |
description.truncate(80) |
indent(n) |
description.indent(4) |
join() |
bookmarks.join(", ") |
map() / filter() |
bookmarks.map(lower()) |
len() |
parents.len() |
Chaining: bookmarks.filter(!contains("WIP")).map(lower()).join(" ")
Examples
# Minimal
change_id.short() " " subject
# WIP emphasis
format(if(subject.contains("WIP"),"[WIP] ",""), change_id.short(), " ", subject)
# Conflicts
format(if(conflict,"⚠ ",""), change_id.short(), " ", subject)
# Bookmarks
format(change_id.short()," ",bookmarks.join(",")," ",subject)
# JSON output
format(
'{"change":"', change_id.short().json(), '",',
'"author":"', author.email.json(), '",',
'"conflict":', if(conflict, 'true','false'), '}'
)
Revset + Template
# Divergent heads with conflicts
jj log -r 'heads(all()) & conflicts()' --template 'format(change_id.short()," ",subject)'
# Commits ahead of remote
jj log -r 'myfeature - myfeature@origin' --template 'format("AHEAD ", change_id.short())'
Pitfalls
| Issue | Fix |
|---|---|
| Unescaped quotes in JSON | Use .json() on dynamic fields |
| Slow on huge histories | Narrow revset first |
| Complex templates | Build incrementally with format() |