Why?
Many have little motivation to give Jujutsu a try because “Git works just fine”. I guess you’re here because you’re curious to see what Jujutsu brings to the table. So the next natural question is why Jujutsu exists and what problems it solves. Spoiler alert: it solves problems you didn’t know you had1.
3 Things to Improve
In interviews, I like to ask: if you had a magic wand, what three things would you change about your favorite tech? Here’s how I would answer about Git.
1. Git Has Too Many Building Blocks
The more building blocks, the harder it gets:
- Changes live in 3 distinct places: working copy, index, and repository.
- Consequently,
git restorecan be used with either--staged,--worktreeor both, getting to different results. - Same for
git resetwith--soft,--mixedand--hard. - Stashes live in a side-store with separate rules.
- Pseudo-refs like
MERGE_HEADpop up during conflicts.
I’d ask for a model with fewer building blocks, but more composable: powerful as ever, yet with intimidating operations made straightforward.
2. Inconsistent interface
“How can I view a list of all tags?”
“git tag”, replied Master Git.
“How can I view a list of all remotes?”
“git remote -v”, replied Master Git.
“How can I view a list of all branches?”
“git branch -a”, replied Master Git.
“And how can I view the current branch?”
“git rev-parse –abbrev-ref HEAD”, replied Master Git.
My favorite inconsistency is the index. Pro
Git calls
it the “proposed next commit snapshot”. Is it the next commit? Not
quite: it’s a quasi-commit. It has a SHA1, but branches can’t target
it. You can’t git show it. You rebase commits, but stash the
index. It’s a special case requiring special commands.
If I had a magic wand, I would ask for no exceptions, so all commands would be consistent. Indeed, Jujutsu removes all the special cases. Want to stash? It lets you, reusing the building blocks you have already learned. Welcome, composition.
3. Leaky abstraction
Git stops fighting you once you learn its internal model. When people struggle, it’s often because they built a poor intuition of it.
If I had a magic wand, I’d want an opaque abstraction capturing what I mean, quietly handling the how.
Take “undoing stuff.” In Git, to undo a command you first need to know how it works under the hood, so you can derive its inverse:
- You did
git rebase -i. To undo,git reset --hard ORIG_HEAD - Did a
git stash apply? You needgit stash drop. - Did a
git tag? You needgit tag -d - Did a
git add? You needgit restore --staged <file> - Did a
git commit --amend? You needgit reset --soft HEAD@{1}
What’s the equivalent in jj? jj undo.
- Undo a fetch?
jj undo. - Undo a rebase, a merge, a commit, a conflict resolution?
jj undo.
Consistently jj undo, no matter the change. You will wonder how you
could have worked for so many years without jj undo.
We’ll touch on this later. First, let’s explore a well-designed piece of Git to learn your second Jujutsu command.
-
This reminds me of The Blub Paradox (Paul Graham - Beating the Averages). “[People] are satisfied with whatever language they happen to use, because it dictates the way they think about programs.”.
That is: until you’ve used more powerful tools, you don’t experience their advantages as missing features of your current tool. In a sense, you can’t miss what you’ve never had. ↩