v0.27.0

jj-vcs/jjv0.27.0Mar 6, 2025by ilyagr

AI Summary

This release focuses on Git compatibility by enabling the `git.subprocess` feature by default and introduces new signing and templating capabilities.

Key Highlights

  • Git subprocess is now enabled by default for improved fetch/push compatibility.
  • New `jj sign` and `jj unsign` commands allow for commit signing.
  • Templates now support new functions like `truncate_start`, `stringify`, and `trim`.
  • Help text is now colored when stdout is a terminal.

Breaking Changes

  • Bookmark names are now parsed as revset symbols.
  • `jj bookmark create`, `set`, and `move` now make hidden commits visible.
  • The `ui.allow-filesets` configuration option has been removed.
  • `templates.annotate_commit_summary` has been renamed to `templates.file_annotate`.

New Features

  • String pattern syntax support on `git fetch`.
  • Template functions for truncation and string manipulation.
  • Support for overriding stubs with aliases.
  • Undo operation hints suggesting `jj op restore`.

Full Release Notes

### About

jj is a Git-compatible version control system that is both simple and powerful. See the [installation instructions](https://jj-vcs.github.io/jj/v0.27.0/install-and-setup/) to get started.

### Release highlights

* `git.subprocess` is now enabled by default, improving compatibility with Git
  fetches and pushes by spawning an external `git` process. Users can opt out
  of this by setting `git.subprocess = false`, but this will likely be removed
  in a future release. Please report any issues you run into.

### Breaking changes

* Bookmark name to be created/updated is now parsed as [a revset
  symbol](docs/revsets.md#symbols). Quotation may be needed in addition to shell
  quotes. Example: `jj bookmark create -r@- "'name with space'"`

* `jj bookmark create`, `jj bookmark set` and `jj bookmark move` onto a hidden
   commit make it visible.

* `jj bookmark forget` now untracks any corresponding remote bookmarks instead
  of forgetting them, since forgetting a remote bookmark can be unintuitive.
  The old behavior is still available with the new `--include-remotes` flag.

* `jj fix` now always sets the working directory of invoked tools to be the
  workspace root, instead of the working directory of the `jj fix`.

* The `ui.allow-filesets` configuration option has been removed.
  [The "fileset" language](docs/filesets.md) has been enabled by default since v0.20.

* `templates.annotate_commit_summary` is renamed to `templates.file_annotate`,
  and now has an implicit `self` parameter of type `AnnotationLine`, instead of
  `Commit`. All methods on `Commit` can be accessed with `commit.method()`, or
  `self.commit().method()`.

### Deprecations

* This release takes the first steps to make target revision required in
  `bookmark create`, `bookmark move` and `bookmark set`. Those commands will display
  a warning if the user does not specify target revision  explicitly. In the near
  future those commands will fail if target revision is not specified.

* The `signing.sign-all` config option has been deprecated in favor of
  `signing.behavior`. The new option accepts `drop` (never sign), `keep` (preserve
  existing signatures), `own` (sign own commits), or `force` (sign all commits).
  Existing `signing.sign-all = true` translates to `signing.behavior = "own"`, and
  `false` translates to `"keep"`. Invalid configuration is now an error.

### New features

* The new `jj sign` and `jj unsign` commands allow for signing/unsigning commits.
  `jj sign` supports configuring the default revset through `revsets.sign` when
  no `--revisions` arguments are provided.

* `jj git fetch` now supports [string pattern syntax](docs/revsets.md#string-patterns)
  on `--remote` option and `git.fetch` configuration.

* Template functions `truncate_start()` and `truncate_end()` gained an optional
  `ellipsis` parameter; passing this prepends or appends the ellipsis to the
  content if it is truncated to fit the maximum width.

* Templates now support `stringify(x)` function and string method
  `.escape_json()`. The latter serializes the string in JSON format. It is
  useful for making machine-readable templates by escaping problematic
  characters like `\n`.

* Templates now support `trim()`, `trim_start()` and `trim_end()` methods
  which remove whitespace from the start and end of a `String` type.

* The description of commits backed out by `jj backout` can now be configured
  using `templates.backout_description`.

* New `AnnotationLine` templater type. Used in `templates.file_annotate`.
  Provides `self.commit()`, `.content()`, `.line_number()`, and
  `.first_line_in_hunk()`.

* Templates now have `format_short_operation_id(id)` function for users to
  customize the default operation id representation.

* The `jj init`/`jj revert` stubs that print errors can now be overridden with
  aliases. All of `jj clone/init/revert` add a hint to a generic error.

* Help text is now colored (when stdout is a terminal).

* Commands that used to suggest `--ignore-immutable` now print the number of
  immutable commits that would be rewritten if used and a link to the docs.

* `jj undo` now shows a hint when undoing an undo operation that the user may
   be looking for `jj op restore` instead.

### Fixed bugs

* `jj status` now shows untracked files under untracked directories.
  [#5389](https://github.com/jj-vcs/jj/issues/5389)

* Added workaround for the bug that untracked files are ignored when watchman is
  enabled. [#5728](https://github.com/jj-vcs/jj/issues/5728)

* The `signing.backends.ssh.allowed-signers` configuration option will now
  expand `~/` to `$HOME/`.
  [#5626](https://github.com/jj-vcs/jj/pull/5626)

* `config-schema.json` now allows arrays of strings for the settings `ui.editor`
  and `ui.diff.tool`.

* `config-schema.json` now allows an array of strings or nested table for the
  `ui.pager` setting.

### Contributors

Thanks to the people who made this release happen!

* Alain Leufroy (@aleufroy)
* Aleksey Kuznetsov (@zummenix)
* Alexander Mikhailov (@AM5800)
* Andrew Gilbert (@andyg0808)
* Antoine Martin (@alarsyo)
* Anton Bulakh (@necauqua)
* Austin Seipp (@thoughtpolice)
* Baltasar Dinis (@bsdinis)
* Benjamin Tan (@bnjmnt4n)
* Bryce Berger (@bryceberger)
* Burak Varlı (@unexge)
* David Rieber (@drieber)
* Emily (@emilazy)
* Evan Mesterhazy (@emesterhazy)
* George Christou (@gechr)
* HKalbasi (@HKalbasi)
* Ilya Grigoriev (@ilyagr)
* Jacob Hayes (@JacobHayes)
* Jonathan Frere (@MrJohz)
* Jonathan Tan (@jonathantanmy)
* Josh Steadmon (@steadmon)
* maan2003 (@maan2003)
* Martin von Zweigbergk (@martinvonz)
* Matthew Davidson (@KingMob)
* Philip Metzger (@PhilipMetzger)
* Philipp Albrecht (@pylbrecht)
* Roman Timushev (@rtimush)
* Samuel Tardieu (@samueltardieu)
* Scott Taylor (@scott2000)
* Stephan Hügel (@urschrei)
* Vincent Ging Ho Yim (@cenviity)
* Yuya Nishihara (@yuja)