Are you a developer who’s ever felt bogged down by the complexities of Git? Do you wish for a version control system that makes iterative development, refactoring, and collaboration feel more natural and less error-prone? You’re in the right place!
Welcome to Jujutsu, often abbreviated as jj, a modern, Git-compatible version control system designed to streamline your development workflow. In this guide, we’ll embark on a journey to master jj, starting with its fundamental concepts and practical applications. This first chapter introduces you to the core philosophy of Jujutsu, guides you through its installation, and helps you take your very first steps.
By the end of this chapter, you’ll understand jj’s unique approach to version control, have it installed on your system, and be ready to create and manage your first commits. We assume you’re already familiar with basic version control concepts like commits, branches, and merging, ideally from experience with Git or Mercurial.
Understanding Jujutsu’s Core Philosophy
Jujutsu (jj) is a new generation of version control system that aims to combine the best aspects of Git and Mercurial while introducing powerful new concepts. It’s built to be Git-compatible, meaning you can use jj on existing Git repositories and interact seamlessly with Git remotes like GitHub or GitLab. However, jj isn’t just a Git wrapper; it fundamentally rethinks how you interact with your code history.
Why Jujutsu? Solving Common VCS Pain Points
jj was created to address several common frustrations developers face with traditional VCS, especially Git. Understanding these pain points helps clarify why jj’s design choices are so impactful.
- Complex Staging Area: Git’s staging area (index) can be powerful but often adds an extra mental burden, especially for beginners or when making quick changes. It requires an explicit
git addstep before committing. - Immutable History Mindset: Git’s strong emphasis on immutable history, while good for integrity, can make refactoring and cleaning up your local commits cumbersome. Operations like
rebase -iare powerful but require careful manual intervention and understanding of detached HEAD states. - Branch Management Overload: Traditional branches in Git can become unwieldy, leading to “branch spaghetti” and confusion about which branch is tracking what. This often hinders linear, iterative development.
- Lack of Robust Undo: While Git has
reflog, it’s not a general-purpose, easy-to-use undo mechanism for most operations. Recovery often involves digging through the reflog manually.
jj tackles these issues head-on, offering a fresh perspective that prioritizes simplicity, power, and safety.
The Jujutsu Paradigm Shift: Core Concepts
To truly appreciate jj, it’s crucial to understand its core differentiating concepts. These aren’t just new features; they represent a fundamental shift in how you think about version control, moving from a rigid, “snapshot-based” model to a more fluid, “change-based” one.
The Working Copy as a Commit
In Git, your working directory, the staging area, and your commits are distinct entities. You modify files, git add them to the staging area, and then git commit to create a new snapshot. This multi-step process can sometimes feel disconnected from the actual work.
jj simplifies this by treating your entire working copy as a commit itself. What does this mean in practice?
- There’s no separate staging area. Any change in your working directory is implicitly part of the “working copy commit.”
- When you run
jj commit,jjcreates a new commit that contains all changes from your current working directory. Then, it automatically moves the “working copy commit” to be a child of this new, just-created commit.
This model often feels more intuitive, as your working directory is always in a committable state, embodying the current “in-progress” commit. You don’t need to explicitly stage changes; just save your files, and jj sees them as part of your active work.
Mutable History by Design
One of jj’s most powerful features is its embrace of mutable history. Unlike Git, where changing past commits is seen as an advanced operation (and potentially dangerous if not handled carefully, especially when interacting with shared history), jj makes it a central, safe, and easy part of your local workflow.
Why is this important? It empowers you to refine your work and maintain a clean, logical history before sharing it with others. This means you can effortlessly:
- Edit previous commits: Fix a typo, add a missing file, or refine a commit message.
- Reorder commits: Arrange your changes in a more logical sequence.
- Split a single commit into multiple: Break down a large commit into smaller, more reviewable chunks.
- Combine multiple commits into one: Squash several related commits into a single, cohesive change.
jj encourages you to iterate and refine your local history before sharing it, leading to cleaner, more logical commit graphs. This flexibility is a game-changer for iterative development and code review preparation.
The Operation Log: Your Safety Net
With great power comes great responsibility, but jj provides a crucial safety net: the operation log. Every single action you perform with jj – every commit, rebase, undo, or update – is recorded in this log. This is a fundamental difference from Git’s reflog, which primarily tracks where your branch pointers have been. The jj operation log tracks every command executed.
This log gives you unparalleled confidence to experiment freely with jj’s mutable history features, knowing you can always revert to a previous state of your repository.
- Undo any operation: Made a mistake? Just
jj undo. This command effectively reverses the lastjjoperation, restoring your repository to its state before that operation. - Redo an undone operation: Changed your mind after an undo?
jj redowill reapply the undone operation. - Explore your command history: The
jj op logcommand allows you to see what you did and when, providing a transparent audit trail of your actions.
📌 Key Idea: The operation log is Jujutsu’s powerful safety net, allowing you to undo and redo any operation, making mutable history fearless. This significantly reduces the cognitive load of complex refactoring.
Installing Jujutsu (as of 2026-05-19)
Let’s get jj up and running on your system! Jujutsu is actively developed, and its latest stable version often includes significant improvements. As of May 19, 2026, we’ll aim for a recent stable release. For consistency and stability, let’s target Jujutsu version 0.20.0 or later, which reflects current stable releases. Always check the official GitHub releases page for the absolute latest version and release notes.
You can install jj in several ways depending on your operating system.
macOS Installation
The recommended way to install jj on macOS is using Homebrew, a popular package manager.
brew install jujutsu
Linux Installation
For Linux, you can often find pre-built binaries or install via cargo. Using cargo is generally recommended for the latest versions or if pre-built packages aren’t readily available for your distribution.
Using cargo (Recommended for latest versions)
First, ensure you have Rust and Cargo installed. If not, follow the official installation instructions at rust-lang.org.
Then, install jj using cargo:
cargo install jj
Pre-built Binaries (Alternative)
You can also download pre-built binaries from the official Jujutsu GitHub releases page. Look for the .tar.gz archive for your architecture (e.g., jj-v0.20.0-x86_64-unknown-linux-gnu.tar.gz), extract it, and place the jj executable in a directory that’s included in your system’s PATH.
Windows Installation
For Windows, pre-built binaries are typically the easiest route.
Pre-built Binaries (Recommended)
Download the appropriate .zip file (e.g., jj-v0.20.0-x86_64-pc-windows-msvc.zip) from the official Jujutsu GitHub releases page. Extract the jj.exe executable and place it in a directory that’s included in your system’s PATH environment variable.
Verify Your jj Installation
After installation, open a new terminal or command prompt and run the following command to check if jj is correctly installed and accessible:
jj --version
You should see output similar to this (the exact version number might differ if you installed a newer release):
jj 0.20.0
If you see the version number, congratulations! jj is ready to go. If not, double-check your installation steps, especially ensuring the jj executable is in your system’s PATH.
Getting Hands-On with Jujutsu: Your First Repository and Commit
Now that jj is installed, let’s dive in and experience its unique workflow by creating a new project and making our first commits. This section will walk you through the essential commands for daily use.
Step 1: Initialize Your First Jujutsu Repository
We’ll start by creating a new directory for our project and initializing a jj repository within it.
Create a Project Directory: Open your terminal or command prompt and create a new directory for your project.
mkdir my_jj_project cd my_jj_projectInitialize the Jujutsu Repository: Inside your new project directory, run the
jj initcommand.jj initYou’ll see output confirming the initialization:
Initialized empty Jujutsu repository in my_jj_project/.jjThis command creates a
.jjdirectory inside your project, similar to Git’s.gitdirectory, wherejjstores its internal data.Check the Status: Let’s see the current state of our newly initialized repository using
jj status.jj statusYou should see something like this:
Current working copy: 000000000000 There is no Diff in the working copy000000000000isjj’s special identifier for the “null” or “empty” commit. It represents the state before any actual changes have been committed. At this point, your working copy is empty and has no changes.
Step 2: Making Your First Change and Commit
It’s time to create some content and make our first jj commit! Remember, with jj, there’s no staging area. Your working directory is your current working copy commit.
Create a File: Let’s create a simple
README.mdfile usingecho.echo "# My First Jujutsu Project" > README.md echo "This is a test project to learn Jujutsu." >> README.mdCheck Status Again: Now that we’ve made changes, let’s see what
jj statusreports.jj statusOutput:
Current working copy: 000000000000 Working copy has changes: A README.mdNotice how
jjimmediately recognizes the new file and indicates that the “working copy has changes.” There’s nojj addcommand because your working copy is a commit; any changes are automatically part of that implicit working copy commit.View the Diff: You can see the changes in your working copy using
jj diff. This is analogous togit diff.jj diffOutput:
diff --git a/README.md b/README.md new file mode 100644 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# My First Jujutsu Project +This is a test project to learn Jujutsu.This
diffoutput is very similar to what you’d see in Git, showing the new lines added.Commit Your Changes: Now, let’s create our first actual commit. In
jj, thecommitcommand takes all changes in your working directory and creates a new commit that is a child of your current working copy’s parent.jj commit -m "Initial project setup"Output:
Created 6d5e1f706e22 (empty) (no description set) Replaced 000000000000 with 6d5e1f706e22 (empty) (no description set) Working copy now at 6d5e1f706e22 (empty) (no description set)What just happened?
jjcreated a new commit with a unique ID (e.g.,6d5e1f706e22). This is your actual commit, containing theREADME.mdfile.- The “working copy commit” then moved to become this new commit. This is the “working copy as a commit” in action.
- The
(empty)and(no description set)parts are internal detailsjjshows briefly because it creates the commit then applies the message and content. Don’t worry about them.
Check Status After Commit: Let’s confirm the state of our repository after the commit.
jj statusOutput:
Current working copy: 6d5e1f706e22 Initial project setup There is no Diff in the working copyNow,
jj statusshows your working copy is associated with your new commit6d5e1f706e22, and there are no further changes in your working directory. Perfect!
Step 3: Exploring Your History
Let’s see the history we’ve created and how jj presents it.
View the Commit Log: The
jj logcommand displays your repository’s history, similar togit logbut withjj’s unique perspective.jj logOutput (commit IDs will vary):
@ 6d5e1f706e22 Initial project setup o 000000000000 (empty) (no description set)Here’s what you’re seeing:
@ 6d5e1f706e22 Initial project setup: This is yourInitial project setupcommit. The@symbol is crucial – it indicates that this is the commit your working copy is currently on.o 000000000000 (empty) (no description set): This is the “null” commit, the conceptual parent of your very first commit.
Notice the linear, clean history.
jjaims for this by default, simplifying the visual representation of your changes.Make Another Change and Commit: Let’s add another line to our
README.mdand commit it, observing how the history evolves.echo "This is the second line of the README." >> README.md jj commit -m "Add second line to README"Now, run
jj logagain:jj logOutput (again, IDs will vary):
@ 7a1b2c3d4e5f Add second line to README o 6d5e1f706e22 Initial project setup o 000000000000 (empty) (no description set)You can clearly see your two commits stacked on top of each other, with the working copy (
@) pointing to the latest one. This “stacking” of commits is a core concept injjthat we’ll explore much more deeply in future chapters.Show a Specific Commit: You can view the contents of any specific commit using
jj show <commit_id>. Let’s look at theInitial project setupcommit. You can use a short prefix of the commit ID.jj show 6d5e1f706e22This command will display the files and their content as they were in that specific commit, allowing you to inspect past states of your project.
Mini-Challenge: Build a Small Feature Iteratively
Let’s put your new knowledge to the test and practice the jj workflow.
Challenge:
- Create a new file called
features.txtwith the content “Feature A: Initial idea”. - Commit this change with a message like “feat: Add initial feature A idea”.
- Modify
features.txtto add “Feature A: Refined details”. - Commit this modification with a message like “feat: Refine feature A details”.
- Use
jj logto observe your commit history, paying attention to the order and the working copy pointer. - Use
jj showon your first feature commit (the one adding “Initial idea”) to see its content without the refined details.
Hint: Remember, there’s no jj add. Just make your changes in the working directory and then jj commit.
What to observe/learn:
- How
jjautomatically tracks all changes in your working copy, eliminating the staging area. - The linear progression and stacking of commits in
jj logas you build a feature iteratively. - How
jj showlets you easily inspect the exact content of any past commit.
Common Pitfalls & Troubleshooting for New jj Users
As you transition from Git to jj, you might encounter a few initial hiccups due to the fundamental differences in their models. Recognizing these common pitfalls can help you quickly adapt.
- Expecting a Staging Area (The
jj addReflex): The most common mistake for Git users is instinctively looking for anaddcommand.- Pitfall: Trying to run
jj add <file>or similar. - Why it happens: In Git,
git addis essential to stage changes. - Solution: Remember,
jjdoesn’t have a separate staging area. All changes in your working directory are implicitly part of the current working copy commit. Just modify files and thenjj commit. If you only want to commit some changes from your working directory,jjhas powerful commands likejj splitorjj amend -i(interactive) which we’ll cover in detail later.
- Pitfall: Trying to run
- Misinterpreting
jj commit’s Behavior: Thecommitcommand injjbehaves differently than in Git.- Pitfall: Thinking
jj commitjust moves a branch pointer. - Why it happens: In Git,
git commitcreates a commit and then moves the current branch pointer. - Solution: In
jj,jj commitcreates a new commit that is a child of your current working copy commit, and then it moves your working copy to point to this new commit. Think ofjj commitas “capture my current working state as a new commit, and then continue working on top of it.” This subtle difference is key tojj’s mutable history model.
- Pitfall: Thinking
- Ignoring
jj log’s Visual Cues: Especially when coming from Git, it’s easy to just skimjj logand miss its unique indicators.- Pitfall: Not understanding the
@symbol or the linear presentation. - Why it happens: Git’s
logoften shows complex branch graphs. - Solution: Make
jj logyour friend. Use it frequently to understand where your working copy (@) is positioned and how your commits are stacked. The linear, cleaner history is a feature, not a lack of information.
- Pitfall: Not understanding the
🧠 Important: jj’s philosophy is “commit early, commit often.” Because history is mutable and undo is easy with the operation log, you’re encouraged to save your work frequently without worrying about creating “messy” commits. You can always clean them up and refine them later before sharing. This encourages smaller, more focused changes.
Summary and What’s Next
In this first chapter, you’ve taken your initial steps into the world of Jujutsu, a powerful and intuitive version control system. You’ve installed jj and experienced its fundamental workflow.
Here’s a quick recap of the key takeaways:
- Jujutsu’s Purpose: A modern, Git-compatible VCS designed to simplify development workflows and overcome common Git frustrations with its unique model.
- Core Concepts:
- The working copy as a commit, eliminating the need for a separate staging area.
- Mutable history by design, making it easy and safe to refine your local commits.
- The operation log, providing a robust undo/redo mechanism for every action, ensuring safety.
- Installation: You successfully installed
jj(targeting version 0.20.0 or later as of 2026-05-19) on your system. - First Steps: You initialized a
jjrepository, made changes, committed them, and explored your repository’s history usingjj status,jj diff,jj commit, andjj log. - Common Pitfalls: We discussed the key mindset shifts required when moving from Git, particularly regarding the absence of a staging area and the unique behavior of
jj commit.
You’re now equipped with the foundational knowledge to interact with jj and appreciate its core philosophy. In the next chapter, we’ll dive deeper into jj’s mutable history features, learning how to modify, reorder, and refine your commits with unparalleled ease. Get ready to experience true flexibility in your version control!
References
- Jujutsu GitHub Repository: https://github.com/jj-vcs/jj
- Jujutsu Releases: https://github.com/jj-vcs/jj/releases
- Jujutsu Tutorial (Official Docs): https://github.com/martinvonz/jj/blob/main/docs/tutorial.md
- The Rust Programming Language (for
cargoinstallation): https://www.rust-lang.org/tools/install
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.