Releases: jj-vcs/jj
Release list
v0.44.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
- Support for fetching and pushing tags has now been stabilized. Tags can be
tracked or untracked just like bookmarks. Tracked tags are pushed by default.
Breaking changes
-
jj git fetchnow fetches tags the same way it fetches bookmarks. Tags are
fetched as<name>@<remote>, and these remote tags are automatically tracked
by local tags of the same name. Runningjj git fetchin an existing
repository will re-fetch all tags to initialize the tracking state.Git's
tagOptis no longer respected. To disable tag fetching, set
remotes.<name>.fetch-tags = '~*'in the jj configuration. -
jj git clone --fetch-tags=all|none|includedis removed in favor of
--tag=PATTERN. -
jj git push --allnow pushes all tags in addition to bookmarks. -
The
WorkspaceRef.root()andRepoPath.absolute()template functions now
returnOption<FsPath>andFsPathrespectively, instead ofString. The
pathkeyword injj config listtemplates now returnsOption<FsPath>. -
jj file searchnow prints every matched line prefixed by the file path,
instead of only the file paths of files containing a match. Use
--name-onlyfor the previous behavior.
#9399 -
Passing an argument more than once is no longer an error. The last occurrence
wins, sojj --no-pager --no-pager versionandjj log -n 5 -n 10now work,
and an argument baked into an alias or a wrapper can be given explicitly as
well. Arguments that can be specified multiple times, such as--configand
jj log -r, are unaffected and still collect all of their values.
#8101
#9859
Deprecations
None
New features
-
New
merge_point()revset function which (similar tofork_point) finds the
point where multiple branches merge. -
jj workspace listnow shows workspace roots by default. The output can be
customized withtemplates.workspace_listor-T, andWorkspaceRef.root()
returns an optionalFsPathvalue.
#9713,
#9826 -
New
try(expr, fallback...)template function to suppress runtime errors. -
jj runnow processes revisions from oldest to newest by default. The start
order is guaranteed: each revision begins execution only after the previous
one has started, even with--jobshigher than 1. -
jj rungained a--passthroughflag that connects the subprocess's
stdout/stderr directly to the terminal instead of capturing output. -
jj rungained a--ignore-changesflag to avoid editing any revisions even
if the command modifies the working copy. -
jj rungained a--ignore-errorsflag to continue running against the
remaining revisions even if the command exits with a nonzero exit code. -
jj file searchnow supports-n/--line-numberto prefix each match with
its 1-based line number within the file. -
jj git pushgained a--allow-conflictsflag to allow pushing commits
containing conflicts. -
New
jj tag track/untrackcommands to associate local tags with remotes.
Note that fetched tags are tracked by default. -
Added
builtin_log()revset alias for the built-in defaultjj logrevset.
revsets.lognow defaults tobuiltin_log(), so custom log revsets can
reuse the built-in default instead of copying its full expression. -
Added config option
diff.stat.max-bar-widthfor use with--statto limit
the++--bar width. In the templating language,diff.stat()can optionally
take a second (positional or named) argumentmax_bar_widthfor an equivalent
effect. -
jj absorbnow supports--interactive/-i/--toolto let you
interactively choose which hunks from the source to consider for absorption.
This is useful when you only want to absorb part of a commit without first
splitting it. Any hunks that are not selected or cannot be absorbed remain in
the source commit.
Fixed bugs
-
Recursive alias definitions are detected more precisely. jj can now expand
aliases that are simply repeated. For example, with the aliasjj = [], the
commandjj jj jjwill resolve tojj. Aliases can also fall back to the
default command. For example, with the aliasi = ["--ignore-working-copy"],
jj iwill resolve tojj --ignore-working-copy. -
Git temporary files are now cleaned up more reliably in the presence of
signals (e.g.Ctrl-C). This should reduce the rate of "Could not acquire
lock for index file" errors.
(#7530) -
Fixed Git HEAD mismatch after the working copy became immutable.
#9827 -
jjnow creates a new working-copy revision as soon as the one of the current
workspace becomes immutable, as well as during snapshotting. This brings the
behavior closer tojj0.42 and earlier. -
Snapshotting no longer fails if the working copy contains a path whose name
isn't valid UTF-8. Such paths can't be tracked, so they are now skipped and
reported as a warning instead.
#9774 -
Fixed failure when reading configuration in copied repo with an empty
repo-level configuration directory. -
jj diffandjj statusno longer omit a rename or copy in a merge commit
when the renamed source is present in more than one parent. The identical copy
record reported for each parent was mistaken for a conflict and discarded.
#9752 -
jj runno longer panics when its revset includes a conflicted commit. The
conflict is now preserved in the rewritten commit.
#9747 -
Fixed a panic when passing overly-large length parameters to ID templater
functions (commit_id.short(),commit_id.shortest(), etc.).
#9833 -
jj git importandexportin colocated workspaces are now disabled by
default. These commands usually do nothing, but they had a race condition.
Contributors
Thanks to the people who made this release happen!
- Aaron Bies (@slerpyyy)
- Ada Alakbarova (@ada4a)
- Alexandre Hallaine (@alexandre-hallaine)
- Amaan Qureshi (@amaanq)
- Austin Seipp (@thoughtpolice)
- Caleb White (@calebdw)
- Chawye Hsu (@chawyehsu)
- David Rieber (@drieber)
- Gaëtan Lehmann (@glehmann)
- hexbinoct (@hexbinoct)
- ivelieu (@ivelieu)
- Joseph Lou (@josephlou5)
- Josh McKinney (@joshka)
- Josh Steadmon (@steadmon)
- Kevin Liao (@kevincliao)
- Luna Schwalbe (@lunagl)
- Martin von Zweigbergk (@martinvonz)
- Matt Van Horn (@mvanhorn)
- Nika Layzell (@mystor)
- Niko Savola (@nikosavola)
- Nitzan Raz (@BackSlasher)
- Noah Lev (@camelid)
- OlshaMB (@OlshaMB)
- Philip Metzger (@PhilipMetzger)
- Remo Senekowitsch (@senekor)
- Rob Pilling (@bobrippling)
- Stephen Jennings (@jennings)
- Techcable (@Techcable)
- TogarashiPepper (@TogarashiPepper)
- Vladimir Petrzhikovskii (@0xdeafbeef)
- Waleed Khan (@arxanas)
- Wang Yuantao (@0WD0)
- xtqqczze (@xtqqczze)
- Yash Bavadiya (@xevrion)
- Yuya Nishihara (@yuja)
v0.43.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
jj runallows you to run a command over a set of changes, each with their
own private working copy; the commands may update the working copy and
changes/conflicts are propagated accordingly, e.g.,jj run -- cargo check --all-featuresorjj run -- cargo fixbehaves as one might expect.
Breaking changes
-
The deprecated
git_head()andgit_refs()functions have been removed from
revsets and templates. -
Git-like symbols (e.g.
refs/heads/main) are no longer resolved to
revisions. Use the bookmark/tag<name>or<name>@<remote>syntax instead. -
The deprecated
ui.revsets-use-glob-by-defaultoption has been removed. -
jj bookmark track/untrackno longer supports<kind>:<bookmark>@<remote>
patterns. However, the<bookmark>@<remote>symbol syntax is still supported.
#9226
Deprecations
New features
-
jj shownow supports--reversedflag. -
jjnow looks for config files in/etc/jj. -
jj config gcwill delete configuration of deleted/moved repos from
~/.config/jj/reposfolder.
#9362 -
jj runallows you to run a command over a set of changes, each with their
own private working copy; the commands may update the working copy and
changes/conflicts are propagated accordingly, e.g.,jj run -- cargo check --all-featuresorjj run -- cargo fixbehaves as one might expect. -
jj gerrit uploadnow supports the-o(--option) flag, which works like
git push -o(--push-option). -
jj git fetchnow rebases the descendants of revisions that were rewritten
based on their change IDs. Previously, when multiple bookmarked revisions
existed in a stack, those rewritten revisions and their descendants wouldn't
always be rebased. Note that immutable descendants will not be rebased. -
Add a
forks()revset function that yields all commits with more than 1 child. -
colorsconfig now supports crossed-out text styling with
{ crossed-out = true }.
Fixed bugs
-
On Windows, querying a path's file identity no longer follows symbolic links,
matching the behavior on Unix. Previously a symlink shared the identity of its
target, so two symlinks pointing at the same target were treated as the same
file. This identity check is used when writing the working copy to detect
aliases of the reserved.gitand.jjdirectories.
#8924 -
jjnow creates a new working-copy revision during snapshotting if the
working copy was immutable. Previously, the new revision was created
immediately after the working copy became immutable.
#7751
#9338 -
jj git remote addnow warns if the new remote exactly matches an existing
remote's fetch URL or effective push URL.
#413 -
Fixed corrupt loose Git objects on Intel Raptor Lake CPU and aarch64.
Previously, jj could report a successful commit even thoughgit fsckwould
later fail withincorrect data check,corrupt loose object, ormissing blob, and later jj operations could fail withcorrupt deflate stream.
Contributors
Thanks to the people who made this release happen!
- adlerd (@adlerd)
- ase (@adamse)
- Atakan Yenel (@atakanyenel)
- Austin Seipp (@thoughtpolice)
- Benjamin Tan (@bnjmnt4n)
- David Rieber (@drieber)
- figsoda (@figsoda)
- Gaëtan Lehmann (@glehmann)
- hexbinoct (@hexbinoct)
- Jakub Stasiak (@jstasiak)
- Jonas Carpay (@jonascarpay)
- Joseph Lou (@josephlou5)
- Josh McKinney (@joshka)
- Josh Steadmon (@steadmon)
- Martin von Zweigbergk (@martinvonz)
- Matt Stark (@matts1)
- Philip Metzger (@PhilipMetzger)
- shoce (@shoce)
- Stephen Jennings (@jennings)
- Thomas Axelsson (@thomas-2nd)
- Vincent Ging Ho Yim (@cenviity)
- Yuya Nishihara (@yuja)
v0.42.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
- Switched to the mimalloc memory allocator for better multi-threaded
performance.
Breaking changes
-
The following deprecated command options have been removed:
jj commit --reset-author/--authorjj describe --no-edit/--edit/--reset-author/--authorjj git push --allow-newjj metaedit --update-committer-timestamp
-
The following deprecated config options have been removed:
git.auto-local-bookmarkgit.push-new-bookmarks
Deprecations
jj evologno longer supports legacy commit predecessors recorded injj<
0.30.
New features
-
Shell completions now surface descriptions for custom aliases,
revset-aliases, template-aliases, and fileset-aliases. Descriptions are
extracted from the.docfield of the alias definition if it is a table
with.docand.definitionproperties. -
jj shownow accepts multiple revisions, showing all of them one after the
other, behaving closer togit show. -
jj git fetchnow generates evolution history based on change IDs. If change
IDs are preserved by the remote, local descendant revisions will be rebased
onto the rewritten parents. -
Added
jj util backend namecommand that prints the commit backend being used
in the current repo. -
Added
edit-invocation-modeconfig option for diff editors (e.g.
jj diffedit,jj split). When set to"file-by-file", the editor is
launched once per changed file, making it possible to use per-file tools like
vimdifffor editing.
Fixed bugs
-
jj git remote addnow reports an error instead of panicking when the
remote name is empty or contains whitespace.
#9099 -
Color-words diffs are now shown as separate before and after lines when color
output is disabled, making piped or redirected diffs readable.
#5894 -
jj bookmark forgetno longer printsForgot N local bookmarks.when no
local bookmarks were actually forgotten (e.g. when only an untracked remote
bookmark matched). #9181. -
The
builtin_log_redactedtemplate now also redacts workspace names.
Contributors
Thanks to the people who made this release happen!
- Alex Jaspersen (@ajaspers)
- Archer (@archer-321)
- ase (@adamse)
- Austin Seipp (@thoughtpolice)
- David Rieber (@drieber)
- Eyüp Can Akman (@eyupcanakman)
- Jakub Stasiak (@jstasiak)
- James Dixon (@lemonase)
- Joseph Lou (@josephlou5)
- Laurynas Keturakis (@laulauland)
- Luna Schwalbe (@lunagl)
- Martin von Zweigbergk (@martinvonz)
- Niko Savola (@nikosavola)
- OlshaMB (@OlshaMB)
- Sergey Kasmy (@SergeyKasmy)
- truffle (@truffle-dev)
- Vincent Ging Ho Yim (@cenviity)
- Yuya Nishihara (@yuja)
v0.41.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
-
jj fixnow supports formatting specific line ranges (allowing you to format
only modified lines); see the configuration manual and notes below for more. -
The new global flag
--no-integrate-operationwill let you run a command without
impacting the repo state or the working copy, which is useful when automated tools
may create snapshots in the background.
Breaking changes
-
The
--patternflag forfile searchnow defaults toregex:instead ofglob:. -
jj git push --all/--tracked/-r REVSETSno longer fails when revisions to
push are private or have conflicts. Bookmarks which aren't eligible to push
will be skipped. -
Branch/bookmark patterns passed to
jj git cloneare now saved to jj's repo
settings file instead of.git/config. Git fetch refspecs are set to the
default value.
Deprecations
- In the templating language, the
Operationtype's.tags()function has been
deprecated in favor of.attributes().
New features
-
The
--patternflag forfile searchnow accepts various pattern kinds through
kind:patternsyntax. -
A new global flag
--no-integrate-operationlets you run a command without
impacting the repo state or the working copy. -
A new config option
diff.git.show-path-prefixcan be used to suppress the
a/andb/path prefixes in thediff --gitoutput. -
jj fixnow supports line range-limited formatting via thefix.tools.<name>.line-range-arg
andrun-tool-if-zero-line-rangesconfigs. This allows running tools only on modified
lines and fine-grained control over when the tool is run. If you have set theline-range-arg
config, use--all-linesto match the previous behavior of formatting the entire file. -
A new
replace(pattern, content, replacement)template function is added
which supports replacement of content in templates, using a lambda to format
replacement text. It supports all string patterns, including regexes with
capture groups (e.g.replace(regex:'(\w+) (\w+)', "hello world", |c| c.get(1) ++ " " ++ c.get(2))). -
New
ByteStringtemplate type for things like file content. -
jj gerrit uploadnow supports the new options--message(-m),--edit
and--merged. You can now also pass multiple hashtags by repeating the
--hashtagoption. -
New
remotes.<name>.fetch-bookmarks/fetch-tagsoptions to configure
default fetch targets. -
JJ_PAGERcan now override theui.pagerconfig, matchingJJ_EDITORfor
callers that need a jj-specific environment override.
Fixed bugs
-
Improving consistency with
githandling of.gitignore, including/
after entries and\r\r\nfor MacOS files. -
jj statusfilters untracked paths by fileset
#9287 -
Improved performance for snapshotting, visibly improving
jj status
speed for large repositories. -
Pre-existing Git submodule directories are no longer considered conflicts in
checkouts. #8065. -
Fixed a panic in
jj gerrit uploadwhen run without-rand the
inferred revision was immutable. #9398 -
jj statusrespects path filters in working copy summaries. -
jj git remote rename/removenow updates thetrunk()alias. -
Commands would sometimes incorrectly diagnose a stale working copy and suggest
runningjj op integratewhen it would have no effect. This should now be
much less likely to happen in practice.
#9314
Contributors
Thanks to the people who made this release happen!
- Adrian Freund (@freundTech)
- ase (@adamse)
- Austin Seipp (@thoughtpolice)
- Benjamin Tan (@bnjmnt4n)
- Björn Kautler (@Vampire)
- David Higgs (@higgsd)
- David Rieber (@drieber)
- dzaima (@dzaima)
- Federico G. Schwindt (@fgsch)
- Gaëtan Lehmann (@glehmann)
- hewigovens (@hewigovens)
- Ilya Grigoriev (@ilyagr)
- jonmeow (@jonmeow)
- Joseph Lou (@josephlou5)
- Josh McKinney (@joshka)
- Jun Mukai (@jmuk)
- Lucas Garron (@lgarron)
- Martin von Zweigbergk (@martinvonz)
- Matt Stark (@matts1)
- Maximilian Gaß (@mxey)
- OlshaMB (@OlshaMB)
- Philip Metzger (@PhilipMetzger)
- rayaq
- Remo Senekowitsch (@senekor)
- rishiad (@rishiad)
- Ryan Patterson (@CGamesPlay)
- Sebastian Barfurth (@sbarfurth)
- Thomas Axelsson (@thomasa88)
- xtqqczze (@xtqqczze)
- Yuya Nishihara (@yuja)
v0.40.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
None
Breaking changes
None
Deprecations
None
New features
-
New
diff_lines_added()anddiff_lines_removed()revset functions for
matching content on only one side of a diff. -
The
endparameter in theString.substr(start, end)templating method is
now optional. If not given,substr()returns fromstartto the end of the
string. -
WorkspaceReftemplates now provide a.root()method to show the absolute
path to each workspace root. -
The
jj arrangeTUI now includes immediate parents and children. They are not
selectable and are dimmed by default. -
jj arrangeuses the default log template (builtin_log_compact) instead of
the shorter commit summary style. -
In the
jj arrangeTUI, the "swap up/down" actions now move along graph edges
even if the commit rows are not adjacent. -
Diff colors can now be configured
differently for each format. -
jj op lognow includes the name of the workspace the operation was created
from. -
The
config()template function now accepts aStringifyexpression instead
ofLiteralString. This allows looking up configuration values dynamically. -
jj op show,jj op diff,jj op log -pnow only show "interesting"
revisions by default (defined byrevsets.op-diff-changes-in). A new flag,
--show-changes-in, can be used to override this. #6083
Fixed bugs
-
.gitignorewith UTF-8 BOM can now be parsed correctly. -
Fix incompatibility with gpgsm 2.5.x.
Contributors
Thanks to the people who made this release happen!
- Aaron Sutton (@aaronjsutton)
- Adam Sandberg Eriksson (@adamse)
- Anton Älgmyr (@algmyr)
- Austin Seipp (@thoughtpolice)
- Benjamin Tan (@bnjmnt4n)
- Ben Warren (@warrenbhw)
- Bryant Chandler (@brychanrobot)
- David Higgs (@higgsd)
- Filip Weiss (@fiws)
- Gabriel Goller (@kaffarell)
- Gaëtan Lehmann (@glehmann)
- Ilya Grigoriev (@ilyagr)
- Jeff Turner (@jefft)
- Joseph Lou (@josephlou5)
- Josh Steadmon (@steadmon)
- KITAGAWA Yasutaka (@kit494way)
- Liam (@terror)
- Li-Wen Hsu (@lwhsu)
- Martin von Zweigbergk (@martinvonz)
- Philip Metzger (@PhilipMetzger)
- Poliorcetics (@poliorcetics)
- Remo Senekowitsch (@senekor)
- Rob Pilling (@bobrippling)
- Scott Taylor (@scott2000)
- Shnatu
- Stephen Prater (@stephenprater)
- Yuya Nishihara (@yuja)
- Zeyi Fan (@fanzeyi)
v0.39.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
-
jj arrangecommand brings up a TUI where you can reorder and abandon
revisions. #1531 -
jj bookmark advanceautomatically moves bookmarks forward to a
target revision (defaults to@) using customization points
revsets.bookmark-advance-fromandrevsets.bookmark-advance-to.
It is heavily inspired by the longstanding community aliasjj tug.
Breaking changes
-
Dropped support for legacy index files written by jj < 0.33. New index files
will be created as needed. -
The following deprecated config options have been removed:
core.fsmonitorcore.watchman.register-snapshot-trigger
-
The deprecated command
jj op undohas been removed. Usejj op revertor
jj undo/redoinstead.
Deprecations
jj debug snapshotis deprecated in favor ofjj util snapshot. Although
this was an undocumented command in the first place, it will be removed after
6 months (v0.45.0) to give people time to migrate away.
New features
-
Add support for push options in
jj git pushwith the--optionflag.
This allows users to pass options to the remote server when pushing commits.
The short alias-ois also supported. -
jj newnow evaluates thenew_descriptiontemplate to populate the
initial commit description when no-mmessage is provided. -
Templates now support
first(),last(),get(index),reverse(),
skip(count), andtake(count)methods on list types for more flexible
list manipulation. -
New
builtin_draft_commit_description_with_difftemplate that includes the
diff in the commit description editor, making it easier to review changes
while writing commit messages. -
Revsets and templates now support
name:xpattern aliases such as'grep:x' = 'description(regex:x)'. -
Filesets now support user aliases.
-
jj workspace addnow links with relative paths. This enables workspaces to work
inside containers or when moved together. Existing workspaces with absolute paths
will continue to work as before. -
jj undonow also outputs what operation was undone, in addition to the
operation restored to. -
Bookmarks with two or more consecutive
-characters no longer need to be quoted
in revsets. For example,jj diff -r '"foo--bar"'can now be written asjj diff -r foo--bar. -
New flag
--simplify-parentsonjj rebaseto apply the same transformation
asjj simplify-parentson the rebased commits.
#7711 -
jj rebase --branchandjj rebase --sourcewill no longer return an error
if the given argument resolves to an empty revision set
(jj rebase --revisionsalready behaved this way). Instead, a message will be
printed to inform the user why nothing has changed. -
Changed Git representation of conflicted commits to include files from the
first side of the conflict. This should prevent unchanged files from being
highlighted as "added" in editors when checking out a conflicted commit in a
colocated workspace. -
New template function
Timestamp::since(ts)that returns theTimestampRange
between two timestamps. It can be used in conjunction with.duration()in
order to obtain a human-friendly duration between twoTimestamps. -
Added new
jj util snapshotcommand to manually or programmatically trigger a
snapshot. This introduces an official alternative to the
previously-undocumentedjj debug snapshotcommand. The Watchman integration
has also been updated to use this command instead. -
Changed background snapshotting to suppress stdout and stderr to avoid long
hangs. -
jj gerrit uploadnow supports a variety of new flags documented in
gerrit's documentation.
This includes, for example,--reviewer=foo@example.comand
--label=Auto-Submit. -
jj gerrit uploadnow recognizes Change-Id explicitly set via the alternative
trailerLink, and will generate aLink: <review-url>/id/<change-id>trailer
ifgerrit.review-urloption is set. -
jj gerrit uploadno longer requires the-rflag, and will default to
uploading what you're currently working on. -
Templates now support
Serializeoperations on the result ofmap()and
if(), when supported by the underlying type. -
jj bookmark renamenow supports--overwrite-existingto allow renaming a
bookmark even if the new name already exists, effectively replacing the
existing bookmark. -
Conditional configuration based on environment variables with
--when.environments.
#8779
Fixed bugs
-
Windows: use native file locks (
LockFileEx) instead of polling with file
creation, fixing issues with "pending delete" semantics leaving lock files
stuck. -
jjnow safely detaches theHEADof alternate Git worktrees if their
checked-out branch is moved or deleted during Git export. -
jj file track --include-ignorednow works whenfsmonitor.backend="watchman".
#8427
Contributors
Thanks to the people who made this release happen!
- Aaron Christiansen (@AaronC81)
- Andy Brenneke (@abrenneke)
- Anton Älgmyr (@algmyr)
- Austin Seipp (@thoughtpolice)
- Benjamin Tan (@bnjmnt4n)
- Bram Geron (@bgeron)
- Bryce Berger (@bryceberger)
- Caleb White (@calebdw)
- countskm (@countdigi)
- David Higgs (@higgsd)
- Evan Simmons (@estk)
- Fedor Sheremetyev (@sheremetyev)
- Gaëtan Lehmann (@glehmann)
- George Christou (@gechr)
- Hubert Lefevre (@Paluche)
- Ian (@chronologos)
- Ilya Grigoriev (@ilyagr)
- Jaen (@jaens)
- Joseph Lou (@josephlou5)
- Josh Steadmon (@steadmon)
- Martin von Zweigbergk (@martinvonz)
- Matt Kulukundis (@fowles)
- Matt Stark (@matts1)
- max (@pr2502)
- Nika Layzell (@mystor)
- Philip Metzger (@PhilipMetzger)
- Richard Smith (@zygoloid)
- Scott Taylor (@scott2000)
- Steve Klabnik (@steveklabnik)
- Theodore Dubois (@tbodt)
- William Phetsinorath (@shikanime)
- xtqqczze (@xtqqczze)
- Yuya Nishihara (@yuja)
v0.38.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
- Per-repo and per-workspace config is now stored outside the repo, for security
reasons. This is not a breaking change because we automatically migrate
legacy repos to this new format..jj/repo/config.tomland
.jj/workspace-config.tomlshould no longer be used.
Breaking changes
-
The minimum supported
gitcommand version is now 2.41.0. macOS users will
need to either upgrade "Developer Tools" to 26 or install Git from
e.g. Homebrew. -
Deprecated
ui.always-allow-large-revsetssetting andall:revset modifier
have been removed. -
<name>@<remote>revset symbols can also be resolved to remote tags. Tags are
prioritized ahead of bookmarks. -
Legacy placeholder support used for unset
user.nameoruser.emailhas been
removed. Commits containing these values will now be pushed withjj git push
without producing an error. -
If any side of a conflicted file is missing a terminating newline, then the
materialized file in the working copy will no longer be terminated by a
newline.
Deprecations
- The revset function
diff_contains()has been renamed todiff_lines().
New features
-
jj git fetchnow shows details of abandoned commits (change IDs and
descriptions) by default, matching thejj abandonoutput format.
#3081 -
jj workspace rootnow accepts an optional--nameargument to show
the root path of the specified workspace (defaults to the current one). When
given a workspace that was created before this release, it errors out. -
jj git push --bookmark <name>will now automatically track the bookmark if
it isn't tracked with any remote already. -
Add
git_web_url([remote])template function that converts a git remote URL
to a web URL, suitable for opening in a browser. Defaults to the "origin"
remote. -
New
divergent()revset function for divergent changes. -
String pattern values in revsets and templates can now be substituted by
aliases. For example,grep(x) = description(regex:x)now works. -
A new config option
remotes.<name>.auto-track-created-bookmarksbehaves
similarly toauto-track-bookmarks, but it only applies to bookmarks created
locally. Setting it to"*"is now the closest replacement for the deprecated
git.push-new-bookmarksoption. -
jj tag listcan now be filtered by revset. -
Conflict markers will use LF or CRLF as the line ending according to the
contents of the file.
#7376 -
New experimental
jj git fetch --tagflag to fetch tags in the same way as
bookmarks. If specified, tags won't be fetched implicitly, and only tags
matching the pattern will be fetched as<name>@<remote>tags. The fetched
remote tags will be tracked by the local tags of the same name. -
New
remote_tags()revset function to query remote tags. -
New builtin
hyperlink()template function that gracefully falls back to
text when outputting to a non-terminal, instead of emitting raw OSC 8 escape
codes. #7592
Fixed bugs
-
jj git init --colocatenow refuses to run inside a Git worktree, providing
a helpful error message with alternatives.
#8052 -
jj git pushnow ensures that tracked remote bookmarks are updated even if
there are no mappings in the Git fetch refspecs.
#5115 -
jj git fetch/pushnow forwards most ofgitstderr outputs such as
authentication requests. #5760 -
Conflicted bookmarks and tags in
trunk()will no longer generate verbose
warnings. The configuredtrunk()alias will temporarily be disabled.
#8501 -
Dynamic shell completion for
jj config unsetnow only completes
configuration options which are set.
#7774 -
Dynamic shell completion no longer attempts to resolve aliases at the
completion position. This previously prevented a fully-typed alias from
being accepted on some shells and replaced it entirely with its expansion on
bash. Now, the completion will only resolve the alias, and suggest candidates
accordingly, after the cursor has been advanced to the next position.
#7773 -
Setting the editor via
ui.editor,$EDITOR, orJJ_EDITORnow respects shell quoting. -
jj gerrit uploadwill no longer swallow errors and surface if changes fail
to get pushed to gerrit.
#8568 -
jj file track --include-ignorednow works whenfsmonitor.backend="watchman".
#8427 -
Conflict labels are now preserved correctly when restoring files from commits
with different conflict labels. -
The empty tree is now always written when the working copy is empty.
#8480 -
When using the Watchman filesystem monitor, changes to .gitignore now trigger
a scan of the affected subtree so newly unignored files are discovered.
#8427 -
--quietnow hides progress bars.
Contributors
Thanks to the people who made this release happen!
- Benjamin Davies (@Benjamin-Davies)
- Bryce Berger (@bryceberger)
- Chris Rose (@offbyone)
- Daniel Morsing (@DanielMorsing)
- David Fröhlingsdorf (@2079884FDavid)
- David Higgs (@higgsd)
- David Rieber (@drieber)
- Federico G. Schwindt (@fgsch)
- Gaëtan Lehmann (@glehmann)
- George Christou (@gechr)
- itstrivial
- Jeff Turner (@jefft)
- Jonas Greitemann (@jgreitemann)
- Jonas Helgemo (@jonashelgemo)
- Joseph Lou (@josephlou5)
- Kaiyi Li (@06393993)
- Lukas Wirth (@Veykril)
- Martin von Zweigbergk (@martinvonz)
- Matt Stark (@matts1)
- Paul Smith (@paulsmith)
- Pavan Kumar Sunkara (@pksunkara)
- Philip Metzger (@PhilipMetzger)
- Remo Senekowitsch (@senekor)
- Sami Jawhar (@sjawhar)
- Scott Taylor (@scott2000)
- Simone Cattaneo (@simonecattaneo91)
- Steve Klabnik (@steveklabnik)
- tom (@lecafard)
- Vincent Ging Ho Yim (@cenviity)
- _WD_ (@0WD0)
- xtqqczze (@xtqqczze)
- Yuya Nishihara (@yuja)
- yz (@yzheng453)
v0.37.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
-
A new syntax for referring to hidden and divergent change IDs is available:
xyz/nwherenis a number. For instance,xyz/0refers to the latest
version ofxyz, whilexyz/1refers to the previous version ofxyz.
This allows you to perform actions likejj restore --from xyz/1 --to xyzto
restorexyzto its previous contents, if you made a mistake.For divergent changes, the numeric suffix will always be shown in the log,
allowing you to disambiguate them in a similar manner.
Breaking changes
-
String patterns in revsets, command
arguments, and configuration are now parsed as globs by default. Use
substring:orexact:prefix as needed. -
remotes.<name>.auto-track-bookmarksis now parsed the same way they
are in revsets and can be combined with logical operators. -
jj bookmark track/untracknow accepts--remoteargument. If omitted, all
remote bookmarks matching the bookmark names will be tracked/untracked. The
old<bookmark>@<remote>syntax is deprecated in favor of<bookmark> --remote=<remote>. -
On Windows, symlinks that point to a path with
/won't be supported. This
path is invalid on Windows. -
The template alias
format_short_change_id_with_hidden_and_divergent_info(commit)
has been replaced byformat_short_change_id_with_change_offset(commit). -
The following deprecated config options have been removed:
git.push-bookmark-prefixui.default-descriptionui.diff.formatui.diff.tool
-
The deprecated
commit_id.normal_hex()template method has been removed. -
Template expansion that did not produce a terminating newline will not be
fixed up to provide one byjj log,jj evolog, orjj op log. -
The
diffconflict marker style can now use\\\\\\\markers to indicate
the continuation of a conflict label from the previous line.
Deprecations
- The
git_head()andgit_refs()functions will be removed from revsets and
templates.git_head()should point to thefirst_parent(@)revision in
colocated repositories.git_refs()can be approximated as
remote_bookmarks(remote=glob:*) | tags().
New features
-
Updated the executable bit representation in the local working copy to allow
ignoring executable bit changes on Unix. By default we try to detect the
filesystem's behavior, but this can be overridden manually by setting
working-copy.exec-bit-change = "respect" | "ignore". -
jj workspace addnow also works for empty destination directories. -
jj git remotefamily of commands now supports different fetch and push URLs. -
[colors]table now supportsdim = trueattribute. -
In color-words diffs, context line numbers are now rendered with decreased
intensity. -
Hidden and divergent commits can now be unambiguously selected using their
change ID combined with a numeric suffix. For instance, if there are two
commits with change IDxyz, then one can be referred to asxyz/0and the
other can be referred to asxyz/1. These suffixes are shown in the log when
necessary to make a change ID unambiguous. -
jj util gcnow prunes unreachable files in.jj/repo/store/extrato save
disk space. -
Early version of a
jj file searchcommand for searching for a pattern in
files (likegit grep). -
Conflict labels now contain information about where the sides of a conflict
came from (e.g.nlqwxzwn 7dd24e73 "first line of description"). -
--insert-beforenow accepts a revset that resolves to an empty set when
used with--insert-after. The behavior is similar to--onto. -
jj tag listnow supports--sortoption. -
TreeDiffEntrytype now has adisplay_diff_path()method that formats
renames/copies appropriately. -
TreeDiffEntrynow has astatus_char()method that returns
single-character status codes (M/A/D/C/R). -
CommitEvolutionEntrytype now has apredecessors()method which
returns the predecessor commits (previous versions) of the entry's commit. -
CommitEvolutionEntrytype now has ainter_diff()method which
returns aTreeDiffbetween the entry's commit and its predecessor version.
Optionally accepts a fileset literal to limit the diff. -
jj file annotatenow reports an error for non-files instead of succeeding
and displaying no content. -
jj workspace forgetnow warns about unknown workspaces instead of failing.
Fixed bugs
-
Broken symlink on Windows. #6934.
-
Fixed failure on exporting moved/deleted annotated tags to Git. Moved tags are
exported as lightweight tags. -
jj gerrit uploadnow correctly handles mixed explicit and implicit
Change-Ids in chains of commits (#8219) -
jj git pushnow updates partially-pushed remote bookmarks accordingly.
#6787 -
Fixed problem of loading large Git packfiles.
GitoxideLabs/gitoxide#2265 -
The builtin pager won't get stuck when stdin is redirected.
-
jj workspace addnow prevents creating an empty workspace name. -
Fixed checkout of symlinks pointing to themselves or
.git/.jjon Unix. The
problem would still remain on Windows if symlinks are enabled.
#8348 -
Fixed a bug where jj would fail to read git delta objects from pack files.
GitoxideLabs/gitoxide#2344
Contributors
Thanks to the people who made this release happen!
- Anton Älgmyr (@algmyr)
- Austin Seipp (@thoughtpolice)
- Bryce Berger (@bryceberger)
- Carlos Knippschild (@chuim)
- Cole Helbling (@cole-h)
- David Higgs (@higgsd)
- Eekle (@Eekle)
- Gaëtan Lehmann (@glehmann)
- Ian Wrzesinski (@isuffix)
- Ilya Grigoriev (@ilyagr)
- Julian Howes (@jlnhws)
- Kaiyi Li (@06393993)
- Lukas Krejci (@metlos)
- Martin von Zweigbergk (@martinvonz)
- Matt Stark (@matts1)
- Ori Avtalion (@salty-horse)
- Scott Taylor (@scott2000)
- Shaoxuan (Max) Yuan (@ffyuanda)
- Stephen Jennings (@jennings)
- Steve Fink (@hotsphink)
- Steve Klabnik (@steveklabnik)
- Theo Buehler (@botovq)
- Thomas Castiglione (@gulbanana)
- Vincent Ging Ho Yim (@cenviity)
- xtqqczze (@xtqqczze)
- Yuantao Wang (@0WD0)
- Yuya Nishihara (@yuja)
v0.36.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
-
The documentation has moved from https://jj-vcs.github.io/jj/ to
https://docs.jj-vcs.dev/.301 redirects are being issued towards the new domain, so any existing links
should not be broken. -
Fixed race condition that could cause divergent operations when running
concurrentjjcommands in colocated repositories. It is now safe to
continuously run e.g.jj logwithout--ignore-working-copyin one
terminal while you're running other commands in another terminal.
#6830 -
jjnow ignores$PAGERset in the environment and usesless -FRXon most
platforms (:builtinon Windows). See the docs for
more information, and #3502 for
motivation.
Breaking changes
-
In filesets or path patterns, glob matching
is enabled by default. You can usecwd:"path"to match literal paths. -
In the following commands, string pattern
arguments are now parsed the same way they
are in revsets and can be combined with logical operators:jj bookmark delete/forget/list/move,jj tag delete/list,jj git clone/fetch/push -
In the following commands, unmatched bookmark/tag names is no longer an
error. A warning will be printed instead:jj bookmark delete/forget/move/track/untrack,jj tag delete,jj git clone/push -
The default string pattern syntax in revsets will be changed to
glob:in a
future release. You can opt in to the new default by setting
ui.revsets-use-glob-by-default=true. -
Upgraded
scm-recordfrom v0.8.0 to v0.9.0. See release notes at
https://github.com/arxanas/scm-record/releases/tag/v0.9.0. -
The minimum supported Rust version (MSRV) is now 1.89.
-
On macOS, the deprecated config directory
~/Library/Application Support/jj
is not read anymore. Use$XDG_CONFIG_HOME/jjinstead (defaults to
~/.config/jj). -
Sub-repos are no longer tracked. Any directory containing
.jjor.git
is ignored. Note that Git submodules are unaffected by this.
Deprecations
-
The
--destination/-darguments forjj rebase,jj split,jj revert,
etc. were renamed to--onto/-o. The reasoning is that--onto,
--insert-before, and--insert-afterare all destination arguments, so
calling one of them--destinationwas confusing and unclear. The old names
will be removed at some point in the future, but we realize that they are
deep in muscle memory, so you can expect an unusually long deprecation period. -
jj describe --editis deprecated in favor of--editor. -
The config options
git.auto-local-bookmarkandgit.push-new-bookmarksare
deprecated in favor ofremotes.<name>.auto-track-bookmarks. For example:[remotes.origin] auto-track-bookmarks = "glob:*"
For more details, refer to
the docs. -
The flag
--allow-newonjj git pushis deprecated. In order to push new
bookmarks, please track them withjj bookmark track. Alternatively, consider
setting up an auto-tracking configuration to avoid the chore of tracking
bookmarks manually. For example:[remotes.origin] auto-track-bookmarks = "glob:*"
For more details, refer to
the docs.
New features
-
jj commit,jj describe,jj squash, andjj splitnow accept
--editor, which ensures an editor will be opened with the commit
description even if one was provided via--message/-m. -
All
jjcommands show a warning when the providedfilesetexpression
doesn't match any files. -
Added
files()template function toDiffStats. This supports per-file stats
likelines_added()andlines_removed() -
Added
join()template function. This is different fromseparate()in that
it adds a separator between all arguments, even if empty. -
RepoPathtemplate type now has aabsolute() -> Stringmethod that returns
the absolute path as a string. -
Added
format_path(path)template alias that controls how file paths are printed
withjj file list. -
New built-in revset aliases
visible()andhidden(). -
Unquoted
*is now allowed in revsets.bookmarks(glob:foo*)no longer
needs quoting. -
jj prev/next --no-editnow generates an error if the working-copy has some
children. -
A new config option
remotes.<name>.auto-track-bookmarkscan be set to a
string pattern. New bookmarks matching it will be automatically tracked for
the specified remote. See
the docs. -
jj lognow supports a--countflag to print the number of commits instead
of displaying them.
Fixed bugs
-
jj fixnow prints a warning if a tool failed to run on a file.
#7971 -
Shell completion now works with non‑normalized paths, fixing the previous
panic and allowing prefixes containing.or..to be completed correctly.
#6861 -
Shell completion now always uses forward slashes to complete paths, even on
Windows. This renders completion results viable when using jj in Git Bash.
#7024 -
Unexpected keyword arguments now return a parse failure for the
coalesce()
andconcat()templating functions. -
Nushell completion script documentation add
-foption, to keep it up to
date.
#8007 -
Ensured that with Git submodules, remnants of your submodules do not show up
in the working copy after runningjj new.
#4349
Contributors
Thanks to the people who made this release happen!
- abgox (@abgox)
- ase (@adamse)
- Björn Kautler (@Vampire)
- Bryce Berger (@bryceberger)
- Chase Naples (@cnaples79)
- David Higgs (@higgsd)
- edef (@edef1c)
- Evan Mesterhazy (@emesterhazy)
- Fedor (@sheremetyev)
- Gaëtan Lehmann (@glehmann)
- George Christou (@gechr)
- Hubert Lefevre (@Paluche)
- Ilya Grigoriev (@ilyagr)
- Jonas Greitemann (@jgreitemann)
- Joseph Lou (@josephlou5)
- Julia DeMille (@judemille)
- Kaiyi Li (@06393993)
- Kyle Lippincott (@spectral54)
- Lander Brandt (@landaire)
- Lucio Franco (@LucioFranco)
- Luke Randall (@lukerandall)
- Martin von Zweigbergk (@martinvonz)
- Matt Stark (@matts1)
- Mitchell Skaggs (@magneticflux-)
- Peter Schilling (@schpet)
- Philip Metzger (@PhilipMetzger)
- QingyaoLin (@QingyaoLin)
- Remo Senekowitsch (@senekor)
- Scott Taylor (@scott2000)
- Stephen Jennings (@jennings)
- Steve Klabnik (@steveklabnik)
- Tejas Sanap (@whereistejas)
- Tommi Virtanen (@tv42)
- Velociraptor115 (@Velociraptor115)
- Vincent Ging Ho Yim (@cenviity)
- Yuya Nishihara (@yuja)
v0.35.0
About
jj is a Git-compatible version control system that is both simple and powerful. See
the installation instructions to get started.
Release highlights
-
Workspaces can now have their own separate configuration. For instance, you
can usejj config set --workspaceto update a configuration option only in
the current workspace. -
After creating a local bookmark, it is now possible to use
jj bookmark track
to associate the bookmark with a specific remote before pushing it. When
pushing a tracked bookmark, it is not necessary to use--allow-new. -
The new
jj git colocation enableandjj git colocation disablecommands
allow converting between colocated and non-colocated workspaces.
Breaking changes
-
The
remote_bookmarks(remote=pattern)revset now includes Git-tracking
bookmarks if the specifiedpatternmatchesgit. The default is
remote=~exact:"git"as before. -
The deprecated flag
--summaryofjj abandonhas been removed. -
The deprecated command
jj backouthas been removed, usejj revertinstead. -
The following deprecated config options have been removed:
signing.sign-allcore.watchman.register_snapshot_triggerdiff.format
Deprecations
-
jj bisect run --command <cmd>is deprecated in favor of
jj bisect run -- <cmd>. -
jj metaedit --update-committer-timestampwas renamed to
jj metaedit --force-rewritesince the old name (and help text)
incorrectly suggested that the committer name and email would not
be updated.
New features
-
Workspaces may have an additional layered configuration, located at
.jj/workspace-config.toml.jj configsubcommands which took layer options
like--reponow also support--workspace. -
jj bookmark trackcan now associate new local bookmarks with remote.
Tracked bookmarks can be pushed without--allow-new.
#7072 -
The new
jj git colocationcommand provides sub-commands to show the
colocation state (status), to convert a non-colocated workspace into
a colocated workspace (enable), and vice-versa (disable). -
New
jj tag set/deletecommands to create/update/delete tags locally.
Created/updated tags are currently always exported to Git as lightweight
tags. If you would prefer them to be exported as annotated tags, please give
us feedback on #7908. -
Templates now support a
.split(separator, [limit])method on strings to
split a string into a list of substrings. -
-Gis now available as a short form of--no-graphinjj log,jj evolog,
jj op log,jj op showandjj op diff. -
jj metaeditnow accepts-m/--messageoption to non-interactively update
the change description. -
The
CryptographicSignature.key()template method now also works for SSH
signatures and returns the corresponding public key fingerprint. -
Added
template-aliases.empty_commit_marker. Users can override this value in
their config to change the "(empty)" label on empty commits. -
Add support for
--when.workspacesconfig scopes. -
Add support for
--when.hostnamesconfig scopes. This allows configuration to
be conditionally applied based on the hostname set inoperation.hostname. -
jj bisect runaccepts the command and arguments to pass to the command
directly as positional arguments, such as
jj bisect run --range=..main -- cargo check --all-targets. -
Divergent changes are no longer marked red in immutable revisions. Since the
revision is immutable, the user shouldn't take any action, so the red color
was unnecessarily alarming. -
New commit template keywords
local/remote_tagsto show only local/remote
tags. These keywords may be useful in non-colocated Git repositories where
local and exported@gittags can point to different revisions. -
jj git clonenow supports the--branchoption to specify the branch(es)
to fetch during clone. If present, the first matching branch is used as the
working-copy parent. -
Revsets now support logical operators in string patterns.
Fixed bugs
-
jj metaedit --author-timestamptwice with the same value no longer
edits the change twice in some cases. -
jj squash: fixed improper revision rebase when both--insert-afterand
--insert-beforewere used. -
jj undocan now revert "fetch"/"import" operation that involves tag updates.
#6325 -
Fixed parsing of
files(expr)revset expression including parentheses.
#7747 -
Fixed
jj describe --stdinto append a final newline character.
Contributors
Thanks to the people who made this release happen!
- Alpha Chen (@kejadlen)
- Angel Ezquerra (@AngelEzquerra)
- ase (@adamse)
- Austin Seipp (@thoughtpolice)
- Benjamin Brittain (@benbrittain)
- bipul (@bipulmgr)
- Brian Schroeder (@bts)
- Bryce Berger (@bryceberger)
- Cole Helbling (@cole-h)
- Daniel Luz (@mernen)
- David Higgs (@higgsd)
- Defelo (@Defelo)
- Fedor (@sheremetyev)
- Gabriel Goller (@kaffarell)
- Gaëtan Lehmann (@glehmann)
- George Christou (@gechr)
- Ilya Grigoriev (@ilyagr)
- Isaac Corbrey (@icorbrey)
- James Coman (@jamescoman)
- Joseph Lou (@josephlou5)
- Lander Brandt (@landaire)
- Martin von Zweigbergk (@martinvonz)
- Michael Chirico (@MichaelChirico)
- Owen Brooks (@owenbrooks)
- Peter Schilling (@schpet)
- Philip Metzger (@PhilipMetzger)
- Remo Senekowitsch (@senekor)
- Ross Smyth (@RossSmyth)
- Scott Taylor (@scott2000)
- Steve Fink (@hotsphink)
- Steve Klabnik (@steveklabnik)
- Theo Buehler (@botovq)
- Theodore Dubois (@tbodt)
- Theodore Keloglou (@sirodoht)
- Yuya Nishihara (@yuja)