Files
gh-towry-dots-conf-claude-l…/skills/git-jj/references/jj_template.md
2025-11-30 09:02:31 +08:00

87 lines
2.4 KiB
Markdown

# 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
```bash
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
```bash
# 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
```bash
# 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()` |