# 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 # 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 = "" ```