Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

josh CLI

The josh command is the primary tool for working with filtered git repositories. It provides projection-aware equivalents of the common git operations.

Installation

cargo install josh-cli --locked --git https://github.com/josh-project/josh.git

josh clone

Clone a repository, optionally applying a filter projection.

josh clone <url> <filter> <out> [options]
ArgumentDescription
<url>Remote repository URL (HTTPS, SSH, or local path)
<filter>Filter spec to apply (e.g. :/docs, :workspace=workspaces/myproject)
<out>Local directory to clone into

Options:

FlagDescription
-b, --branch <ref>Branch or ref to clone (default: HEAD)
--forge <name>Forge integration to use (e.g. github)
--no-forgeDisable forge integration

Examples:

# Clone only the docs/ subdirectory
josh clone https://github.com/josh-project/josh.git :/docs ./josh-docs

# Clone a workspace projection
josh clone https://github.com/myorg/monorepo.git :workspace=workspaces/frontend ./frontend

# Clone the full repository (no filter)
josh clone https://github.com/josh-project/josh.git :/ ./josh

josh fetch

Fetch from a remote and update the filtered local refs. Equivalent to git fetch but filter-aware.

josh fetch [options]

Options:

FlagDescription
-r, --remote <name>Remote name or URL to fetch from (default: origin)
-R, --ref <ref>Ref to fetch (default: HEAD)

josh pull

Fetch and integrate changes from a remote. Equivalent to git pull but filter-aware.

josh pull [options]

Options:

FlagDescription
-r, --remote <name>Remote name or URL to pull from (default: origin)
-R, --ref <ref>Ref to pull (default: HEAD)
--rebaseRebase the current branch on top of the upstream branch
--autostashAutomatically stash local changes before rebasing

josh push

Push commits back to the upstream repository. Josh reverses the filter and reconstructs the correct upstream commits, so your changes land in the right place in the monorepo.

josh push [<remote>] [<refspecs>...] [options]
ArgumentDescription
<remote>Remote name to push to (default: origin)
<refspecs>Refs to push (default: current branch)

Options:

FlagDescription
-f, --forceForce-push (non-fast-forward)
--atomicAtomic push (all-or-nothing)
--dry-runShow what would be pushed without actually pushing

josh publish

Push each commit as an independent, minimal diff (stacked changes workflow). Each commit with a Change ID is pushed to its own ref and, when forge integration is configured, gets its own pull request.

josh publish [<remote>] [<refspecs>...] [options]
ArgumentDescription
<remote>Remote name to push to (default: origin)
<refspecs>Refs to push (default: current branch)

Options:

FlagDescription
-f, --forceForce-push (non-fast-forward)
--atomicAtomic push (all-or-nothing)
--dry-runShow what would be pushed without actually pushing

josh remote

Manage josh-aware remotes.

Note: josh remote add can be used in any existing git repository, not only ones originally cloned with josh clone. This is the standard way to add josh filtering to a repository you already have checked out.

josh remote add

Add a remote with an associated filter projection.

josh remote add <name> <url> <filter> [options]
ArgumentDescription
<name>Remote name
<url>Remote repository URL
<filter>Filter spec to associate with this remote

Options:

FlagDescription
--forge <name>Forge integration (e.g. github)
--no-forgeDisable forge integration

Example:

# Add a second remote scoped to the backend/ subdirectory
josh remote add backend https://github.com/myorg/monorepo.git :/services/backend

josh filter

Re-apply the filter for an existing remote to update the local filtered refs. Useful after manually modifying the filter configuration without fetching.

josh filter <remote>
ArgumentDescription
<remote>Remote name whose filter should be re-applied

josh auth

Manage authentication credentials for forge integrations. Forge integration is optional and used for automatic pull request management — see Forge integration for details.

josh auth login <forge>
josh auth logout <forge>

The only currently supported forge is github. See Forge integration for full documentation.


josh cache

Manage the distributed filter cache. The distributed cache stores filter results inside a ref in the git repository, allowing a warm cache to be shared between machines via ordinary git push/fetch.

The cache subcommand requires a josh remote to be configured (see josh remote add).

josh cache build

Apply the configured filter to all already-fetched refs and populate the local distributed cache with the results.

josh cache build [remote]
ArgumentDescription
[remote]Remote name to build cache for (default: origin)

Run this before josh cache push to ensure the cache is up to date.

josh cache push

Push the local distributed cache and the filtered refs to the backing remote, so that other machines can fetch them.

josh cache push [remote]
ArgumentDescription
[remote]Remote name to push cache to (default: origin)

josh cache fetch

Fetch the distributed cache and filtered refs from the remote, warming the local cache without re-computing filters from scratch.

josh cache fetch [remote]
ArgumentDescription
[remote]Remote name to fetch cache from (default: origin)

Typical workflow:

# On the machine that computes the cache (e.g. CI):
josh cache build
josh cache push

# On another machine (e.g. a developer workstation):
josh cache fetch
# subsequent josh fetch / clone operations use the pre-built cache

Note: The distributed cache is currently only available through the josh CLI. It is not yet supported by josh-proxy.


josh-filter (standalone binary)

josh-filter is a lower-level command that rewrites git history using Josh filter specs. It is intended for scripting and one-off history rewriting tasks rather than day-to-day development workflows.

Input: the second positional argument selects what to filter. It defaults to HEAD but can be any of:

  • . - the working tree (including uncommitted changes)
  • + - the index (staged changes only)
  • A full or abbreviated commit SHA
  • A ref name (e.g. main, refs/heads/feature)

Output: the filtered commit SHA is printed to stdout. The filtered history is also written to the ref given by --update (default: FILTERED_HEAD).

Basic usage:

# Filter HEAD through :/docs and write result to FILTERED_HEAD
josh-filter :/docs

# Filter the working tree and print the resulting SHA
josh-filter :/docs .

# Filter a specific commit SHA
josh-filter :/docs abc1234 --update refs/my/filtered

Options:

FlagDescription
--update <ref>Ref to update with the filtered result (default: FILTERED_HEAD)
--file <path>Read filter spec from a file
--squash-pattern <pattern>Squash commits matching the pattern
--squash-file <path>Read squash patterns from a file
--singleProduce a single squashed commit
-dDiscovery mode: populate cache with probable filters
-tOutput Chrome tracing data
-pPrint the filter spec (and exit)
-iPrint the filter ID (and exit)
-sPrint cache statistics
-nSkip loading the cache
--distributed-cacheEnable the distributed cache backend
--reverseReverse-apply the filter (unapply): reconstruct upstream commits from filtered ones
--check-roundtripWhen used with --reverse, verify that applying the filter to the reverse result reproduces the original commit. Exits with code 1 if the check fails.