# Git is not fine

[[billjings-blog|Bill Jings]] wrote this because he's in love with [[jujutsu]] (jj) and wants people to try it. The hook is honest — you won't try it if you think git is fine, and his argument is that git is *not* fine, especially if your workflow is meaningfully distributed across time, people, or both.

Git's two jobs are distributed source storage and distributed workflow tooling. It knocked the storage one out of the park so thoroughly that most users don't see that the workflow side was mostly an afterthought.

## There is no C

The clean tutorial diagrams use commit names like C1, C2, C2'. Real repo diagrams show hashes and branch names. Once you switch to real names you discover what git actually does and does not know about:

- No notion of successor commits. There's no "C2'" pointing back to "C2" — they're independent objects, the rebase history is gone.
- No revision history. Amend a commit and the old commit isn't reachable from the new one.
- No rebase history.
- No idea which commits are garbage.

Branches don't fix this. They have history but:

- They're not 1:1 with code changes — convention only, can't be relied on.
- They don't have relationships with each other. From `trunk` you can't reliably find `wp/bugfix`; it's not even reachable through forward references.

## Stacked PRs are fragile in git

Stacking is how you maintain throughput when timezone latency would otherwise serialize you. Write PR 1, submit, write PR 2 on top of PR 1, submit, etc. Standard CPU pipelining applied to code review.

The case that gets ugly is rebasing the stack onto an updated trunk. You want to bring trunk forward and bring the whole stack with it. In git this is fragile:

- You can't easily see successor commits from inside an earlier commit.
- Even if you could, those successors might be garbage.
- Branches "are" the PRs but in this workflow they're easy to accidentally step on.

Tools like Graphite work around this by maintaining a separate branch-metadata store outside git, which can drift out of sync the moment you touch git directly.

## No mutability model

All of this flows from git's hands-off mutability. Bill walks through the working copy / staging / unstaged / stash / HEAD model. Each is a snapshot or diff that exists "in the repo" only in a fuzzy filesystem sense. None of your changes move to the left (the committed world) without an explicit command.

What's interesting is that the steps look like a rebase — staging on top of HEAD, replayed against another branch. If commits were mutable you could model the whole thing uniformly. They aren't, because commit IDs are content hashes, so working-copy and staging have to be branches instead, which inherits all the branch problems above.

The cost:

- Learning git is harder because everything exists twice.
- Export is weird — repo state is much different from what you clone.
- Async flows where changesets change over time don't work, because the left side can't represent change except through branches.
- Your actual workflow sometimes can't be represented at all — the mutability half can't represent merges.

## Git can't represent real workflows

The clinching example: you're building a feature, you hit a non-blocking bug, you stash, branch, fix, PR. Now you want your feature work to *include* the bugfix code while still submitting them as two parallel PRs. In git you have two options:

- Rebase the feature onto the bugfix and push the dependency through review.
- Rebase while developing, undo before submitting.

What you can't say is "my editing workspace should have all the bugfix code plus all my feature code, but the PRs should stay parallel." That's a one-line statement in jj — see [Isaac Corbrey's jujutsu megamerges piece](https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-and-profit). Same shape as testing a feature for compatibility with several unmerged PRs.

## Where this lands

Bill's framing is that pre-git VCS pain was obvious to everyone; Subversion was bad and nobody pretended otherwise. Today nobody complains about administering their git repo and most users haven't asked for branch management to get easier. For users whose workflows are meaningfully distributed — and that's everyone using LLMs, since async development is what agents create — git is now behind the state of the art for an embarrassingly long time. Meta has been running in-house systems that run circles around git for almost a decade.

The note about "I don't touch git anymore, Claude does that" is the one Bill is most skeptical of: agents do *more* asynchronous development, not less, so the workflow problems get worse, not better. The thesis sits next to [[agentic-coding-fatigue]] and [[clean-code-coding-agents]] in the cluster about how agent-driven development reshapes tooling assumptions.
