r2026.04.19 #1966
christian-schilling
started this conversation in
General
r2026.04.19
#1966
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Changelog r2026.04.19
New Features
joshCLI (#1518)A new
joshcommand as a local alternative to usingjosh-proxy.Josh remotes are stored in
.joshfiles rather than git remote config. Ajosh remotesubcommandmanages them.
josh publish(stacked changes) (#1916)A new
josh publishcommand for stacked-change workflows. It handles splitting a branch intoper-change refs, manages base refs for each change, creates/updates GitHub PRs automatically, and
marks non-bottom-of-stack PRs as drafts.
josh-filterjosh-filternow accepts a commit SHA, the working tree (.), or the index (+) as input(Support commit SHA as input to josh-filter #1925, Support index and working tree as input for josh-filter #1942).
josh-filternow returns the output SHA on stdout. Useful for scripting. (Print result sha from josh-filter #1635)josh-filtergained a roundtrip check mode to verify a filter can be applied and reversed back tothe original. (Implement roundtrip check in josh-filter #1749)
New filter:
:pin(#1573)Prevents a path from being updated by new commits. The filtered tree retains the version from the
first parent.
New filter:
:prune=trivial-merge(#1483)Explicitly prunes merge commits whose tree is identical to the first parent, i.e., merges that
brought in no changes. Unlike the new default behavior of removing trivial merges introduced by
filtering (see Breaking Changes), this filter also prunes trivial merges that were already present
in the original history.
Stored filters (
:+path/to/file) (#1601, #1611)Filters can now be stored in
.joshfiles within the repository tree and referenced via:+path/to/file. Unlike workspaces, stored filters have no implicit subdir — the filter is appliedas-is. Stored filters can reference other stored filters (and workspaces can reference them too),
enabling composable filter libraries inside a repo. Workspaces cannot be referenced this way.
Filter syntax shorthands:
:invert[f]and:<X>[f](#1604):invert[:f]expands to the inverse off.:<X>[:f]is a scope shorthand that expands to:X:f:invert[:X].Useful for composing filters that operate within a scoped context.
File filter supports renames (#1594)
The
:filefilter now supports renaming files.:replacenow supports inversion (#1480)The
:replacefilter is now invertible.Note that this does not undo replacements on the push path, but just enables use inside compose.
:messagefilter additions (#1589, #1680):messagenow accepts a regex pattern for rewriting commit messages and can read blob content fromthe input tree to use in the commit message.
Filter meta options (#1710)
Filters now support a meta option syntax:
:~(key="value")[filter].They affect things like history shape and commit properties. Current meta options include:
history="linear": linearize history (previously the standalone:linearfilter);:linearis kept as a shorthand
history="keep-trivial-merges": opt out of the new default behavior of removing trivial merges(see Breaking Changes)
gpgsig="remove": strip GPG signatures from commits (previously the standalone:unsignfilter);
:unsignis kept as a shorthandgpgsig="norm-lf": normalize line endings in GPG signature headers to LF (backwardcompatibility option)
Experimental filters (Not enabled by default. Don't use in production!)
:$path="content": inserts a blob with literal content at the given path. (Add blob insertion and treeid filter #1924):#path[:f]: outputs the tree hash as a blob. (Add blob insertion and treeid filter #1924):&path/:#path: reference and dereference trees or blobs by sha. (Add object ref/defref fiters #1938):!path/to/script[:f]: like stored filters, but the.starfile at the given path contains aStarlark script that computes the filter dynamically. (Change starlark filter syntax to :! #1935)
Retry with backoff in josh-proxy (#1895)
josh-proxynow retries transient upstream HTTP errors with exponential backoff, improvingreliability against unreliable upstreams.
ARM docker images
Release images are now published for arm64 in addition to amd64. (#1422) Images for all master
commits are also published to the GitHub Container Registry (ghcr.io).
Pluggable cache backends (#1558)
The filter cache now supports pluggable backends, making it possible to swap out the storage layer
for cache storage.
Distributed cache (#1559, #1957)
A new cache backend stores cache data inside a ref in the repository. This allows transferring a
warm cache between machines (e.g. via push/fetch), which is useful for seeding the cache in CI or
other environments where starting cold would be expensive. Currently only supported via the CLI,
not josh-proxy.
New
josh cache build,josh cache push, andjosh cache fetchsubcommands manage thedistributed cache.
josh cache buildapplies the configured filter to all already-fetched refs andpopulates the local distributed cache.
josh cache pushandjosh cache fetchtransfer the cacheto/from a remote via ordinary git push/fetch.
josh clone,josh fetch, andjosh pullautomatically fetch the distributed cache from theremote before filtering, avoiding a cold start.
Breaking Changes
Trivial merges removed by default (#1774)
Merge commits whose tree becomes identical to the first parent as a result of filtering are now
removed during history simplification. A meta option is available to restore the previous behavior
of keeping all trivial merges.
:revfilter syntax reworked;:fromfilter removed (#1785)The
:revfilter now uses explicit match operators (<,<=,==) and a default wildcard (_)instead of bare SHAs with the
000...wildcard. The:fromfilter has been removed; its use caseis covered by
:revwith the_default operator.:joinfilter removed (#1615):joinhas been removed. It was a limited alternative to using--reverse/push.Meta config support removed from josh-proxy (#1752)
The
--metaURL parameter and associated clone-blocking/locking configuration (clone_locked_refs,clone_blocked) have been removed from josh-proxy.josh-ui (web UI) removed (#1956)
The
/uiendpoint no longer exists. The josh-ui component has been removed from the project.Cache moved to
.git/josh/cache(#1787)The local sled cache is now stored at
.git/josh/cacheinstead of.git/josh.Performance Improvements
Complex workspace/stored filter graphs (#1959)
The algorithm for selecting which missing filter to compute next now uses nesting level. This
prevents an exponential blowup in the number of "missing" entries on graphs involving workspaces
with many filters.
Filter optimizer: Prefix sort fixed and optimized (#1469)
The prefix sort used a comparison function that did not satisfy total ordering, causing panics after
a Rust update. The sort was rewritten to order entries alphabetically while preserving the relative
order of filters that share a prefix as input or output directory. Additionally fixed quadratic
complexity when composing many prefix entries, with further micro-optimizations: faster hash,
eliminated redundant hashing.
Workspace cache overlocking fixed (#1482)
The lock was held during workspace
.joshfile parsing, serializing concurrent requests. The lockscope has been narrowed.
is_ancestor_ofearly exit (#1729)A new sequence number is assigned to each commit during traversal. Sequence numbers take the
maximum over all parents, guaranteeing monotonicity and enabling earlier termination during
ancestry checks.
find_unapply_baseearly exit (#1665)find_unapply_basenow exits early once the base is found.Serve
/info/refsinside josh-proxy (#1735)josh-proxy now serves
/info/refsdirectly instead of spawninggit http-backend. Previously,refs had to be written into a namespace directory so that http-backend could read them back —
a bottleneck that scaled poorly with large numbers of branches. Serving refs directly cuts push
latency substantially (e.g. ~33% faster on repos with ~600 branches).
Bug Fixes
chain(prefix(a/b), subdir(a))optimizer produced wrong results: the filter optimizer hada bug when chaining a prefix with a subdir that partially overlapped. (Fix chain(prefix(a/b),subdir(a)) #1529)
workspace.joshis at repo root: produced invalid filtersyntax. (Fix workspace discovery #1470)
:messagefilter placed in wrong position by optimizer (Fix message filter being put in wrong position by optimizer #1648)size. (Limit size of auth cache keyed by HTTP password #1412)
MaxStartupsoption inthe container's sshd config was too low; it has been removed so sshd uses its default. (Remove SSH max startups option #1773)
independently. (Keep pushing other refs if one fails in split push #1830)
This discussion was created from the release r2026.04.19.
All reactions