Write, Commit, Bookmark, Push – A version control guide for beginners with jj



This content originally appeared on DEV Community and was authored by Altariarite

jj is a shiny new version control system. I’ve been using it for a week now and it revolutionised my workflow with GitHub. It’s simpler and more intuitive than git, but the official tutorial and the default UI can be a little daunting.

This guide will start with a simpler jj interface and walk you through common development workflows. We start from making a single change and go all the way to managing a stack of tiny pull requests.

I hope I can show you why jj feels amazing by the end! We’ll use a simple Python project as our example.

Setup

First, let’s customise jj. Then we will set up our project and initialise it with jj .

0. Customise jj

The default jj log shows a lot of stuff. That can be quite confusing for someone new to jj. When starting out I preferred to use a simpler interface. You can do that by writing to ~/.config/jj/config.toml

"$schema" = "https://jj-vcs.github.io/jj/latest/config-schema.json"

[user]
email = "someone@example.com"
name = "Some One"

[ui]
default-command = ["log", "-T", "builtin_log_oneline"]
# replace with your editor
editor = "nvim"

[template-aliases]
# Username part of the email address
'format_short_signature(signature)' = 'signature.email().local()'
# Relative timestamp rendered as "x days/hours/seconds ago"
'format_timestamp(timestamp)' = 'timestamp.ago()'
# Hide git commit id
'format_short_commit_id(id)' = '""'

[templates]
log = "builtin_log_comfortable"

1. Create your project:

mkdir jj-hello-world
cd jj-hello-world

2. Initialise jj and git:

jj works on top of a git repository, which allows it to integrate with platforms like GitHub.

jj git init

1. Your First Change & PR

Now our journey starts! We start by running jj log.

jj-log-start

Wow, what are all those things? 🤷‍♂ A minute ago we just had an empty folder!

Turns out, every new jj repository starts with two “commits”:

  1. The line starting with is the root commit. It’s the special, empty starting point of your project’s entire history, identified by all Zs (zzzzzzzz). Think of it as the foundation upon which all your future work will be built.

  2. The line starting with @ is your current working-copy commit. The @ symbol means this is your active workspace where any new file changes will be automatically tracked. In a brand new repository, this commit is also (empty) and has no description yet, ready for you to start coding.

Let’s make a simple change.

1. Write a change:

Modify the main.py file and save.

print("hello world!")

jj automatically captures this change in your working copy. If we run jj log again, you will see that the (empty) tag is gone. jj knows that we have changed something.

jj-log-changed

We can see the change with jj diff

jj-diff

2. Commit your change:

jj commit -m "Add hello world"

Your jj log will now show three commits: the root commit, the feature you committed just now, and a new empty working-copy commit you’re now on.

💡Note:
Your feature commit has the id xvuxvpsx. That’s exactly the same as the id of the previous working copy. The new working copy has a new id that starts with m

3. Sync and first push:
Let’s push your feature. Create a new, empty repository on GitHub. Then, add it as a remote.

# Replace <your-github-url> with your repository's URL
git remote add origin <your-github-url>

We want to give our commit a “bookmark”. Since GitHub is organised around named branches, this bookmark tells jj which of your local commits should become a specific branch on the remote. We want to bookmark our feature commit as main.

jj bookmark create main -r x

💡Note:
-r stands for “revision”, which is a synonym for “commit”. And x is the shortest unique id for our local commit.

Push to remote.

jj git push --allow-new

Now your feature is on GitHub! \o/

Next up, we will look at creating and fixing PRs (pull requests), which happens all the time when you collaborate with someone on GitHub, or sometimes even when you work alone. Stay tuned!


This content originally appeared on DEV Community and was authored by Altariarite