Initial commit
This commit is contained in:
86
skills/git-jj/references/jj_template.md
Normal file
86
skills/git-jj/references/jj_template.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# 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()` |
|
||||
Reference in New Issue
Block a user