JU

Jujutsu

Git-compatible version control system

Developer Tools & Git ★ 31.7k stars Medium setup Apache-2.0

Jujutsu is a new version control system that is compatible with Git repositories while offering a simpler model based on changes and automatic conflict handling. It runs locally as a self-contained CLI.

Key features

  • Git-compatible backend
  • Change-based model
  • Automatic rebasing
  • First-class conflicts

Pros & cons

Strengths

  • Git-compatible backend
  • Painless conflict handling
  • Undo any operation

Trade-offs

  • Workflow rethink required
  • Ecosystem still maturing

Jujutsu replaces

Last reviewed Aug 26, 2026 · 814 words

Jujutsu is the first Git replacement I would tell a self-hoster to adopt, precisely because it is not one. It reads and writes ordinary Git repositories, so your Gitea or Forgejo server, your CI runners, and every collaborator keep using Git and never find out. What changes is the tool in your terminal, and the three things it fixes are the three things that make people afraid of Git: the staging area, mid-rebase conflicts, and the lack of an undo button.

Nothing on the server side changes

jj is a single Rust binary (Apache-2.0, about 31,000 stars, first released in 2022) that stores its data in a normal .git directory. Clone with jj git clone, or run jj git init --colocate inside an existing checkout and both jj and git commands work on the same repo side by side. Pushes and fetches are plain Git protocol, so any forge in the self-hosted Git forges roundup is supported by definition. There is nothing to install on the server and nothing for the server to know.

The working copy is a commit, so there is no staging area

This is the piece that requires the "workflow rethink" the project's critics mention. In jj, whatever is in your working directory is always the contents of the current commit, snapshotted automatically whenever you run a command. There is no git add, no index, no stash. You start a change, edit, and describe it:

jj git clone https://git.example.com/me/homelab.git
cd homelab
jj new main
# edit compose files; jj snapshots the working copy on the next command
jj describe -m "immich: bump image tag, cap ML container at 4 GB"
jj bookmark set main -r @
jj git push --bookmark main

Bookmarks are jj's name for branches, and unlike Git they do not move by themselves when you commit; you point them at a change explicitly, which feels odd for a day and then feels correct. If you make a mess of three commits, jj squash folds the current change into its parent, and jj split does the reverse. Every change also has a stable change ID that survives rebases, so you can refer to "that fix" without chasing a new hash after every amend.

Conflicts get recorded, not thrown in your face

A Git rebase that hits a conflict stops everything until you resolve it. jj records the conflict inside the commit and carries on, rebasing the rest of the stack and any descendants automatically. You resolve the conflicted commit when you get to it, by editing the file and running jj squash or jj resolve, and the resolution propagates forward. For a homelab config repo where you routinely rebase a long-lived "experiments" stack onto main, this turns a 20-minute chore into two commands. The conflict markers are still there in the file if you look; the difference is that nothing is blocked while they exist.

jj undo is the feature that sells it to everyone I show it to

Every operation, including fetches and rebases, is recorded in an operation log. jj op log shows it, jj undo reverts the last one, and jj op restore <id> takes the whole repository back to any earlier state. That includes "I just rebased the wrong branch onto the wrong parent and pushed". Git can technically recover most disasters through the reflog; jj makes recovery a single command you can run without thinking, which is the version that gets used at 11 p.m.

Where it still hurts

The ecosystem is the honest weakness. Git LFS is not supported, submodules are ignored rather than handled, and IDE integrations range from decent to absent, so you will use the terminal. Anything that keys off the Git index (some pre-commit hook setups) needs adjusting. And because bookmarks are manual, people arriving from Git push the wrong commit for the first week until the model clicks. None of this affects the repository on your server, which is why I recommend trying it on one repo rather than a big-bang switch: it is 128 MB of RAM and one binary, and jj and git can be used interchangeably in a colocated checkout until you decide.

What I'd do

Run jj git init --colocate in the repo that holds your compose files and Ansible, use it for a month, and keep pushing to the same Forgejo server. Learn four commands: jj new, jj describe, jj squash, jj undo. If, like me, you stop reaching for git inside a fortnight, switch your other repositories one at a time. Nothing in your dev tools stack has to change, which is a rare property for a version control switch and the main reason this one is safe to try.

Compare Jujutsu

1 head-to-head comparisons.

Similar developer tools & git apps