Goal: Become productive enough to use jj for personal projects while remaining compatible with Git.
Tip
What is Jujutsu?
Jujutsu (command: jj) is a modern version control system.
The important point:
- It uses Git repositories as a backend
- It can push to GitHub/GitLab.
- Team members can continue using Git normally.
- You can use jj locally without asking anyone else to install it.
Think of it as
GitHub / GitLab
▲
│
git protocol
│
-------------------
| |
git CLI jj CLI
| |
------- Git -------
jj is not replacing the Git server.
It replaces the local developer experience.
Why jj exists
Git is extremely powerful.
Unfortunately, it also contains many concepts that interact in confusing ways:
- branch
- HEAD
- detached HEAD
- staging area
- stash
- amend
- rebase
- cherry-pick
- reflog
- rerere
- update-refs
jj attempts to simplify all of these.
Biggest Ideas
1. Everything is already a change
Git
edit
git add
git commit
jj
edit
done
Every modification already belongs to the current change.
There is no staging area.
2. The working copy is a commit
Git has
working tree
+
index
+
HEAD
jj instead creates an always-existing commit called
@
Every edit modifies this commit.
This is probably the biggest mindset shift.
3. Change ID vs Commit ID
Git
commit SHA
ab12cd...
Changes every time history is rewritten.
jj introduces
Change ID
qpuxmyrv
The change ID survives history rewriting.
The commit SHA changes.
The change ID stays.
This is useful because people can continue referring to the same logical change.
4. Bookmarks replace branches
Git developers think
branch
jj developers think
change
Bookmarks mostly exist for pushing to Git remotes.
Local organization is done by the graph itself.
The Working Copy (@)
Example log
@
o
o
o
The top node (@) is your current working change.
Every edit immediately belongs to it.
Creating another change
Instead of
git checkout -b feature
you usually
jj new
Now you have
@
o
previous change
The previous change becomes stable.
You continue editing the new one.
Editing an old change
Suppose
C
B
A
You realize A needs another line.
Git usually requires
- checkout
- amend
- rebase
jj
jj edit A
Now
@
B
C
You edit A directly.
Descendants are automatically rebased.
No manual rebase.
Automatic Rebase
Git
modify A
↓
git rebase
jj
modify A
↓
automatic
This is one of jj’s strongest features.
Operation Log
Git has
reflog
jj has
jj op log
Much more useful.
Every operation is recorded.
Examples
- rebase
- commit
- push
- pull
- edit
You can inspect previous repository states.
Even better:
jj undo
Actually undoes repository operations.
Huge safety net.
Revsets
The equivalent of Git’s
git log
is
jj log
Revsets are a query language for commits.
Examples
@
Current working change.
root()
Repository root.
bookmarks()
All bookmarks.
::
All revisions.
Useful examples:
jj log -r ::
Entire history.
jj log -r @
Current change.
Common Commands
Status
jj status
History
jj log
Diff
jj diff
Create next change
jj new
Edit existing change
jj edit
Describe current change
jj describe
Undo
jj undo
Git clone
jj git clone URL
Push
jj git push
Fetch
jj git fetch
Git Mapping
Git
git status
↓
jj status
Git
git log
↓
jj log
Git
git diff
↓
jj diff
Git
git checkout
↓
jj edit
or
jj new
Git
git commit
↓
jj describe
Git
git commit --amend
↓
jj edit
or
jj squash
Git
git stash
↓
Usually unnecessary.
Create another change instead.
Why jj would fit many developers
Current pain points:
✅ stacked review
✅ moving code between commits
✅ stash
✅ amend
✅ rebase
✅ detached HEAD confusion
jj directly targets these.
Corporate repositories can remain Git repositories.
Things NOT to use immediately
Do not migrate a corporate workflow until comfortable.
Start with personal projects first.
Once comfortable, evaluate:
- GitLab
- Gerrit
- Corporate Workflow
Misc
The most important realization:
Git manages commits.
jj manages changes.
A commit is immutable.
A change evolves.
That single design decision explains almost every feature in jj.