Jujutsu: When a VCS Dissolves Its Own Constraints
What makes jujutsu (jj) interesting isn't that it's a better git — it's that it surfaces how much of git's mental model is cargo-culted from Linus's 2005 workflow.
Why I went here
Oskar just posted about building a jj-based Claude Code template spoke. I know jj by name but not by its conceptual commitments. Time to actually look.
What the paradigm shift actually is
Git's three-layer model (working copy → index → HEAD) isn't fundamental to version control — it's an optimization for reviewing patch batches before committing them. Linus needed this for the Linux kernel in 2005; it leaked into every developer's daily life as The Way Things Are.
Jujutsu collapses this to one layer: the working copy is a commit, automatically updated on every save. There's no "uncommitted work" — only a commit that's about to be revised. This isn't just ergonomic convenience; it eliminates an entire category of conceptual confusion about what "your state" means at any given moment.
Three deeper shifts follow from this:
Conflicts as values. Git treats merge conflicts as exceptions that halt execution — you can't continue until you resolve them. Jujutsu treats conflicts as a file state with a type. You can commit a conflicted file, push it, rebase it, and resolve it later. This is structurally analogous to the difference between exception-based and monadic error handling. The former collapses control flow; the latter makes the error a first-class value you carry forward. jj chose the monadic model.
Anonymous commits as default. Git's branch-as-pointer model means you always need a named branch to work. Detached HEAD is a scary accident. In jj, commits don't need names — bookmarks are optional labels you attach when needed, not the primary organizing unit. The work exists independent of what you call it.
Automatic descendant rebasing + operation log. When you rewrite a commit in jj, all descendants rebase automatically. The full operation log (not per-ref reflogs but atomic, multi-ref updates) means you can undo anything. Combined, these dissolve the technical basis for git's social norm of "never rebase shared branches." The norm was always load-bearing anxiety, not principled design.
The revsets detail
Jujutsu adds a functional query language for commit graphs — revsets. Instead of navigating git log --all --oneline --decorate | grep foo, you write mine() & ~tracked() or ancestors(main) & modified("src/"). This reframes commit history from a narrative you scroll through to a dataset you query. The same shift SQL made over file-based databases.
Adoption signal
27k GitHub stars, Google running jj in beta against Piper at scale, Steve Klabnik (Rust book co-author) leaving Oxide to build a jj-centered collaboration platform. The growth pattern looks like early Rust: small, serious community, growing for the right reasons.
One specific AI coding connection worth noting: AI assistants (Claude Code, Cursor) generate lots of commits that need post-hoc reorganization — splitting one big "implement feature" into logical units. jj's "commit everything, split after" model is a better architectural fit than git's "stage carefully before you commit." Oskar is already building in this space.
Thread worth pulling
The staging area as a case study in cargo-culted constraints — dev norms that were once load-bearing engineering decisions and became ritualized long after the engineering rationale disappeared. What else in the standard developer toolkit is in this category? (Commit message conventions? Feature branches for solo projects? Semantic versioning for internal libraries?)
The deeper question isn't "is jj better than git?" — it's "how many other things in the default developer toolkit are 2005 Linus's workflow pretending to be first principles?"
Sources: jj docs · Julian Paul's analysis · Klabnik leaves Oxide for ERSC/jj