Breaking changes
-
The minimum supported Rust version (MSRV) is now 1.71.0.
-
The storage format of branches, tags, and git refs has changed. Newly-stored
repository data will no longer be loadable by older binaries. -
The
:
revset operator is deprecated. Use::
instead. We plan to delete the
:
form in jj 0.15+. -
The
--allow-large-revsets
flag forjj rebase
andjj new
was replaced by
aall:
before the revset. For example, usejj rebase -d 'all:foo-'
instead ofjj rebase --allow-large-revsets -d 'foo-'
. -
The
--allow-large-revsets
flag forjj rebase
andjj new
can no longer be
used for allowing duplicate destinations. Include the potential duplicates
in a single expression instead (e.g.jj new 'all:x|y'
). -
The
push.branch-prefix
option was renamed togit.push-branch-prefix
. -
The default editor on Windows is now
Notepad
instead ofpico
. -
jj
will fail attempts to snapshot new files larger than 1MiB by default. This behavior
can be customized with thesnapshot.max-new-file-size
config option. -
Author and committer signatures now use empty strings to represent unset
names and email addresses. Theauthor
/committer
template keywords and
methods also return empty strings.
Older binaries may not warn user when attempting togit push
commits
with such signatures. -
In revsets, the working-copy or remote symbols (such as
@
,workspace_id@
,
andbranch@remote
) can no longer be quoted as a unit. If a workspace or
branch name contains whitespace, quote the name like"branch name"@remote
.
Also, these symbols will not be resolved as revset aliases or function
parameters. For example,author(foo@)
is now an error, and the revset alias
'revset-aliases.foo@' = '@'
will be failed to parse. -
The
root
revset symbol has been converted to functionroot()
. -
The
..x
revset is now evaluated toroot()..x
, which means the root commit
is no longer included. -
jj git push
will now push all branches in the rangeremote_branches()..@
instead of only branches pointing to@
or@-
. -
It's no longer allowed to create a Git remote named "git". Use
jj git remote rename
to rename the existing remote.
#1690 -
Revset expression like
origin/main
will no longer resolve to a
remote-tracking branch. Usemain@origin
instead.
New features
-
Default template for
jj log
now does not show irrelevant information
(timestamp, empty, message placeholder etc.) about the root commit. -
Commit templates now support the
root
keyword, which istrue
for the root
commit andfalse
for every other commit. -
jj init --git-repo
now works with bare repositories. -
jj config edit --user
andjj config set --user
will now pick a default
config location if no existing file is found, potentially creating parent directories. -
jj log
output is now topologically grouped.
#242 -
jj git clone
now supports the--colocate
flag to create the git repo
in the same directory as the jj repo. -
jj restore
gained a new option--changes-in
to restore files
from a merge revision's parents. This undoes the changes thatjj diff -r
would show. -
jj diff
/log
now supports--tool <name>
option to generate diffs by
external program. For configuration, see the documentation.
#1886 -
A new experimental diff editor
meld-3
is introduced that sets up Meld to
allow you to see both sides of the original diff while editing. This can be
used withjj split
,jj move -i
, etc. -
jj log
/obslog
/op log
now supports--limit N
option to show the first
N
entries. -
Added the
ui.paginate
option to enable/disable pager usage in commands -
jj checkout
/jj describe
/jj commit
/jj new
/jj squash
can take repeated
-m/--message
arguments. Each passed message will be combined into paragraphs
(separated by a blank line) -
It is now possible to set a default description using the new
ui.default-description
option, to use when describing changes with an empty
description. -
jj split
will now leave the description empty on the second part if the
description was empty on the input commit. -
branches()
/remote_branches()
/author()
/committer()
/description()
revsets now support exact matching. For example,branch(exact:main)
selects the branch named "main", but not "maint".description(exact:"")
selects commits whose description is empty. -
Revsets gained a new function
mine()
that aliasesauthor(exact:"your_email")
. -
Added support for
::
and..
revset operators with both left and right
operands omitted. These expressions are equivalent toall()
and~root()
respectively. -
jj log
timestamp format now accepts.utc()
to convert a timestamp to UTC. -
templates now support additional string methods
.starts_with(x)
,.ends_with(x)
.remove_prefix(x)
,.remove_suffix(x)
, and.substr(start, end)
. -
jj next
andjj prev
are added, these allow you to traverse the history
in a linear style. For people coming from Sapling andgit-branchles
see #2126 for
further pending improvements. -
jj diff --stat
has been implemented. It shows a histogram of the changes,
same asgit diff --stat
. Fixes #2066 -
jj git fetch --all-remotes
has been implemented. It fetches all remotes
instead of just the default remote
Fixed bugs
-
Fix issues related to .gitignore handling of untracked directories
#2051. -
jj config set --user
andjj config edit --user
can now be used outside of any repository. -
SSH authentication could hang when ssh-agent couldn't be reached
#1970 -
SSH authentication can now use ed25519 and ed25519-sk keys. They still need
to be password-less. -
Git repository managed by the repo tool can now be detected as a "colocated"
repository.
#2011
Contributors
Thanks to the people who made this release happen!
- Alexander Potashev (@aspotashev)
- Anton Bulakh (@necauqua)
- Austin Seipp (@thoughtpolice)
- Benjamin Brittain (@benbrittain)
- Benjamin Saunders (@Ralith)
- Christophe Poucet (@poucet)
- Emily Kyle Fox (@emilykfox)
- Glen Choo (@chooglen)
- Ilya Grigoriev (@ilyagr)
- Kevin Liao (@kevincliao)
- Linus Arver (@listx)
- Martin Clausen (@maacl)
- Martin von Zweigbergk (@martinvonz)
- Matt Freitas-Stavola (@mbStavola)
- Oscar Bonilla (@ob)
- Philip Metzger (@PhilipMetzger)
- Piotr Kufel (@qfel)
- Preston Van Loon (@prestonvanloon)
- Tal Pressman (@talpr)
- Vamsi Avula (@avamsi)
- Vincent Breitmoser (@Valodim)
- Vladimir (@0xdeafbeef)
- Waleed Khan (@arxanas)
- Yuya Nishihara (@yuja)
- Zachary Dremann (@Dr-Emann)