471 lines
8.9 KiB
Markdown
471 lines
8.9 KiB
Markdown
# Configuration Reference
|
|
|
|
Comprehensive reference for jj configuration options, templates, filesets, and aliases.
|
|
|
|
## Table of Contents
|
|
|
|
- [Config Files](#config-files)
|
|
- [User Settings](#user-settings)
|
|
- [UI Settings](#ui-settings)
|
|
- [Aliases](#aliases)
|
|
- [Templates](#templates)
|
|
- [Filesets](#filesets)
|
|
- [Git Settings](#git-settings)
|
|
- [Signing](#signing)
|
|
|
|
## Config Files
|
|
|
|
jj loads configuration from multiple sources (in order of precedence):
|
|
|
|
1. **Built-in** - Cannot be edited
|
|
2. **User** - `~/.config/jj/config.toml` or `~/.jjconfig.toml`
|
|
3. **Repo** - `.jj/repo/config.toml`
|
|
4. **Workspace** - `.jj/workspace-config.toml`
|
|
5. **Command-line** - `--config key=value`
|
|
|
|
```bash
|
|
jj config path --user # Show user config path
|
|
jj config edit --user # Edit user config
|
|
jj config edit --repo # Edit repo config
|
|
jj config list # Show all config values
|
|
jj config get <key> # Get specific value
|
|
```
|
|
|
|
## User Settings
|
|
|
|
```toml
|
|
[user]
|
|
name = "Your Name"
|
|
email = "your@email.com"
|
|
```
|
|
|
|
## UI Settings
|
|
|
|
### Basic UI
|
|
|
|
```toml
|
|
[ui]
|
|
# Color output: always, never, auto, debug
|
|
color = "auto"
|
|
|
|
# Default command when running 'jj' with no args
|
|
default-command = "log"
|
|
# Or with arguments:
|
|
default-command = ["log", "--reversed"]
|
|
|
|
# Pager command
|
|
pager = "less -FRX"
|
|
|
|
# Editor for descriptions
|
|
editor = "vim"
|
|
|
|
# Diff format: :color-words, :git, :summary, :stat, :types, :name-only
|
|
diff-formatter = ":color-words"
|
|
|
|
# Movement commands (next/prev) edit instead of creating new commit
|
|
movement.edit = false
|
|
```
|
|
|
|
### Colors and Styles
|
|
|
|
```toml
|
|
[colors]
|
|
# Simple foreground color
|
|
commit_id = "green"
|
|
change_id = "magenta"
|
|
|
|
# Hex colors
|
|
bookmark = "#ff1525"
|
|
|
|
# Full style specification
|
|
commit_id = { fg = "green", bg = "black", bold = true }
|
|
change_id = { underline = true, italic = true }
|
|
|
|
# Combined labels (like CSS selectors)
|
|
"working_copy commit_id" = { underline = true }
|
|
"conflict description" = "red"
|
|
|
|
# Diff colors
|
|
"diff removed" = "red"
|
|
"diff added" = "green"
|
|
"diff removed token" = { bg = "#221111", underline = false }
|
|
"diff added token" = { bg = "#002200", underline = false }
|
|
```
|
|
|
|
### Diff Options
|
|
|
|
```toml
|
|
[diff.color-words]
|
|
# Max removed/added alternation to inline (-1 = all)
|
|
max-inline-alternation = 3
|
|
# Lines of context
|
|
context = 3
|
|
|
|
[diff.git]
|
|
context = 3
|
|
```
|
|
|
|
### External Diff Tools
|
|
|
|
```toml
|
|
[ui]
|
|
diff-formatter = ["difft", "--color=always", "$left", "$right"]
|
|
# Or reference a named tool:
|
|
diff-formatter = "difftastic"
|
|
|
|
[merge-tools.difftastic]
|
|
program = "difft"
|
|
diff-args = ["--color=always", "$left", "$right"]
|
|
diff-invocation-mode = "dir" # or "file-by-file"
|
|
```
|
|
|
|
## Aliases
|
|
|
|
### Command Aliases
|
|
|
|
```toml
|
|
[aliases]
|
|
# Simple alias
|
|
l = ["log", "-r", "@::"]
|
|
|
|
# Complex alias
|
|
show-tree = ["log", "-r", "@::", "--no-graph", "-T", "commit_id.short() ++ ' ' ++ description.first_line()"]
|
|
|
|
# External command (via util exec)
|
|
my-script = ["util", "exec", "--", "my-jj-script"]
|
|
|
|
# Inline script
|
|
format = ["util", "exec", "--", "bash", "-c", """
|
|
set -euo pipefail
|
|
jj fix
|
|
""", ""]
|
|
```
|
|
|
|
### Revset Aliases
|
|
|
|
```toml
|
|
[revset-aliases]
|
|
# Custom revsets
|
|
'wip' = 'description(exact:"") & mine()'
|
|
'stacked' = 'trunk()..@'
|
|
'recent' = 'ancestors(@, 20) & mine()'
|
|
'feature(x)' = 'bookmarks(glob:"feature-" ++ x ++ "*")::'
|
|
|
|
# Override built-in trunk() detection
|
|
'trunk()' = 'latest(remote_bookmarks(exact:"main", exact:"origin") | remote_bookmarks(exact:"master", exact:"origin"))'
|
|
|
|
# Customize immutable commits
|
|
'immutable_heads()' = 'trunk() | tags()'
|
|
```
|
|
|
|
### Template Aliases
|
|
|
|
```toml
|
|
[template-aliases]
|
|
# Custom formatting
|
|
'format_short_id(id)' = 'id.shortest(8)'
|
|
'format_timestamp(ts)' = 'ts.ago()'
|
|
|
|
# Custom commit format
|
|
'my_log' = '''
|
|
change_id.short() ++ " " ++
|
|
if(description, description.first_line(), "(no description)") ++
|
|
if(conflict, " CONFLICT", "")
|
|
'''
|
|
```
|
|
|
|
## Templates
|
|
|
|
Templates are a functional language for customizing output.
|
|
|
|
### Log Template
|
|
|
|
```toml
|
|
[templates]
|
|
log = 'builtin_log_oneline'
|
|
# Or custom:
|
|
log = '''
|
|
separate(" ",
|
|
format_short_change_id_with_hidden_and_divergent_info(self),
|
|
format_short_commit_id(commit_id),
|
|
bookmarks,
|
|
tags,
|
|
if(conflict, label("conflict", "conflict")),
|
|
if(empty, label("empty", "(empty)")),
|
|
if(description, description.first_line(), description_placeholder),
|
|
) ++ "\n"
|
|
'''
|
|
```
|
|
|
|
### Draft Description Template
|
|
|
|
```toml
|
|
[templates]
|
|
draft_commit_description = '''
|
|
concat(
|
|
builtin_draft_commit_description,
|
|
"\nJJ: ignore-rest\n",
|
|
diff.git(),
|
|
)
|
|
'''
|
|
|
|
[template-aliases]
|
|
default_commit_description = '''
|
|
"
|
|
|
|
Closes #NNNN
|
|
"
|
|
'''
|
|
```
|
|
|
|
### Commit Trailers
|
|
|
|
```toml
|
|
[templates]
|
|
commit_trailers = '''
|
|
format_signed_off_by_trailer(self)
|
|
++ if(!trailers.contains_key("Change-Id"), format_gerrit_change_id_trailer(self))
|
|
'''
|
|
```
|
|
|
|
### Template Syntax
|
|
|
|
```
|
|
# Literals
|
|
"string"
|
|
true / false
|
|
42
|
|
|
|
# Operators
|
|
x ++ y # Concatenate
|
|
x && y # Logical and
|
|
x || y # Logical or
|
|
!x # Logical not
|
|
x == y # Equality
|
|
|
|
# Conditionals
|
|
if(condition, then, else)
|
|
|
|
# Functions
|
|
separate(sep, items...) # Join non-empty with separator
|
|
concat(items...) # Join all items
|
|
coalesce(items...) # First non-empty
|
|
surround(prefix, suffix, content) # Wrap if non-empty
|
|
label(name, content) # Apply color label
|
|
indent(prefix, content) # Indent lines
|
|
fill(width, content) # Word wrap
|
|
```
|
|
|
|
### Commit Methods
|
|
|
|
Available in log/show templates:
|
|
|
|
```
|
|
self.commit_id()
|
|
self.change_id()
|
|
self.description()
|
|
self.author()
|
|
self.committer()
|
|
self.parents()
|
|
self.bookmarks()
|
|
self.tags()
|
|
self.working_copies()
|
|
self.conflict()
|
|
self.empty()
|
|
self.immutable()
|
|
self.divergent()
|
|
self.hidden()
|
|
self.mine()
|
|
self.contained_in(revset)
|
|
self.diff([fileset])
|
|
```
|
|
|
|
## Filesets
|
|
|
|
Filesets select files for commands like `jj diff`, `jj split`, `jj squash`.
|
|
|
|
### Patterns
|
|
|
|
```bash
|
|
# Path prefix (default)
|
|
jj diff src # Files under src/
|
|
|
|
# Exact file
|
|
jj diff 'file:README.md'
|
|
|
|
# Glob patterns
|
|
jj diff 'glob:*.rs' # .rs in current dir
|
|
jj diff 'glob:**/*.rs' # All .rs files
|
|
jj diff 'glob-i:*.TXT' # Case-insensitive
|
|
|
|
# Root-relative (from repo root)
|
|
jj diff 'root:src'
|
|
jj diff 'root-glob:**/*.rs'
|
|
```
|
|
|
|
### Operators
|
|
|
|
```bash
|
|
# Negation
|
|
jj diff '~Cargo.lock' # Everything except Cargo.lock
|
|
|
|
# Intersection
|
|
jj diff 'src & glob:**/*.rs' # Rust files in src/
|
|
|
|
# Difference
|
|
jj diff 'src ~ glob:**/*.rs' # Non-Rust files in src/
|
|
|
|
# Union
|
|
jj diff 'glob:*.rs | glob:*.toml'
|
|
```
|
|
|
|
### Functions
|
|
|
|
```bash
|
|
all() # All files
|
|
none() # No files
|
|
```
|
|
|
|
### Examples
|
|
|
|
```bash
|
|
# Diff excluding lock files
|
|
jj diff '~Cargo.lock'
|
|
|
|
# Split: put all except foo in first commit
|
|
jj split '~foo'
|
|
|
|
# List non-Rust files in src
|
|
jj file list 'src ~ glob:**/*.rs'
|
|
|
|
# Squash only specific files
|
|
jj squash 'glob:*.md'
|
|
```
|
|
|
|
## Git Settings
|
|
|
|
```toml
|
|
[git]
|
|
# Auto-local-bookmark for new remote bookmarks
|
|
auto-local-bookmark = true
|
|
|
|
# Default push/fetch remote
|
|
push = "origin"
|
|
fetch = "origin"
|
|
|
|
# Push bookmark naming template
|
|
push-bookmark-prefix = "push-"
|
|
|
|
# Private commits (won't be pushed)
|
|
private-commits = "description(glob:'wip:*')"
|
|
|
|
# Colocate by default
|
|
colocate = true
|
|
|
|
# Shallow clone depth
|
|
shallow-clone-depth = 0 # 0 = full clone
|
|
|
|
# Fetch tags
|
|
fetch-tags = "included" # all, included, none
|
|
|
|
# Abandon unreachable commits from remote
|
|
abandon-unreachable-commits = true
|
|
```
|
|
|
|
## Signing
|
|
|
|
```toml
|
|
[signing]
|
|
# Enable signing
|
|
sign-all = false
|
|
|
|
# Signing backend: gpg, ssh, none
|
|
backend = "gpg"
|
|
|
|
# GPG settings
|
|
[signing.backends.gpg]
|
|
program = "gpg"
|
|
# Allow expired keys
|
|
allow-expired-keys = false
|
|
|
|
# SSH settings
|
|
[signing.backends.ssh]
|
|
program = "ssh-keygen"
|
|
# Allowed signers file
|
|
allowed-signers = "~/.ssh/allowed_signers"
|
|
# Key to use
|
|
key = "~/.ssh/id_ed25519.pub"
|
|
```
|
|
|
|
## Immutable Commits
|
|
|
|
```toml
|
|
[revset-aliases]
|
|
# Default: trunk and tags are immutable
|
|
'immutable_heads()' = 'trunk() | tags()'
|
|
|
|
# More restrictive: only trunk
|
|
'immutable_heads()' = 'trunk()'
|
|
|
|
# Include release branches
|
|
'immutable_heads()' = 'trunk() | tags() | bookmarks(glob:"release-*")'
|
|
```
|
|
|
|
## Fix Tools (Formatters)
|
|
|
|
```toml
|
|
[fix.tools.rustfmt]
|
|
command = ["rustfmt", "--emit=stdout"]
|
|
patterns = ["glob:'**/*.rs'"]
|
|
|
|
[fix.tools.black]
|
|
command = ["black", "-", "--stdin-filename=$path"]
|
|
patterns = ["glob:'**/*.py'"]
|
|
|
|
[fix.tools.prettier]
|
|
command = ["prettier", "--stdin-filepath=$path"]
|
|
patterns = ["glob:'**/*.{js,ts,jsx,tsx,json,md}'"]
|
|
```
|
|
|
|
## Merge Tools
|
|
|
|
```toml
|
|
[merge-tools.meld]
|
|
program = "meld"
|
|
merge-args = ["$left", "$base", "$right", "-o", "$output"]
|
|
edit-args = ["$left", "$right"]
|
|
|
|
[merge-tools.vimdiff]
|
|
program = "vim"
|
|
merge-args = ["-d", "$left", "$base", "$right", "$output"]
|
|
merge-tool-edits-conflict-markers = true
|
|
|
|
[ui]
|
|
merge-editor = "meld"
|
|
diff-editor = ":builtin"
|
|
```
|
|
|
|
## Snapshot Settings
|
|
|
|
```toml
|
|
[snapshot]
|
|
# Max file size to track (bytes)
|
|
max-new-file-size = "1MiB"
|
|
|
|
# Auto-track patterns (default: all)
|
|
auto-track = "all()"
|
|
# Or selective:
|
|
auto-track = "glob:**/*.rs"
|
|
|
|
# Watchman integration
|
|
use-watchman = "if-available"
|
|
```
|
|
|
|
## Debug Settings
|
|
|
|
```toml
|
|
[debug]
|
|
# Randomize commit IDs (for testing)
|
|
randomness-seed = ""
|
|
```
|