Using Jujutsu¶
After playing around with Jujutsu (aka jj) for a while I have to say I really like it!
If I had to sum up the difference between git and jj I would say that it’s like the difference imperative and declarative programming.
In git I have to spell out every operation it has to perform to get the commit graph I want - over and over again as I make changes.
While in jj, I tell it once what I want the commit graph to look like and I can make changes throughout history and it will maintain that graph for me automatically in the background.
Command Reference¶
For now I want to use git and jj side by side:
$ jj git init --colocate
Branches occur when you have multiple changes that share a single parent:
$ jj new parent -m "Commit one"
$ jj new parent -m "Commit two"
To merge branches, create a new change with multiple parents:
$ jj new <rev1> <rev2> [... <revN>]
You only really need name a branch (aka bookmark) when you want to push your changes somewhere:
$ jj bookmark set -r <rev> <name>
$ jj git push -b <name> --remote <remote> --allow-new
To push again after you’ve made additional changes:
$ jj bookmark set -r <rev> <name> # Unlike git branches, bookmarks don't move each time you commit
$ jj git push -b <name> --remote <remote>
Filesets¶
When working with denote-style filenames (especially those involving signatures), jj often tries to interpret parts of the filename specially, resulting in errors:
$ jj squash "content/20251213T204155==5=8--ibuffer.rst"
Error: Failed to parse fileset: Syntax error
Caused by: --> 1:24
|
1 | content/20251213T204155==5=8--ibuffer.rst
| ^---
|
= expected <EOI>, `|`, `&`, or `~`
Hint: See https://docs.jj-vcs.dev/latest/filesets/ or use `jj help -k filesets` for filesets syntax and how to match file paths.
The fix is to wrap the filename in two layers of quotes, the first is for the shell, the second layer is for jj:
$ jj squash "'content/20251213T204155==5=8--ibuffer.rst'"
Rebased 1 descendant commits
Working copy (@) now at: znpmlpnx 46e93dff (no description set)
Parent commit (@-) : rympsmzo db0dc66d Add keybinding for ibuffer
User Config¶
Here lies my user config for jj
As with git, you need to set a name and email for your commits
jj/config.toml"$schema" = "https://jj-vcs.github.io/jj/latest/config-schema.json"
user.name = "Alex Carney"
user.email = "alcarneyme@gmail.com"
Use emacs as my editor
jj/config.tomlui.editor = "emacsclient"
By default, running jj with no arguments shows you the log, I prefer this to be the status command
jj/config.tomlui.default-command = "status"
For compatibilty with other tools, it’s best to render diffs and conflicts as git would
jj/config.tomlui.conflict-marker-style = "git"
ui.diff-formatter = ":git"
Aliases
jj/config.toml[aliases]
push-down = ["new", "-B", "@", "--no-edit"]
Repo Config¶
Tip
Edit the configuration for the current repo by running:
jj config edit --repo
Considering how easy it is to rewrite history in jj it’s easy to imagine accidentally creating a mess for yourself.
So, by default jj will mark changes belonging to the revset trunk() as immutable.
[revset-aliases]
"trunk()" = "develop@upstream"