Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Goal

Where you create a brand new repository.
And you figure out why it already contains 2 commits.

Init

You already saw that jj git init adds Jujutsu to an existing Git repository. If there is no Git repository yet, it will create one.

Let's start from an empty repo:

$ git init

Initialized empty Git repository in ~/jj-playground/init/.git/

Enable Jujutsu in it:

$ jj git init
Initialized repo in "."
Hint: Running `git clean -xdf` will remove `.jj/`!

Multiple backends

Why isn't it just jj init? Because Jujutsu is modular and can work with different storage backends. We will stick with Git here, so never mind.

Won't jj and Git clash?

Relax. Jujutsu lives in the hidden directory .jj, which Git ignores:

$ ls -a
. .. .git .jj

$ ls -a .jj
.  ..  .gitignore  repo  working_copy

$ cat .jj/.gitignore
/*

You probably noticed the line:

Hint: Running `git clean -xdf` will remove `.jj/`!

It makes sense: that git clean command is meant for deleting ignored directories.

jj git lets you also access other Git commands with jj git clone, jj git fetch etc.

Want To Remove Jujutsu?

Delete .jj and Jujutsu is gone.

Log

Try a git log:

git log
fatal: your current branch 'main' does not have any commits yet

As expected.
What about jj log?

$ jj log

@  x           empty
◆  z       🔒   empty

Jeez! Where Git fatally errors out, Jujutsu shows not 1, but 2 Changes! How can it be?

The Origin of Time

Let's inspect z:

jj show z
Commit ID: 0000000000000000000000000000000000000000
Change ID: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Author   : (no name set) <(no email set)> (1970-01-01 02:00:00)
Committer: (no name set) <(no email set)> (1970-01-01 02:00:00)

    (no description set)

Looks like a Null Object Pattern. Indeed zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz is the "root commit", the original empty Change, the black hole every repository in the world originates from. In Git, it's implicit and has no concrete representation, so orphaned branches need special commands and options. That's not the case with Jujutsu: zzzz is a loving parent, and every orphan has a home.

Fine, zzzz makes sense. But what about the Change on top of it?

This requires a tiny bit of theory.

Collapsing areas

One approach to understanding Git is to visualize the different areas that exist in its model, and how commands operate on them.

different areas in Git @pabloulloacastro

In Jujutsu, the stash, the index, the working area and the local repository all collapse to a single area. So, Jujutsu's model is:

different areas in Jujutsu

This means that the @ you see in:

$ jj log

@  x           empty
◆  z       🔒   empty

represents the current file system, the working copy of your project. But this is also a commit in your repo. They just happen to be the same.

Why is it already there? Well, when you run git init the file system, the empty working copy of your project, was already there. Naturally, this should already be reflected in the log.

What's inside x?

Is x similar to zzzzz? What does it contain? How can you find out?

Solution

If you guessed jj show, good job!

$ jj show x
Commit ID: cb39db5ba245a72667c7bbd055b625e9522b74f8
Change ID: xmvkoxkuvlrynmwooqtrxtxptmswruqq
Author   : Arialdo <arialdo@ik.me> (2026-06-09 16:10:17)
Committer: Arialdo <arialdo@ik.me> (2026-06-09 17:44:18)

    (no description set)

It's a real commit. It has a real SHA1 (cb39db5), and Git itself acknowledges it has an author:

$ git show cb39db5
  commit cb39db5ba245a72667c7bbd055b625e9522b74f8
  Author: Arialdo <arialdo@ik.me>
  Date:   Tue Jun 9 16:10:17 2026 +0200

It's messageless and empty, but it still looks like a legit commit.