---
schema_version: 1
route: /t/jj.md
tool: "jj"
---

# sincecutoff.com /t/jj — Jujutsu

- name: Jujutsu
- kind: cli
- children: none
- homepage: <https://jj-vcs.dev/>

Changes to the tools coding agents drive, since a model's training cutoff, each linked to its first-party source. Check installed versions and limitations before acting; a cutoff date does not establish what a model knows.
Original editorial content: [Apache 2.0](https://sincecutoff.com/v1/data-license.txt), by [0xPatrick](https://0xpatrick.dev). Preserve applicable license and [NOTICE](https://sincecutoff.com/notice.txt) attribution when redistributing. Third-party source text and examples retain their own rights. [License scope and attribution](https://sincecutoff.com/v1/license.json).
To stay current, read the changes feed: [`/v1/changes.md?tool=jj`](https://sincecutoff.com/v1/changes.md?tool=jj) (or `.json`), adding `since=YYYY-MM-DD` for your training cutoff. Entries for registered children are included; the registry itself is `/v1/tools.json`. How to page and save your place: [llms.txt](https://sincecutoff.com/llms.txt).

### jj aliases can be disabled by configuration (2026-10-07)
- slug: jj-aliases-can-be-disabled-by-configuration-3b52a6354722
- score: 0.95

How to use it:

When an alias should be unavailable, set `aliases.<name>.enabled` to `false` in a configuration layer. This can disable built-in aliases or aliases defined in earlier layers, including repository configuration.

Examples:

```
[aliases]
<name>.enabled = false
```

- why_it_matters: Disable a built-in alias or an alias defined in a later configuration layer.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://jj-vcs.github.io/jj/latest/config/>
- gotchas: "Version: v0.46.0"; "aliases.<name>.enabled (required): Set to `false` to disable the alias. Applies only to the `aliases` table; another configuration file may define the alias again later."; "This setting can disable built-in aliases and aliases in later layers, such as repository config files."

### jj file edit and delete modify files in any revision (2026-10-07)
- slug: jj-file-edit-and-delete-modify-files-in-any-revision-fe96070ab338
- score: 0.98

How to use it:

When editing or deleting a file in a revision, use `jj file edit` or `jj file delete` with the target path; both default to revision `@`, and descendants are rebased after the commit is rewritten.

Examples:

```
jj file edit --revision <REVSET> <FILE>
```

```
jj file delete --revision <REVSET> <FILESET>
```

- why_it_matters: Edit or delete a file in a revision without changing the working copy.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://github.com/jj-vcs/jj/blob/v0.46.0/cli/src/commands/file/edit.rs>, <https://github.com/jj-vcs/jj/blob/v0.46.0/cli/src/commands/file/delete.rs>
- gotchas: "Version: v0.46.0"; "edit: --revision, -r <REVSET>: Revision to edit; defaults to `@`."; "edit: --restore-descendants: Preserve descendants' content, rather than their diff, when rebasing."; "edit: <FILE> (required): File to edit; a new file is created if it does not exist in the revision."; "delete: --revision, -r <REVSET>: Revision to delete files from; defaults to `@`."; "delete: --restore-descendants: Preserve descendants' content, rather than their diff, when rebasing."; "delete: <FILESETS> (required): One or more file or directory paths to delete; filesets are accepted."; "The commands operate on files in any revision and do not require changing the working copy."

### jj git push default target revisions are configurable (2026-10-07)
- slug: jj-git-push-default-target-revisions-are-configurable-b08514ec4184
- score: 0.91

How to use it:

When `jj git push` should target a different default revision set, configure `revsets.git-push` with the desired revset. By default, jj pushes tracking bookmarks and tags pointing to revisions in `remote_bookmarks(remote=exact:remote)..@`.

Examples:

```
[revsets]
git-push = 'remote_bookmarks(remote=exact:remote)..@'
```

- why_it_matters: Set which revisions `jj git push` targets by default.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://github.com/jj-vcs/jj/blob/v0.46.0/docs/config.md>
- gotchas: "Version: v0.46.0"; "revsets.git-push: Revset that selects default target revisions for `jj git push`. Tracking bookmarks and tags pointing to the selected revisions are pushed."; "remote: In the documented example, the `remote` symbol expands to the name of the remote, such as `origin`."

### jj git push targets multiple remotes (2026-10-07)
- slug: jj-git-push-targets-multiple-remotes-ac329c2f80ea
- score: 0.99

How to use it:

When repository changes need to reach multiple configured Git remotes, run `jj git push` with repeatable `--remote` patterns or set `git.push` to a string pattern or array of patterns.

Examples:

```
jj git push --remote '<pattern-1>' --remote '<pattern-2>'
```

```
jj config set --repo git.push '["<pattern-1>", "<pattern-2>"]'
```

- why_it_matters: Push repository changes to multiple configured Git remotes in one `jj git push` operation.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://github.com/jj-vcs/jj/blob/v0.46.0/cli/src/commands/git/push.rs>, <https://github.com/jj-vcs/jj/blob/v0.46.0/docs/config.md>
- gotchas: "Version: v0.46.0"; "--remote <REMOTE>: Remote name pattern to push to; repeatable. Patterns use glob syntax by default and support other string pattern syntax."; "git.push: Default remote pattern, or array of patterns, used by `jj git push`. Patterns use glob syntax by default."; "git.push[] (each array item): String pattern selecting a remote; the docs show multiple patterns in one array. Mutually exclusive with nothing documented."; "Prerequisite: The target Git remotes must be configured in the repository."; "`--remote` is repeatable and accepts string patterns."; "Docs conflict: The v0.46.0 push source contains a stale command comment saying there is no option to push to multiple remotes; the release note and same file's `--remote` argument documentation specify repeatable remotes."

### jj ui.editor supports path and line substitutions (2026-10-07)
- slug: jj-ui-editor-supports-path-and-line-substitutions-dfd07a434a58
- score: 0.96

How to use it:

When configuring jj’s editor to open a relevant file at a specified line, set `ui.editor` with `$line` for the 1-based line number and `$path` for the file path.

Examples:

```
[ui]
editor = ["emacs", "+$line", "$path"]
```

- why_it_matters: Configure an editor command to open the relevant file at a specified line.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://github.com/jj-vcs/jj/discussions/10339>, <https://github.com/jj-vcs/jj/blob/main/docs/config.md>
- gotchas: "Version: v0.46.0"; "ui.editor (required): Editor command and arguments; it is overridden by `JJ_EDITOR` and takes precedence over `VISUAL` and `EDITOR`."; "$line: Substituted with the 1-based line number for cursor positioning."; "$path: Substituted with the file path."

### jj workspace add creates colocated Git worktrees (2026-10-07)
- slug: jj-workspace-add-creates-colocated-git-worktrees-56b66f4cd94f
- score: 0.97

How to use it:

When adding a workspace in a Git-backed repository, use `jj workspace add --colocate <destination>` to create a corresponding Git worktree or `--no-colocate` to prevent one; without either flag, creation depends on whether the current workspace is colocated and `git.colocate` is true.

Examples:

```
jj workspace add --colocate <destination>
```

```
jj workspace add --no-colocate <destination>
```

- why_it_matters: When adding a workspace alongside Git worktrees, configure whether `jj workspace add` creates a corresponding Git worktree.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.46.0>, <https://github.com/jj-vcs/jj/discussions/10339>, <https://github.com/jj-vcs/jj/blob/main/cli/src/commands/workspace/add.rs>
- gotchas: "Version: v0.46.0"; "<destination> (required): Directory path where the new workspace is created."; "--colocate: Create a Git worktree alongside the new workspace."; "--no-colocate: Do not create a Git worktree alongside the new workspace."; "git.colocate: Boolean configuration setting used for default colocation; the release note says the default creates a worktree when the current workspace is colocated and this setting is true."; "Prerequisite: Git command version 2.42.0 or later; `jj workspace add` uses `git worktree add --orphan`, introduced in Git 2.42.0."; "The default colocates only when the current workspace is colocated and `git.colocate` is `true`."

### jj converge resolves divergent commits (2026-09-03)
- slug: jj-converge-resolves-divergent-commits-c4286987ea6a
- score: 0.93

How to use it:

When divergence should be reconciled automatically, run `jj converge`; it uses `revsets.converge` by default and creates a replacement revision using heuristics. If prompts must be avoided, add `--no-interactive`; it warns and exits without changes if it cannot resolve automatically.

Examples:

```
jj converge
```

```
jj converge --revisions '<REVSET>'
```

```
jj converge --no-interactive
```

- why_it_matters: Resolve divergent commits in a repository when automatic reconciliation is appropriate.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.45.0>, <https://github.com/jj-vcs/jj/blob/v0.45.0/docs/config.md>, <https://github.com/jj-vcs/jj/blob/v0.45.0/cli/src/commands/converge.rs>
- gotchas: "Version: v0.45.0"; "--revisions REVSET (alias: --revision, -r): Search for divergence among revisions matching the revset; defaults to the `revsets.converge` setting (`mutable() & divergent()`)."; "--no-interactive: Do not prompt; if automatic resolution fails, warn and exit without changes."; "Heuristics may be inconclusive, in which case the command prompts the user."; "In non-interactive mode, the command aborts if prompting would be needed."

### jj absorb adds interactive hunk selection (2026-08-06)
- slug: jj-absorb-adds-interactive-hunk-selection-ea4af8ca0557
- score: 0.98

How to use it:

When absorbing only some changes from a source revision, run `jj absorb -i` and select the changes to consider. Selected changes are assigned to eligible ancestors; changes that cannot be assigned unambiguously remain in the source.

Examples:

```
jj absorb -i
```

```
jj absorb --tool <NAME>
```

- why_it_matters: When absorbing only selected changes from a source commit, choose the hunks interactively.
- before: Split the source commit before absorbing only part of it.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/v0.44.0/cli/src/commands/absorb.rs>
- gotchas: "Version: v0.44.0"; "--interactive, -i: Interactively choose which parts to absorb; only selected changes are considered."; "--tool <NAME>: Select the diff editor to use; implies `--interactive`."; "--from, -f <REVSET>: Source revision; defaults to `@`."; "--into, -t <REVSETS>: Destination revisions; only ancestors of the source are considered. Defaults to `mutable()`."; "FILESETS: Restrict changes moved to the specified paths; defaults to all paths."; "Hunks that are not selected or cannot be absorbed remain in the source commit."

### jj diff.stat limits stat bar width (2026-08-06)
- slug: jj-diff-stat-limits-stat-bar-width-d71aeaa31f28
- score: 0.92

How to use it:

When reviewing diff statistics in a narrow layout, set `diff.stat.max-bar-width` to cap the `++--` bar while using `--stat`. For template output, `diff.stat()` accepts an optional `max_bar_width` argument for the same effect.

Examples:

```
[diff.stat]
max-bar-width = 10

jj show --stat
```

```
jj diff -T 'diff.stat(max_bar_width=10)'
```

- why_it_matters: When reviewing diff statistics in a narrow output layout, limit the `++--` bar width.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/main/docs/config.md>, <https://github.com/jj-vcs/jj/blob/main/docs/templates.md>, <https://github.com/jj-vcs/jj/discussions/9925>
- gotchas: "Version: v0.44.0"; "diff.stat.max-bar-width: Maximum character width of the `++--` bar in diff stat output; without it, the bar uses remaining available space, with a minimum of 30% of total width."; "--stat: Enables diff stat output; the release note says the new config option applies when using it."; "diff.stat() max_bar_width: Optional second positional or named integer argument limiting the maximum character length of the `++--` bar. The template docs also list an optional first `width` argument; they do not state that the arguments are mutually exclusive."; "The `max_bar_width` argument to `diff.stat()` is optional and may be positional or named."

### jj file search adds line numbers (2026-08-06)
- slug: jj-file-search-adds-line-numbers-32c8e6895a2e
- score: 0.92

How to use it:

When reviewing repository search results, run `jj file search -n --pattern <PATTERN>` to prefix each matching line with its file path and 1-based line number. The pattern is required and defaults to regex syntax when no kind prefix is given.

Examples:

```
jj file search -n --pattern '<PATTERN>'
```

- why_it_matters: When reviewing repository search results, include each match's line number.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/v0.44.0/cli/src/commands/file/search.rs>
- gotchas: "Version: v0.44.0"; "-n, --line-number: Prefix each matched line with its 1-based line number within the file."; "-p, --pattern <PATTERN> (required): Pattern to search for in a single line; supports string pattern syntax such as `kind:pattern`, defaulting to regex if the kind is omitted."; "Line numbers are 1-based and within the file."

### jj file search prints matched lines (2026-08-06)
- slug: jj-file-search-prints-matched-lines-6130358974a6
- score: 0.97

How to use it:

When searching repository files and reviewing matching content, run `jj file search` with a pattern to print each matching line prefixed by its file path. Add `--name-only` to print only paths containing matches.

Examples:

```
jj file search --pattern <PATTERN> [FILESETS...]
```

```
jj file search --pattern <PATTERN> --name-only [FILESETS...]
```

- why_it_matters: When searching repository files and reviewing matching content, print each matched line with its path.
- before: Previously, `jj file search` printed only paths of files containing a match; use `--name-only` for that behavior.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/v0.44.0/cli/src/commands/file/search.rs>
- gotchas: "Version: v0.44.0"; "--pattern <PATTERN> / -p <PATTERN> (required): Pattern to search for in a single line; defaults to regex syntax. A glob pattern must match the whole line."; "--name-only: Print paths of files containing a match, not matched lines; conflicts with `--line-number`."; "FILESETS...: Restrict the search to files matching these prefixes; without them, search all files."; "--revision <REVSET> / -r <REVSET>: Revision whose files to search; defaults to `@`."

### jj git fetch tracks tags from remotes (2026-08-06)
- slug: jj-git-fetch-tracks-tags-from-remotes-e1f12fa257c6
- score: 0.92

How to use it:

When synchronizing tags in a jj v0.44.0 repository, run `jj git fetch` to fetch remote tags and track them with same-named local tags. For existing repositories, run it to re-fetch tags and initialize tracking; use `jj tag track` or `jj tag untrack` to change tracking, or set `remotes.<name>.fetch-tags = '~*'` to disable tag fetching.

Examples:

```
jj git fetch
```

- why_it_matters: When synchronizing tags in a jj repository, fetch remote tags and manage which local tags track them.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/discussions/9925>, <https://github.com/jj-vcs/jj/blob/main/docs/config.md>
- gotchas: "Version: v0.44.0"; "<name> in `remotes.<name>.fetch-tags` (required): Remote name whose tag-fetch pattern is configured."; "`fetch-tags`: String pattern selecting tag names to fetch for the remote; `~*` disables fetching tags."; "`jj tag track` / `jj tag untrack` arguments (required): Not found in the official pages read; the v0.44.0 release note states these commands associate or disassociate local tags with remotes."; "Git's `tagOpt` is no longer respected."

### jj run adds --ignore-changes (2026-08-06)
- slug: jj-run-adds-ignore-changes-082964bfe9f9
- score: 0.95

How to use it:

When running a command across revisions that may modify the working copy, add `--ignore-changes` to `jj run` to avoid editing those revisions.

Examples:

```
jj run --ignore-changes -- <command> [<arg> ...]
```

- why_it_matters: When running a command across revisions that may modify the working copy, avoid editing those revisions.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>
- gotchas: "Version: v0.44.0"; "--ignore-changes: Avoid editing revisions even if the command modifies the working copy."

### jj run adds --ignore-errors (2026-08-06)
- slug: jj-run-adds-ignore-errors-5fb8a940258a
- score: 0.95

How to use it:

When a command run across revisions must continue after a nonzero exit, pass `--ignore-errors` to `jj run`.

Examples:

```
jj run --ignore-errors -r '<revset>' -- <command> [<arg> ...]
```

- why_it_matters: When running a command across revisions, continue processing later revisions after a nonzero exit code.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/main/docs/config.md#run-running-commands-across-revisions>, <https://jj-vcs.github.io/docs>
- gotchas: "Version: v0.44.0"; "--ignore-errors (required): Continue running against remaining revisions when the command exits with a nonzero exit code."; "-r, --revision <REVSET>: Select the revisions for `jj run`."; "-- <command> [<arg> ...] (required): Separate `jj run` options from the command and its arguments."

### jj templates add try(expr, fallback...) (2026-08-06)
- slug: jj-templates-add-try-expr-fallback-b54c13ecd23c
- score: 0.95

How to use it:

When a template expression can fail at runtime, wrap it in `try(...)` to return the first successful expression and suppress earlier runtime errors; parsing errors still pass through.

Examples:

```
jj log -T 'try(expr, fallback)'
```

- why_it_matters: When a template expression may fail at runtime, provide a fallback value.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.44.0>, <https://github.com/jj-vcs/jj/blob/v0.44.0/docs/templates.md>
- gotchas: "Version: v0.44.0"; "expr (required): Template expression evaluated first."; "fallback...: Zero or more expressions evaluated in order; returns the first successful result. Earlier runtime errors are suppressed; parsing errors, including type errors, pass through."

### jj revsets add forks() (2026-07-02)
- slug: jj-revsets-add-forks-272a36ed7f39
- score: 0.92

How to use it:

When you need commits with multiple children, run `jj log -r 'forks()'` to select and display them.

Examples:

```
jj log -r 'forks()'
```

- why_it_matters: Select commits with multiple child commits in a revset.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.43.0>, <https://github.com/jj-vcs/jj/blob/v0.43.0/docs/revsets.md>
- gotchas: "Version: v0.43.0"; "`forks()`: Takes no arguments; selects commits with more than one child."; "`-r <REVSET>` (required): Passes a revset to `jj log`; `forks()` is the revset in this invocation."; "Prerequisite: Use jj v0.43.0 or later, where `forks()` was added."

### jj run executes commands across changes (2026-07-02)
- slug: jj-run-executes-commands-across-changes-f93c479732de
- score: 0.95

How to use it:

When you need to check or fix code across selected changes, run `jj run` with the command after `--`; it checks out each revision in an isolated working copy and amends it with resulting changes, rebasing descendants by default. Specify revisions with `-r`/`--revision` or use the configured `revsets.run` selection.

Examples:

```
jj run -- cargo check --all-features
```

```
jj run -- cargo fix
```

```
jj run -r <REVSET> -- <COMMAND> [ARGS...]
```

- why_it_matters: Check or fix code across a set of changes, including changes that may update files or produce conflicts.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.43.0>, <https://github.com/jj-vcs/jj/blob/v0.43.0/cli/src/commands/run.rs>
- gotchas: "Version: v0.43.0"; "COMMAND [ARGS...] (required): Command and arguments to run across each selected revision; use `--` to pass arguments that start with `-`."; "-r, --revision <REVSETS> (alias: --revisions): Select revisions to change. If omitted, `revsets.run` config determines the selection."; "-j, --jobs <N>: Set parallel process count; overrides `run.jobs`, defaulting to 1 when neither is set."; "--root: Run from each revision's working-copy root instead of the subdirectory where `jj run` was invoked."; "--clean: Delete each reused working copy before running; each revision starts from a freshly checked-out tree."; "--restore-descendants: Preserve descendants' content when rebasing them; default behavior rebases descendants and propagates the diff."

### jj show adds --reversed (2026-07-02)
- slug: jj-show-adds-reversed-0775d259b86b
- score: 0.94

How to use it:

When reviewing a change’s contents in reverse revision order, run `jj show --reversed` (optionally specify revisions).

Examples:

```
jj show --reversed <REVSETS>
```

- why_it_matters: Inspect a change in reverse order when reviewing its contents.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.43.0>, <https://github.com/jj-vcs/jj/blob/v0.43.0/cli/src/commands/show.rs>
- gotchas: "Version: v0.43.0"; "--reversed: Show revisions in the opposite order (older revisions first)."; "REVSETS: Revisions to show, compared to their parent(s); defaults to `@` when omitted."; "Prerequisite: Use jj v0.43.0 or later; the release note introduces this flag in v0.43.0."

### jj diff editors support file-by-file invocation (2026-06-04)
- slug: jj-diff-editors-support-file-by-file-invocation-56cdea66571e
- score: 0.94

How to use it:

When editing changes with a per-file diff editor, set `edit-invocation-mode` to `"file-by-file"` under that editor’s `[merge-tools.<tool>]` config; jj then launches the editor once per changed file. [jj v0.42.0 config docs](https://github.com/jj-vcs/jj/blob/v0.42.0/docs/config.md)

Examples:

```
[ui]
diff-editor = "<tool>"

[merge-tools.<tool>]
edit-invocation-mode = "file-by-file"
```

- why_it_matters: Edit changed files separately when using a per-file diff editor with `jj diffedit` or `jj split`.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.42.0>, <https://github.com/jj-vcs/jj/blob/v0.42.0/docs/config.md>
- gotchas: "Version: v0.42.0"; "`ui.diff-editor`: Selects the default diff editor; the docs say it defaults to the built-in editor if unset."; "`merge-tools.<tool>.edit-invocation-mode` (required): Sets the diff editor invocation mode; use `\"file-by-file\"` to invoke it once per changed file. No mutually exclusive sub-keys are documented."; "`merge-tools.<tool>.edit-args`: Sets arguments for the selected diff editor; defaults to `[\"$left\", \"$right\"]` when unset. An empty list makes jj refuse to use the tool for diff editing."; "Prerequisite: Use an installed diff editor that supports per-file invocation; the release note names `vimdiff` as an example."

### jj show accepts multiple revisions (2026-06-04)
- slug: jj-show-accepts-multiple-revisions-a471b4846758
- score: 0.95

How to use it:

When reviewing several revisions, run `jj show <REVISION> <REVISION>`; it shows their changes in sequence. [jj v0.42.0 release](https://github.com/jj-vcs/jj/releases/tag/v0.42.0)

Examples:

```
jj show <REVISION> <REVISION>
```

- why_it_matters: Show several revisions while reviewing repository history.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.42.0>, <https://github.com/jj-vcs/jj/blob/v0.42.0/cli/src/commands/show.rs>
- gotchas: "Version: v0.42.0"; "REVSETS: Positional revision arguments; `jj show` shows changes in these revisions compared with their parent(s). Defaults to `@` when omitted. [Source](https://github.com/jj-vcs/jj/blob/v0.42.0/cli/src/commands/show.rs)"

### Configure default jj fetch targets (2026-05-07)
- slug: configure-default-jj-fetch-targets-68e61e09b01f
- score: 0.91

How to use it:

When you want to choose default fetch targets for a remote, set its `fetch-bookmarks` and/or `fetch-tags` string pattern in jj configuration. `fetch-tags` is experimental.

Examples:

```
[remotes.<name>]
fetch-bookmarks = "~gh-pages"
fetch-tags = "v*"
```

- why_it_matters: Configure which bookmarks and tags jj fetches by default when working in a repository.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.41.0>, <https://github.com/jj-vcs/jj/blob/v0.41.0/docs/config.md>
- gotchas: "Version: v0.41.0"; "remotes.<name>.fetch-bookmarks: String pattern matching bookmark names to fetch. If unset, default fetch refspecs are read from the remote’s Git configuration."; "remotes.<name>.fetch-tags: Experimental string pattern matching tag names to fetch. Matching tags are fetched as tracked `<name>@<remote>` tags, and corresponding local tags are created."; "Prerequisite: Configure these as jj TOML settings for a remote; the documentation gives `[remotes.<name>]` as the table form."

### `file search` pattern kinds and default (2026-05-07)
- slug: file-search-pattern-kinds-and-default-d139180715e5
- score: 0.92

How to use it:

When searching repository files, run `jj file search` with `--pattern`; an unprefixed pattern now uses regex matching. Prefix the pattern with `glob:` when you want glob matching.

Examples:

```
jj file search --pattern 'regex:<regular-expression>'
```

```
jj file search --pattern 'glob:<glob-pattern>' <fileset>
```

- why_it_matters: Search repository files using a glob or regular-expression pattern.
- before: The `--pattern` default was `glob:`; prefix the pattern with `regex:` to use regular-expression matching.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.41.0>, <https://github.com/jj-vcs/jj/blob/v0.41.0/cli/src/commands/file/search.rs>, <https://docs.jj-vcs.dev/latest/revsets/#string-patterns>
- gotchas: "Version: v0.41.0"; "--pattern <PATTERN> (required): Pattern to search for in a single line. Supports `exact:`, `glob:`, `regex:`, and `substring:`; omitted kind defaults to regex. `glob:` must match the whole line. Pattern kinds are alternatives, not mutually exclusive options."; "<REVSET> (`-r`, `--revision`): Revision to search; defaults to `@`."; "<FILESETS>: Optional file path prefixes to search instead of all files."; "exact:: Match strings exactly equal to the pattern."; "glob:: Match using Unix-style shell wildcards."; "regex:: Match substrings using a regular expression."; "substring:: Match strings containing the pattern."; "The `--pattern` flag accepts various pattern kinds through `kind:pattern` syntax."

### jj fix can format selected line ranges (2026-05-07)
- slug: jj-fix-can-format-selected-line-ranges-1f1885bf3fe3
- score: 0.98

How to use it:

When a configured formatter supports line ranges, set `fix.tools.<name>.line-range-arg` to pass each modified range and optionally set `run-tool-if-zero-line-ranges` to run it when no ranges are available. Run `jj fix --all-lines` to format whole modified files.

Examples:

```
[fix.tools.<name>]
command = ["<formatter>", "<formatter-args>"]
patterns = ["<fileset>"]
line-range-arg = "--lines=$first:$last"
run-tool-if-zero-line-ranges = false

jj fix --all-lines
```

- why_it_matters: Format only modified lines when running `jj fix` on files with configured formatting tools.
- before: Without line-range configuration, the tool processes the entire file; `--all-lines` formats the entire modified file when line ranges are configured.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.41.0>, <https://github.com/jj-vcs/jj/blob/v0.41.0/docs/config.md>, <https://github.com/jj-vcs/jj/blob/v0.41.0/cli/src/commands/fix.rs>
- gotchas: "Version: v0.41.0"; "fix.tools.<name>.command (required): Arguments to run the tool; first argument is its executable path."; "fix.tools.<name>.patterns (required): Filesets selecting affected files; an empty list matches no files."; "fix.tools.<name>.line-range-arg: Template string passed for each modified range; `$first` and `$last` are 1-based endpoints. Deletion-only empty ranges are skipped."; "fix.tools.<name>.run-tool-if-zero-line-ranges: Run the tool when no line ranges were calculated; defaults to `false`. Not mutually exclusive with `line-range-arg`."; "--all-lines: Format all lines instead of only modified lines; short form `-a`."; "Prerequisite: Configure a fix tool with a command and matching fileset patterns. For line-limited formatting, the formatter must support the configured range argument."; "`--all-lines` matches the previous behavior of formatting the entire file when `line-range-arg` is set."

### Template `replace` function supports pattern replacement (2026-05-07)
- slug: template-replace-function-supports-pattern-replacement-09e80ed08fd7
- score: 0.94

How to use it:

When formatting replacement text in a jj template, call `replace(pattern, content, replacement)`; use a lambda and `c.get(index)` to format text from regex capture groups.

Examples:

```
jj log -T 'replace(regex:"(\\w+) (\\w+)", "hello world", |c| c.get(1) ++ " " ++ c.get(2))'
```

- why_it_matters: Format replacement text while transforming string content in a jj template.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.41.0>, <https://github.com/jj-vcs/jj/blob/v0.41.0/docs/templates.md>
- gotchas: "Version: v0.41.0"; "pattern (required): A `StringPattern`; `regex:\"...\"` matches substrings using a regular expression."; "content (required): Template content in which to replace every pattern match."; "replacement (required): A lambda of type `|RegexCaptures| -> Template`, formatted for each match."; "RegexCaptures.get(index) (required): Returns the capture group at the given index; capture group 0 is the full match."; "-T / --template (required): Passes a template expression to a jj command that accepts templates."; "Prerequisite: Use jj v0.41.0 or later for the documented global `replace()` template function."; "Supports all string patterns, including regexes with capture groups."

### jj operation views filter revisions and allow override (2026-04-02)
- slug: jj-operation-views-filter-revisions-and-allow-override-5e0206d8944b
- score: 0.90

How to use it:

When reviewing operation changes with jj v0.40.0, use `jj op show`, `jj op diff`, or `jj op log -p`; they show revisions selected by `revsets.op-diff-changes-in` by default. Pass `--show-changes-in <REVSETS>` to override the selection.

Examples:

```
jj op show --show-changes-in '<REVSETS>'
```

```
jj op diff --show-changes-in '<REVSETS>'
```

```
jj op log -p --show-changes-in '<REVSETS>'
```

- why_it_matters: Inspect operation changes while reviewing or debugging repository history.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.40.0>, <https://github.com/jj-vcs/jj/blob/v0.40.0/docs/config.md>
- gotchas: "Version: v0.40.0"; "--show-changes-in <REVSETS>: Overrides the selected revisions shown by `jj op show`, `jj op diff`, and `jj op log -p`."; "revsets.op-diff-changes-in: Revset selecting revisions considered interesting in operation diffs; revisions outside it are elided into a summary count. Default: `mutable() | immutable_heads()`."; "By default, only revisions defined as “interesting” by `revsets.op-diff-changes-in` are shown."

### jj revsets add diff_lines_added() and diff_lines_removed() (2026-04-02)
- slug: jj-revsets-add-diff-lines-added-and-diff-lines-removed-116e8e4086c9
- score: 0.95

How to use it:

When querying revisions for content changed on one side of a diff, use `diff_lines_added(text, [files])` for added lines or `diff_lines_removed(text, [files])` for removed lines.

Examples:

```
jj log -r 'diff_lines_added("<pattern>")'
```

```
jj log -r 'diff_lines_removed("<pattern>")'
```

- why_it_matters: Match added or removed content while querying revisions.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.40.0>, <https://github.com/jj-vcs/jj/blob/v0.40.0/docs/revsets.md>
- gotchas: "Version: v0.40.0"; "text (required): Line-by-line string pattern to match on the selected diff side."; "files: Fileset expression narrowing search paths; all modified files are scanned by default."

### jj String.substr() allows omitting end (2026-04-02)
- slug: jj-string-substr-allows-omitting-end-582453ef02c0
- score: 0.96

How to use it:

When a jj template needs the substring from a start index through the string’s end, call `.substr(start)`; `end` is optional. [jj v0.40.0 release notes](https://github.com/jj-vcs/jj/releases/tag/v0.40.0)

Examples:

```
<string>.substr(<start>)
```

- why_it_matters: Format a string template using a substring that extends to the string's end.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.40.0>, <https://github.com/jj-vcs/jj/blob/main/docs/templates.md>
- gotchas: "Version: v0.40.0"; "start (required): Zero-based start index, in UTF-8 bytes for String; negative values count from the end."; "end: Exclusive end index; negative values count from the end. Omit to return through the string’s end. No mutual-exclusion rule applies."

### jj bookmark advance moves bookmarks to a target revision (2026-03-04)
- slug: jj-bookmark-advance-moves-bookmarks-to-a-target-revision-8ba896fb7d4f
- score: 0.94

How to use it:

After updating commits, run `jj bookmark advance` to advance eligible bookmarks to the configured target, which defaults to `@`.

Examples:

```
jj bookmark advance
```

```
[revsets]
bookmark-advance-from = 'heads(::to & bookmarks())'
bookmark-advance-to = '@'
```

- why_it_matters: Advance repository bookmarks to the target revision after updating commits.
- before: Use the community alias `jj tug` for the longstanding equivalent workflow.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/docs/config.md>
- gotchas: "Version: v0.39.0"; "revsets.bookmark-advance-from: Revset selecting bookmarks to advance; default is `heads(::to & bookmarks())`. It can refer to `to`."; "revsets.bookmark-advance-to: Destination revset; default is `@`, the current working copy."

### jj bookmark rename can overwrite an existing bookmark (2026-03-04)
- slug: jj-bookmark-rename-can-overwrite-an-existing-bookmark-3efcf177a636
- score: 0.92

How to use it:

When renaming a bookmark to a name that already exists, run `jj bookmark rename` with `--overwrite-existing` to replace the existing bookmark.

Examples:

```
jj bookmark rename --overwrite-existing <old> <new>
```

- why_it_matters: Rename a bookmark to a name that already exists in the repository.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/cli/src/commands/bookmark/rename.rs>
- gotchas: "Version: v0.39.0"; "old (required): Existing bookmark name to rename."; "new (required): New bookmark name."; "--overwrite-existing: Allow renaming when the new bookmark name already exists."; "The flag allows the existing bookmark with the new name to be replaced."

### jj configuration supports environment-based conditions (2026-03-04)
- slug: jj-configuration-supports-environment-based-conditions-dc5267884877
- score: 0.94

How to use it:

When a repository development setting should apply only under an environment condition, add a conditional scope to jj configuration. Use `--when.environments` with `NAME=VALUE` to match a value or `NAME` to match whenever the variable is set.

Examples:

```
[[--scope]]
--when.environments = ["<NAME>=<VALUE>"]
[--scope.<section>]
<key> = "<value>"
```

- why_it_matters: Apply a jj configuration condition based on environment variables in a repository development setup.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/docs/config.md>
- gotchas: "Version: v0.39.0"; "--when.environments (required): List of environment conditions. Each item is `NAME=VALUE` to match that value, or `NAME` to match if set. Items in the list are alternatives (OR)."; "--scope (required): Conditional configuration table; its variables are expanded to the root config table."; "Multiple condition keys: If multiple `--when` conditions are specified, their intersection is used (AND)."

### jj gerrit upload accepts additional upload flags (2026-03-04)
- slug: jj-gerrit-upload-accepts-additional-upload-flags-559f1eb825a5
- score: 0.92

How to use it:

When uploading a jj change for Gerrit review, run `jj gerrit upload` with the desired reviewer and label flags. The release note gives `--reviewer=foo@example.com` and `--label=Auto-Submit` as examples.

Examples:

```
jj gerrit upload --reviewer=<email> --label=<label>
```

- why_it_matters: Upload a jj change for review with reviewer or label options.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://gerrit-review.googlesource.com/Documentation/user-upload.html>, <https://www.jj-vcs.dev/latest/gerrit/>
- gotchas: "Version: v0.39.0"; "--reviewer=<email>: Requests the specified account as a reviewer."; "--label=<label>: Applies a review label. Gerrit documents label scores as optional; if omitted, the default is +1 when allowed."; "-r, --revisions <REVISIONS>: Selects revisions to upload; the v0.39.0 release note says the flag is no longer required and the command defaults to the current working revision."; "Prerequisite: Configure authentication for the Gerrit server before uploading."; "Prerequisite: Specify a Gerrit remote or configure a default remote; otherwise the command can fail if no `gerrit` remote exists."; "The release refers to Gerrit's documentation for the variety of supported flags; it does not enumerate them all."

### jj gerrit upload defaults to the current work (2026-03-04)
- slug: jj-gerrit-upload-defaults-to-the-current-work-cad1d2dd6dc5
- score: 0.94

How to use it:

When uploading the change currently being worked on for Gerrit review, run `jj gerrit upload` without `-r`; it defaults to the current work. [v0.39.0 release notes](https://github.com/jj-vcs/jj/releases/tag/v0.39.0)

Examples:

```
jj gerrit upload
```

- why_it_matters: Upload the change currently being worked on for Gerrit review.
- before: Pass `-r` to `jj gerrit upload` to select what to upload.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>
- gotchas: "Version: v0.39.0"; "Without `-r`, the command defaults to uploading what you are currently working on."

### jj rebase adds --simplify-parents (2026-03-04)
- slug: jj-rebase-adds-simplify-parents-8cadc905de73
- score: 0.92

How to use it:

When rebasing commits and you want to remove parent edges that are ancestors of other parents, run `jj rebase --simplify-parents --onto <destination>`; with no source selector, jj rebases the default branch `@`.

Examples:

```
jj rebase --simplify-parents --onto <destination>
```

- why_it_matters: Rebase commits while applying parent simplification to the rebased commits.
- before: Rebase first, then run `jj simplify-parents` on the freshly rebased commits.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/cli/src/commands/rebase.rs>
- gotchas: "Version: v0.39.0"; "--simplify-parents: Simplify parents of rebased commits by removing parents that are ancestors of other parents."; "--onto <REVSETS> (required): Revision(s) to rebase onto; may be repeated to create a merge commit. A rebase destination is required."; "--branch, --source, or --revisions: Selects what to rebase. If none is supplied, the default is `--branch @`."; "Prerequisite: Use jj v0.39.0 or later for this flag."

### jj templates add list manipulation methods (2026-03-04)
- slug: jj-templates-add-list-manipulation-methods-cdd5a1000805
- score: 0.97

How to use it:

When a jj template needs list manipulation for repository inspection, call the list methods on a list value. Use `jj log -T` with a template such as `self.parents().reverse().take(2).map(|c| c.commit_id().short()).join("\n")` to inspect recent parents.

Examples:

```
jj log -T 'self.parents().reverse().take(2).map(|c| c.commit_id().short()).join("\n")'
```

- why_it_matters: Manipulate list values in a jj template used for repository inspection.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/docs/templates.md>
- gotchas: "Version: v0.39.0"; "first(): Returns the first element; errors if the list is empty."; "last(): Returns the last element; errors if the list is empty."; "get(index: Integer) (required): Returns the element at the zero-based index; errors if out of bounds."; "reverse(): Returns the list in reverse order."; "skip(count: Integer) (required): Skips the first count elements and returns the rest."; "take(count: Integer) (required): Returns only the first count elements."; "These methods are supported on list types."

### jj templates add Timestamp::since (2026-03-04)
- slug: jj-templates-add-timestamp-since-a8fe389549c1
- score: 0.94

How to use it:

When a template needs a human-friendly duration between two timestamps, call `.since(start)` on the ending `Timestamp`, then call `.duration()` on the returned `TimestampRange`.

Examples:

```
jj log -T 'self.committer().timestamp().since(self.author().timestamp()).duration()'
```

- why_it_matters: Display a human-friendly duration between timestamps in a jj template.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.39.0>, <https://github.com/jj-vcs/jj/blob/v0.39.0/docs/templates.md>
- gotchas: "Version: v0.39.0"; ".since(start: Timestamp) (required): Returns the `TimestampRange` between `start` and the receiver timestamp."; ".duration() (required): Returns a human-friendly duration string for a `TimestampRange`."; "Prerequisite: Use jj v0.39.0 or later; this template method is documented in the v0.39.0 templates reference."

### jj adds the `remote_tags()` revset function (2026-02-05)
- slug: jj-adds-the-remote-tags-revset-function-1d637f2924a8
- score: 0.90

How to use it:

When querying remote tags, use `remote_tags()` in a jj revset; it selects targets of remote tags across all remotes.

Examples:

```
jj log -r 'remote_tags()'
```

- why_it_matters: When querying remote tags in a repository, use the new revset function.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.38.0>, <https://github.com/jj-vcs/jj/blob/main/docs/revsets.md>
- gotchas: "Version: v0.38.0"; "name_pattern (optional): Filters remote tags by matching tag name; supports jj string patterns."; "remote_pattern (optional; argument may be labeled `remote=`): Filters tags by matching remote name. Both filters may be supplied together; no mutual exclusion is documented."

### jj change IDs support numeric suffixes for hidden and divergent changes (2026-01-08)
- slug: jj-change-ids-support-numeric-suffixes-for-hidden-and-divergent-changes-6ef0e20d63cb
- score: 0.93

How to use it:

When recovering the previous contents of a hidden or divergent change, use the numeric suffix shown in the log to select it, then run `jj restore --from <change-id>/1 --to <change-id>`.

Examples:

```
jj restore --from <change-id>/1 --to <change-id>
```

- why_it_matters: Restore a change from its previous version after an accidental edit.
- sources: <https://github.com/jj-vcs/jj/releases/tag/v0.37.0>
- gotchas: "Version: v0.37.0"; "--from <change-id>/1 (required): Select the previous version of the change as the restore source; `/1` refers to the previous version."; "--to <change-id> (required): Select the change whose contents are to be restored."
