πŸ‘©β€πŸ’» chrismanbrown.gitlab.io

jj

a version control system

2026-03-27

aboutπŸ”—

A couple months ago I was jj curious, and started a new job, and took advantage of the change to start using it full time. I have pretty much not used git directly since!

This is the prose article version of the slides I just presented to my team to give them a ~5 minute lightning talk style introduction to jj.

what is gitπŸ”—

(link to https://xkcd.com/1597)

you know git

famously poor ux

POLL: how many people actually use git by typing commands into the terminal? as opposed to having AI or an IDE do it for you?

what is jjπŸ”—

you don’t know jj but maybe you want to!

why shoud i careπŸ”—

howπŸ”—

changes vs commitsπŸ”—

@  kzkvzsyq chris.brown@guild.com 2026-02-24 12:08:30 ee1ce7f0
β”‚  docs: code promotion
β”‚ β—‹  rozumxpm travis.rivers@guildeducation.com 2026-03-26 15:24:31 PATH-3862-semantic-search 5d7f958d
β”‚ β”‚  test: seed webpack config env vars
β”‚ β—‹  owsloxzt travis.rivers@guildeducation.com 2026-03-26 14:39:31 413bd03d
β”‚ β”‚  Update catalog API URL default
β”‚ β—‹  nlwrxosv travis.rivers@guildeducation.com 2026-03-26 14:01:58 16a10043
β”‚ β”‚  style: format semantic search guard
β”‚ β—‹  srxlzzoq travis.rivers@guildeducation.com 2026-03-26 14:01:06 626f3b7c
β”‚ β”‚  fix: gate semantic search hydration behind wave 3
β”‚ β—‹  uwmnulzm travis.rivers@guildeducation.com 2026-03-26 14:00:59 7c22f7c3
β”‚ β”‚  fix: gate semantic search behind wave 3
β”‚ β—†  vuxonmvt 45524041+travrivers@users.noreply.github.com 2026-03-26 13:11:15 fix/catalog-api-url-default main d2ba9ac1
β”‚ β”‚  Fix Wave 3 funding filter result/count consistency (#2251)

workflowπŸ”—

also supports a squash workflow: https://steveklabnik.github.io/jujutsu-tutorial/real-world-workflows/the-squash-workflow.html

oh shit gitπŸ”—

https://ohshitgit.com/

ohshitgit is a collection of common git problems and their solutions

this is a fun way to do a side-by-side comparison because it reveals that a lot of common git problems simply do not exist with jj

Oh shit, I did something terribly wrong, please tell me git has a magic time machine!?!πŸ”—

GIT

git reflog
## you will see a list of every thing you've
## done in git, across all branches!
## each one has an index HEAD@{index}
## find the one before you broke everything
git reset HEAD@{index}

JJ

jj op undo

global undo is sick. undo rebases, merges, anything

Oh shit, I committed and immediately realized I need to make one small change!πŸ”—

GIT

## make your change
git add . # or add individual files
git commit --amend --no-edit

JJ

...just edit the file

this problem does not exist in jj

Oh shit, I need to change the message on my last commit!πŸ”—

GIT

git commit --amend
## follow prompts to change the commit message

JJ

## describe ANY change:
jj desc abc

I think to edit a message from long ago, you have to e.g. git rebase -i HEAD~5 and then β€˜reword’ ? with jj you can edit any description any time from anywhere

Oh shit, I accidentally committed something to master that should have been on a brand new branch!πŸ”—

GIT

## create a new branch from the current state of master
git branch some-new-branch-name
## remove the last commit from the master branch
git reset HEAD~ --hard
git checkout some-new-branch-name
## your commit lives in this branch now :)

JJ

## n/a
## or, move the commit somewhere else:
jj rebase -r abc -d def

not really a thing in jj because of anonymous branches. you just work on master anyway, and then update your bookmark

Oh shit, I accidentally committed to the wrong branch!πŸ”—

GIT

# undo the last commit, but leave the changes available
git reset HEAD~ --soft
git stash
# move to the correct branch
git checkout name-of-the-correct-branch
git stash pop
git add . # or add individual files
git commit -m "your message here";
# now your changes are on the correct branch

JJ

jj rebase -r abc -d def

only kind of a thing in jj. if you need to move / cherrypick / whatever a change, then just move it.

Oh shit, I tried to run a diff but nothing happened?!πŸ”—

GIT

git diff --staged

JJ

n/a
no staging area

problem does not exist in jj

Oh shit, I need to undo a commit from like 5 commits ago!πŸ”—

GIT

# find the commit you need to undo
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git revert [saved hash]
# git will create a new commit that undoes that commit
# follow prompts to edit the commit message
# or just save and commit

JJ

jj abandon abc

you can always abandon any change. it automatically rebases the change’s descendant’s onto the parent

Oh shit, I need to undo my changes to a file!πŸ”—

GIT

# find a hash for a commit before the file was changed
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git checkout [saved hash] -- path/to/file
# the old version of the file will be in your index
git commit -m "Wow, you don't have to copy-paste to undo"

JJ

jj restore --from abc path/to/file

demoπŸ”—

so what does it look like

quick demo of:

consπŸ”—

getting startedπŸ”—

brew install jj
jj help -k tutorial

you really start to notice the pain points of git and how much awkwardness we just accept once you experience how easy jj is