A Short Guide to Jujutsu (Jj) for Git Users
Jujutsu (jj) is a modern, Git-compatible version control system from Google designed to be simple and powerful. It aims to make complex workflows effortless, especially cleaning up commit history. If you’ve ever felt that Git was hard or required too much discipline, jj might be for you.
The jj Philosophy
- Effortless History: With
jj, you don’t need perfect commits from the start. Work freely, and clean up your history later with powerful commands likejj split,jj squash, andjj edit. - No Staging Area: The working copy is always “live.” There is no need for
git addorgit stash. To work on something new, you just check out a different revision. - Free Checkpointing:
jjrecords every operation. You can undo almost anything with the magicjj undocommand.
1. Installation and Configuration
First, install jj on your system.
- Linux/macOS (Homebrew):
1brew install jj - Windows (Scoop/Winget):
1 2 3scoop install jj # OR winget install --id Jujutsu.Jujutsu - NixOS:
1 2 3environment.systemPackages = with pkgs; [ jujutsu ]; # OR nix profile install nixpkgs#jujutsu - For other methods, see the official installation guide.
After installing, configure your user details. This is a one-time setup.
|
|
2. Creating Repositories
- Clone a Git repo: This is the most common way to start. It creates a
jjrepo that is linked to the Git remote.1> jj git clone https://github.com/user/repo.git - Use
jjin an existing Git repo:1 2> cd my-existing-git-repo > jj git init --colocate - Create a new repo:
1> jj git init my-new-repo
3. The Core Workflow: Making Changes
The jj workflow is different from Git’s. Instead of add -> commit, you just do the work.
- Start a new change: Use
jj newto create a new, empty revision to work on. Your changes will be automatically saved to it.1 2> jj new # Now, edit your files - Describe your change: When you’re ready, describe the revision. You can do this at any time.
1> jj describe -m "My new feature" - Check your status: Get in the habit of running these commands all the time to see what’s happening.
1 2 3> jj st # See modified files > jj log # See the history of revisions > jj diff # See code changes in the current revision - Push a change: after cleanup, move your bookmark and push
1 2>jj bookmark move master --to=@ >jj git push --bookmark master
4. Understanding Revision IDs vs. Commit IDs
This is the most important concept to grasp. Run jj log to see them.
- Revision ID (e.g.,
wuloypwt): A local, permanent ID for a set of changes. It never changes, even if you edit the commit. It’s how you refer to revisions injjcommands. - Commit ID (e.g.,
182d3ce4): This is the Git SHA. It represents the entire state of the worktree. It will change every time you edit the revision (e.g., by rebasing or amending the message). This is what you see in GitHub.
5. Navigating and Editing History (The Magic)
jj makes history manipulation safe and easy. There is no need for git stash.
- Edit a past revision: Just use
jj editwith the revision ID. Your working copy will update to that revision, and you can start making changes.Use1> jj edit <revision-id> # e.g., jj edit wuloypwt@for the current revision,@-for its parent, and@+for a child. - Fixing Mistakes:
- The magic undo button: This reverts the last operation (a commit, a rebase, etc.). You can even run it multiple times.
1> jj undo - The operation log: To go further back in time, view the log of all operations and restore to a previous state.
1 2> jj op log > jj op restore <operation-id>
- The magic undo button: This reverts the last operation (a commit, a rebase, etc.). You can even run it multiple times.
- Cleaning up commits:
- Split a commit: If a commit does too much, split it into smaller ones.
1> jj split - Combine commits: To merge a revision into its parent, use
jj squash.1> jj squash
- Split a commit: If a commit does too much, split it into smaller ones.
6. Branching and Remotes
In jj, branches are just pointers (called “bookmarks”) to revisions. They don’t automatically move forward when you create a new commit. You must explicitly create, move, and push them.
- Start a new line of work:
1 2# Creates a new, empty revision on top of main > jj new main - Do your work: Make some edits, then describe the commit.
1 2 3> jj describe -m "A new feature" # You might continue with more commits > jj new -m "Another commit for the feature" - Create a bookmark (branch): Before you push, create a bookmark to give your line of work a name. The
-r @flag means “give the name to the current revision.”1> jj bookmark create my-feature -r @ - List bookmarks: To see all bookmarks (local and remote), use
jj bookmark list.1> jj bookmark list - Pull latest changes: First, fetch from the remote. To make
jjautomatically update your localmainbookmark whenorigin/mainchanges, you can “track” the remote branch. Then, rebase your stack of changes onto the main branch.1 2 3> jj git fetch > jj bookmark track main@origin > jj rebase -d origin/main - Push your branch: The command for pushing a bookmark is
jj git push --bookmark <name>. The first time you push a new bookmark, you will likely need to use--change <id>to create a remote branch with that name.1 2 3 4 5# Push a specific bookmark. This is the most common push command. > jj git push --bookmark my-feature # Alternatively, push a specific change, which will create a branch for it > jj git push --change .
7. Important Considerations & Downsides
- Force-Pushing is Normal:
jjworks by rewriting history, so it force-pushes changes. This can make reviewing a pull request commit-by-commit on GitHub difficult, as old commits will change. - State is Local: The undo history and the status of revisions are stored locally on your machine. If you clone your repo on a second computer, you won’t have the undo history from the first. A revision created on machine A will be “immutable” (you can’t use
jj split, etc.) on machine B. Push your branches before switching computers to avoid losing work. - Using Git in Parallel: It’s safe to run read-only
gitcommands (likegit status). For any action that modifies history (commit,rebase,push), use thejjcommand to avoid confusion.
Also check out “The jj VCS Workshop” by Jimmy Koppel and of course the jj-vcs site.