{"article":{"slug":"jj-jujutsu-v0-46-0-release-notes","title":"jj (Jujutsu) v0.46.0 release notes","subtitle":null,"summary":"Jujutsu 0.46.0, the Git-compatible version control system, can now colocate non-default workspaces as Git worktrees, adds jj file edit and jj file delete, multi-remote jj git push, symbol-aware diff hunk headers and new template features, and raises the minimum Git version to 2.42.0.","content_type":"changelog","language":"en","canonical_url":"https://github.com/jj-vcs/jj/releases/tag/v0.46.0","author":{"name":null,"url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Jujutsu (jj-vcs)","url":"https://github.com/jj-vcs/jj","listing_slug":null,"listing":null},"topics":[{"name":"Version Control","slug":"version-control","url":"https://listedarticles.com/topics/version-control"},{"name":"Git","slug":"git","url":"https://listedarticles.com/topics/git"},{"name":"Developer Tools","slug":"developer-tools","url":"https://listedarticles.com/topics/developer-tools"},{"name":"Release","slug":"release","url":"https://listedarticles.com/topics/release"}],"about_listings":[],"cover_image_url":null,"license":"Apache-2.0","word_count":974,"reading_minutes":4,"published_at":"2026-10-07T21:28:17.000Z","added_at":"2026-10-08T11:09:46.059Z","updated_at":"2026-10-08T11:09:46.059Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/jj-jujutsu-v0-46-0-release-notes","markdown_url":"https://listedarticles.com/articles/jj-jujutsu-v0-46-0-release-notes.md","example":false,"citation":"Jujutsu (jj-vcs). \"jj (Jujutsu) v0.46.0 release notes.\" 7 Oct 2026. https://github.com/jj-vcs/jj/releases/tag/v0.46.0 (Apache-2.0)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://github.com/jj-vcs/jj/releases/tag/v0.46.0"},"body_markdown":"[jj](https://github.com/jj-vcs/jj) v0.46.0 release notes, published by the jj-vcs project on GitHub.\n\n### About\n\njj is a Git-compatible version control system that is both simple and powerful. See\nthe [installation instructions](https://docs.jj-vcs.dev/v0.46.0/install-and-setup/) to get started.\n\n### Release highlights\n\n* Jujutsu can now colocate workspaces besides the default one by creating Git\n  worktrees. Use `jj workspace add --[no-]colocate` and the setting\n  `git.colocate` to control this.\n\n### Breaking changes\n\n* The minimum supported `git` command version is now 2.42.0, up from 2.41.0.\n  `jj workspace add` uses `git worktree add --orphan`, which was added in\n  2.42.0.\n* The minimum supported Rust version (MSRV) is now 1.97.1.\n* `jj bisect run` now runs some consistency checks before proceeding to bisect.\n  This helps ensure that the command can tell good and bad revisions apart,\n  and that the working copy does go from bad to good over the provided revset.\n  Use the new flag `--trust-endpoints` to disable these checks.\n* `jj split` now opens a single editor session to edit descriptions for the\n  split commits.\n* `jj undo` and `jj redo` now refuse to undo/redo an operation that was\n  performed in another workspace. Use `--allow-cross-workspace` to undo/redo\n  it anyway.\n* `jj workspace list`/`root` no longer omit unreachable paths. All recorded\n  paths are now shown, with warnings displayed in `jj workspace root`.\n* The `List.get()`, `.first()`, and `.last()` template functions now return\n  `Option<T>` instead of throwing an error on out-of-bounds access.\n\n### New features\n\n* `jj workspace add` supports `--colocate`/`--no-colocate` flags to control\n  whether a Git worktree is created alongside the workspace. The default\n  colocates when the current workspace is colocated and the `git.colocate`\n  config is `true`. `jj workspace forget` removes the corresponding Git\n  worktree when one exists.\n* `jj git colocation status`/`enable`/`disable` now work on child\n  workspaces. `status` correctly reports colocation state and includes\n  the workspace name. `enable` creates a Git worktree and `disable`\n  removes it, allowing colocation to be toggled after workspace\n  creation.\n* `jj workspace remove` removes a workspace and its directory from disk. The\n  working-copy state is snapshotted into a commit before removal.\n* Added commands `jj file edit` and `jj file delete` for editing files in any\n  revision without needing to change the working copy.\n* `jj git push` now supports pushing to multiple remotes at the same time.\n  This can be configured via `git.push` set to a string pattern\n  or array of string patterns, or with the repeatable `--remote` flag,\n  which also accepts string patterns.\n* The default target revisions for `jj git push` can now be configured via\n  `revsets.git-push`.\n* Added the `TreeEntry.normal_value()` template method and the `TreeValue` type\n  to access resolved tree values, formatted as their full object IDs, including\n  Git submodule commit IDs.\n* Diff hunk headers now include nearby source symbols for many common\n  programming and markup languages.\n* `fix.tools.<name>.line-range-args` (replaces `line-range-arg`) is an array of\n  string template args to pass to the fix tool. This is more flexible in cases\n  where you need to pass multiple arguments to the tool, such as separate args\n  for the range start and range end.\n* `jj run` now uses the sparse patterns from the workspace it's run from.\n  Use the `--sparse-patterns` option to control this behavior (evaluated\n  per each `jj run` invocation).\n* `jj util diff <path1> <path2>` to compare files on disk.\n* Aliases now support setting `aliases.<name>.enabled = false`, which will\n  disable them. This can be used to disable built-in aliases or disable aliases\n  in later layers (such as repo config files).\n* `ui.editor` now supports `$path` and `$line` substitution variables. Example:\n  `ui.editor = [\"emacs\", \"+$line\", \"$path\"]`\n* `fill` template function now supports an additional named parameter\n  `break_words`, that allows specifying if the template should break words\n  longer than `width` passed in the input to ensure no words overflow the\n  specified width.\n* The `json()` template function now supports map literals: `json({'key' => value})`\n* The hunk headers of `diff.color-words.conflict = \"pair\"` now include the\n  conflict labels of the compared terms.\n\n### Fixed bugs\n\n* On Windows, `jj` no longer hangs when a subprocess needs to prompt the user,\n  such as `ssh` asking for a key passphrase or for confirmation of an unknown\n  host key. Subprocesses started from a terminal now inherit its console, rather\n  than being given an invisible one by `CREATE_NO_WINDOW` for the prompt to\n  disappear into.\n  [#6745](https://github.com/jj-vcs/jj/issues/6745)\n  [#8547](https://github.com/jj-vcs/jj/issues/8547)\n* On Windows, `jj git colocation enable` and `jj git colocation disable` no\n  longer fail with \"Access is denied (os error 5)\" when the Git repository\n  contains pack files.\n  [#8661](https://github.com/jj-vcs/jj/issues/8661)\n* `jj undo` of `jj workspace forget` now correctly preserves the workspace's\n  recorded path. Previously the path metadata was lost, leaving the workspace\n  in a broken state after undo.\n  [#9991](https://github.com/jj-vcs/jj/issues/9991)\n* `at_operation()` can now be used with operations that are not ancestors of\n  the current operation (e.g. sibling operations created by concurrent\n  commands). Previously, evaluating such expressions failed if they resolved\n  to commits missing from the current operation's index.\n* `.gitignore` files are now respected even if they aren't materialized in the\n  working copy because they are excluded by the sparse patterns. Previously,\n  ignored files could become tracked in a sparse working copy.\n  [#2289](https://github.com/jj-vcs/jj/issues/2289)\n* In-tree ignore files (`.gitignore`) are no longer read through symlinks,\n  matching `git` behavior. Such files are now silently skipped instead of having\n  their symlink target applied. `$GIT_DIR/info/exclude` and `core.excludesFile`\n  are unaffected and still follow symlinks, as `git` does.\n  [#7161](https://github.com/jj-vcs/jj/issues/7161)\n* `jj workspace list` templates are now labeled with `workspace name`,\n  `workspace root`, etc.\n\n### Contributors\n\nThanks to the people who made this release happen!\n\n* Aaron Bies ([@slerpyyy](https://github.com/slerpyyy))\n* Austin Seipp ([@thoughtpolice](https://github.com/thoughtpolice))\n* Bartok9 ([@Bartok9](https://github.com/Bartok9))\n* Brice Figureau ([@masterzen](https://github.com/masterzen))\n* Bryan O'Sullivan ([@bos](https://github.com/bos))\n* Caleb White ([@calebdw](https://github.com/calebdw))\n* David Rieber ([@drieber](https://github.com/drieber))\n* Farid Zakaria ([@fzakaria](https://github.com/fzakaria))\n* Gabriel Goller ([@kaffarell](https://github.com/kaffarell))\n* Gasper Stukelj ([@mirkomartn](https://github.com/mirkomartn))\n* Jakub Stasiak ([@jstasiak](https://github.com/jstasiak))\n* JamBalaya56562 ([@JamBalaya56562](https://github.com/JamBalaya56562))\n* Joseph Lou ([@josephlou5](https://github.com/josephlou5))\n* Karnajeet Gosavi ([@kg290](https://github.com/kg290))\n* LOG ([@logarithmone1128](https://github.com/logarithmone1128))\n* Martin von Zweigbergk ([@martinvonz](https://github.com/martinvonz))\n* Matt Stark ([@matts1](https://github.com/matts1))\n* Mustafa Officewala ([@genericusername2709](https://github.com/genericusername2709))\n* pederbe ([@pederbe](https://github.com/pederbe))\n* Philip Metzger ([@PhilipMetzger](https://github.com/PhilipMetzger))\n* Pro ([@twistedfall](https://github.com/twistedfall))\n* Remo Senekowitsch ([@senekor](https://github.com/senekor))\n* Sami Hiltunen ([@SamiHiltunen](https://github.com/SamiHiltunen))\n* sofia ([@badp](https://github.com/badp))\n* Stephen Jennings ([@jennings](https://github.com/jennings))\n* Vincent Ging Ho Yim ([@cenviity](https://github.com/cenviity))\n* xtqqczze ([@xtqqczze](https://github.com/xtqqczze))\n* Yannik Sander ([@ysndr](https://github.com/ysndr))\n* Yuya Nishihara ([@yuja](https://github.com/yuja))\n","body_html":"<p><a href=\"https://github.com/jj-vcs/jj\" rel=\"nofollow ugc noopener\">jj</a> v0.46.0 release notes, published by the jj-vcs project on GitHub.</p>\n<h3 id=\"about\">About</h3>\n<p>jj is a Git-compatible version control system that is both simple and powerful. See\nthe <a href=\"https://docs.jj-vcs.dev/v0.46.0/install-and-setup/\" rel=\"nofollow ugc noopener\">installation instructions</a> to get started.</p>\n<h3 id=\"release-highlights\">Release highlights</h3>\n<ul><li><p>Jujutsu can now colocate workspaces besides the default one by creating Git</p><p>worktrees. Use <code>jj workspace add --[no-]colocate</code> and the setting\n<code>git.colocate</code> to control this.</p></li></ul>\n<h3 id=\"breaking-changes\">Breaking changes</h3>\n<ul><li><p>The minimum supported <code>git</code> command version is now 2.42.0, up from 2.41.0.</p><p><code>jj workspace add</code> uses <code>git worktree add --orphan</code>, which was added in\n2.42.0.</p></li><li>The minimum supported Rust version (MSRV) is now 1.97.1.</li><li><p><code>jj bisect run</code> now runs some consistency checks before proceeding to bisect.</p><p>This helps ensure that the command can tell good and bad revisions apart,\nand that the working copy does go from bad to good over the provided revset.\nUse the new flag <code>--trust-endpoints</code> to disable these checks.</p></li><li><p><code>jj split</code> now opens a single editor session to edit descriptions for the</p><p>split commits.</p></li><li><p><code>jj undo</code> and <code>jj redo</code> now refuse to undo/redo an operation that was</p><p>performed in another workspace. Use <code>--allow-cross-workspace</code> to undo/redo\nit anyway.</p></li><li><p><code>jj workspace list</code>/<code>root</code> no longer omit unreachable paths. All recorded</p><p>paths are now shown, with warnings displayed in <code>jj workspace root</code>.</p></li><li><p>The <code>List.get()</code>, <code>.first()</code>, and <code>.last()</code> template functions now return</p><p><code>Option&lt;T&gt;</code> instead of throwing an error on out-of-bounds access.</p></li></ul>\n<h3 id=\"new-features\">New features</h3>\n<ul><li><p><code>jj workspace add</code> supports <code>--colocate</code>/<code>--no-colocate</code> flags to control</p><p>whether a Git worktree is created alongside the workspace. The default\ncolocates when the current workspace is colocated and the <code>git.colocate</code>\nconfig is <code>true</code>. <code>jj workspace forget</code> removes the corresponding Git\nworktree when one exists.</p></li><li><p><code>jj git colocation status</code>/<code>enable</code>/<code>disable</code> now work on child</p><p>workspaces. <code>status</code> correctly reports colocation state and includes\nthe workspace name. <code>enable</code> creates a Git worktree and <code>disable</code>\nremoves it, allowing colocation to be toggled after workspace\ncreation.</p></li><li><p><code>jj workspace remove</code> removes a workspace and its directory from disk. The</p><p>working-copy state is snapshotted into a commit before removal.</p></li><li><p>Added commands <code>jj file edit</code> and <code>jj file delete</code> for editing files in any</p><p>revision without needing to change the working copy.</p></li><li><p><code>jj git push</code> now supports pushing to multiple remotes at the same time.</p><p>This can be configured via <code>git.push</code> set to a string pattern\nor array of string patterns, or with the repeatable <code>--remote</code> flag,\nwhich also accepts string patterns.</p></li><li><p>The default target revisions for <code>jj git push</code> can now be configured via</p><p><code>revsets.git-push</code>.</p></li><li><p>Added the <code>TreeEntry.normal_value()</code> template method and the <code>TreeValue</code> type</p><p>to access resolved tree values, formatted as their full object IDs, including\nGit submodule commit IDs.</p></li><li><p>Diff hunk headers now include nearby source symbols for many common</p><p>programming and markup languages.</p></li><li><p><code>fix.tools.&lt;name&gt;.line-range-args</code> (replaces <code>line-range-arg</code>) is an array of</p><p>string template args to pass to the fix tool. This is more flexible in cases\nwhere you need to pass multiple arguments to the tool, such as separate args\nfor the range start and range end.</p></li><li><p><code>jj run</code> now uses the sparse patterns from the workspace it&#39;s run from.</p><p>Use the <code>--sparse-patterns</code> option to control this behavior (evaluated\nper each <code>jj run</code> invocation).</p></li><li><code>jj util diff &lt;path1&gt; &lt;path2&gt;</code> to compare files on disk.</li><li><p>Aliases now support setting <code>aliases.&lt;name&gt;.enabled = false</code>, which will</p><p>disable them. This can be used to disable built-in aliases or disable aliases\nin later layers (such as repo config files).</p></li><li><p><code>ui.editor</code> now supports <code>$path</code> and <code>$line</code> substitution variables. Example:</p><p><code>ui.editor = [&quot;emacs&quot;, &quot;+$line&quot;, &quot;$path&quot;]</code></p></li><li><p><code>fill</code> template function now supports an additional named parameter</p><p><code>break_words</code>, that allows specifying if the template should break words\nlonger than <code>width</code> passed in the input to ensure no words overflow the\nspecified width.</p></li><li>The <code>json()</code> template function now supports map literals: <code>json({&#39;key&#39; =&gt; value})</code></li><li><p>The hunk headers of <code>diff.color-words.conflict = &quot;pair&quot;</code> now include the</p><p>conflict labels of the compared terms.</p></li></ul>\n<h3 id=\"fixed-bugs\">Fixed bugs</h3>\n<ul><li><p>On Windows, <code>jj</code> no longer hangs when a subprocess needs to prompt the user,</p><p>such as <code>ssh</code> asking for a key passphrase or for confirmation of an unknown\nhost key. Subprocesses started from a terminal now inherit its console, rather\nthan being given an invisible one by <code>CREATE_NO_WINDOW</code> for the prompt to\ndisappear into.\n<a href=\"https://github.com/jj-vcs/jj/issues/6745\" rel=\"nofollow ugc noopener\">#6745</a>\n<a href=\"https://github.com/jj-vcs/jj/issues/8547\" rel=\"nofollow ugc noopener\">#8547</a></p></li><li><p>On Windows, <code>jj git colocation enable</code> and <code>jj git colocation disable</code> no</p><p>longer fail with &quot;Access is denied (os error 5)&quot; when the Git repository\ncontains pack files.\n<a href=\"https://github.com/jj-vcs/jj/issues/8661\" rel=\"nofollow ugc noopener\">#8661</a></p></li><li><p><code>jj undo</code> of <code>jj workspace forget</code> now correctly preserves the workspace&#39;s</p><p>recorded path. Previously the path metadata was lost, leaving the workspace\nin a broken state after undo.\n<a href=\"https://github.com/jj-vcs/jj/issues/9991\" rel=\"nofollow ugc noopener\">#9991</a></p></li><li><p><code>at_operation()</code> can now be used with operations that are not ancestors of</p><p>the current operation (e.g. sibling operations created by concurrent\ncommands). Previously, evaluating such expressions failed if they resolved\nto commits missing from the current operation&#39;s index.</p></li><li><p><code>.gitignore</code> files are now respected even if they aren&#39;t materialized in the</p><p>working copy because they are excluded by the sparse patterns. Previously,\nignored files could become tracked in a sparse working copy.\n<a href=\"https://github.com/jj-vcs/jj/issues/2289\" rel=\"nofollow ugc noopener\">#2289</a></p></li><li><p>In-tree ignore files (<code>.gitignore</code>) are no longer read through symlinks,</p><p>matching <code>git</code> behavior. Such files are now silently skipped instead of having\ntheir symlink target applied. <code>$GIT_DIR/info/exclude</code> and <code>core.excludesFile</code>\nare unaffected and still follow symlinks, as <code>git</code> does.\n<a href=\"https://github.com/jj-vcs/jj/issues/7161\" rel=\"nofollow ugc noopener\">#7161</a></p></li><li><p><code>jj workspace list</code> templates are now labeled with <code>workspace name</code>,</p><p><code>workspace root</code>, etc.</p></li></ul>\n<h3 id=\"contributors\">Contributors</h3>\n<p>Thanks to the people who made this release happen!</p>\n<ul><li>Aaron Bies (<a href=\"https://github.com/slerpyyy\" rel=\"nofollow ugc noopener\">@slerpyyy</a>)</li><li>Austin Seipp (<a href=\"https://github.com/thoughtpolice\" rel=\"nofollow ugc noopener\">@thoughtpolice</a>)</li><li>Bartok9 (<a href=\"https://github.com/Bartok9\" rel=\"nofollow ugc noopener\">@Bartok9</a>)</li><li>Brice Figureau (<a href=\"https://github.com/masterzen\" rel=\"nofollow ugc noopener\">@masterzen</a>)</li><li>Bryan O&#39;Sullivan (<a href=\"https://github.com/bos\" rel=\"nofollow ugc noopener\">@bos</a>)</li><li>Caleb White (<a href=\"https://github.com/calebdw\" rel=\"nofollow ugc noopener\">@calebdw</a>)</li><li>David Rieber (<a href=\"https://github.com/drieber\" rel=\"nofollow ugc noopener\">@drieber</a>)</li><li>Farid Zakaria (<a href=\"https://github.com/fzakaria\" rel=\"nofollow ugc noopener\">@fzakaria</a>)</li><li>Gabriel Goller (<a href=\"https://github.com/kaffarell\" rel=\"nofollow ugc noopener\">@kaffarell</a>)</li><li>Gasper Stukelj (<a href=\"https://github.com/mirkomartn\" rel=\"nofollow ugc noopener\">@mirkomartn</a>)</li><li>Jakub Stasiak (<a href=\"https://github.com/jstasiak\" rel=\"nofollow ugc noopener\">@jstasiak</a>)</li><li>JamBalaya56562 (<a href=\"https://github.com/JamBalaya56562\" rel=\"nofollow ugc noopener\">@JamBalaya56562</a>)</li><li>Joseph Lou (<a href=\"https://github.com/josephlou5\" rel=\"nofollow ugc noopener\">@josephlou5</a>)</li><li>Karnajeet Gosavi (<a href=\"https://github.com/kg290\" rel=\"nofollow ugc noopener\">@kg290</a>)</li><li>LOG (<a href=\"https://github.com/logarithmone1128\" rel=\"nofollow ugc noopener\">@logarithmone1128</a>)</li><li>Martin von Zweigbergk (<a href=\"https://github.com/martinvonz\" rel=\"nofollow ugc noopener\">@martinvonz</a>)</li><li>Matt Stark (<a href=\"https://github.com/matts1\" rel=\"nofollow ugc noopener\">@matts1</a>)</li><li>Mustafa Officewala (<a href=\"https://github.com/genericusername2709\" rel=\"nofollow ugc noopener\">@genericusername2709</a>)</li><li>pederbe (<a href=\"https://github.com/pederbe\" rel=\"nofollow ugc noopener\">@pederbe</a>)</li><li>Philip Metzger (<a href=\"https://github.com/PhilipMetzger\" rel=\"nofollow ugc noopener\">@PhilipMetzger</a>)</li><li>Pro (<a href=\"https://github.com/twistedfall\" rel=\"nofollow ugc noopener\">@twistedfall</a>)</li><li>Remo Senekowitsch (<a href=\"https://github.com/senekor\" rel=\"nofollow ugc noopener\">@senekor</a>)</li><li>Sami Hiltunen (<a href=\"https://github.com/SamiHiltunen\" rel=\"nofollow ugc noopener\">@SamiHiltunen</a>)</li><li>sofia (<a href=\"https://github.com/badp\" rel=\"nofollow ugc noopener\">@badp</a>)</li><li>Stephen Jennings (<a href=\"https://github.com/jennings\" rel=\"nofollow ugc noopener\">@jennings</a>)</li><li>Vincent Ging Ho Yim (<a href=\"https://github.com/cenviity\" rel=\"nofollow ugc noopener\">@cenviity</a>)</li><li>xtqqczze (<a href=\"https://github.com/xtqqczze\" rel=\"nofollow ugc noopener\">@xtqqczze</a>)</li><li>Yannik Sander (<a href=\"https://github.com/ysndr\" rel=\"nofollow ugc noopener\">@ysndr</a>)</li><li>Yuya Nishihara (<a href=\"https://github.com/yuja\" rel=\"nofollow ugc noopener\">@yuja</a>)</li></ul>","headings":[{"level":3,"text":"About","id":"about"},{"level":3,"text":"Release highlights","id":"release-highlights"},{"level":3,"text":"Breaking changes","id":"breaking-changes"},{"level":3,"text":"New features","id":"new-features"},{"level":3,"text":"Fixed bugs","id":"fixed-bugs"},{"level":3,"text":"Contributors","id":"contributors"}]}}