Configuring Jujutsu
55 points by op
55 points by op
Thanks for the post! jj tug
is gonna save me a lot of time :)
Your example for the alias is missing commas between the array items. This worked for me:
tug = ["bookmark", "move", "--from", "heads(::@- & bookmarks())", "--to", "@-"]
Here’s a more advanced version of the tug
alias, which works in a few more situations (read the response chain to see how):
https://github.com/jj-vcs/jj/discussions/5568#discussioncomment-13034102
I really appreciate this choice of CSS:
ul {
list-style: lower-greek inside none;
}
It’s a worthy git successor, but it is not surprising that whoever wrote this understands enough complexity to also be a Nix advocate lol
I want to push back very gently on the idea that Jujutsu is more complex.
Jujutsu, at its core, has fewer concepts than Git. There isn’t an index. There aren’t branches, just bookmarks. There aren’t annotated tags. There’s no cherry-pick
s, there’s no garbage collection, there’s no stash.
Additionally, those concepts that do exist are implemented vastly more consistently. If a command needs a revision, it’ll take a revset; none of Git’s massive pile of command-line options for revision filtering that aren’t even shared across multiple commands. Likewise, if you want to adjust output, it’ll be the one single templates language, not some mixture of Git plumbing commands + whatever formatting your particular command honors.
That said, I agree I’ve seen plenty of these tutorials on how to configure Jujutsu (hell, I was debating writing one). But when I’ve looked at them, they’re either trying to help experienced Git users move their existing workflows over to Jujutsu, or they’re giving the author’s preferred examples of various revset/templating tweaks (again, often to make the operation closer to Git). On this particular one, for example, almost the entire thing is spent going over some of the author’s preferred templates. The only exceptions are the tug
alias (“make Jujutsu behave like Git”), turning on the currently experimental “change ID” support (“make GitHub behave like Gerrit”, I guess? not even sure how to count that one), and changing the commit message template (“make Jujutsu behave like Git”).
I think if you accept that Jujutsu has different defaults than Git, and you just work with it the way it’s intended, you’d be facing a much simpler, more consistent SCM, not a more complex one.
And that all said: Git has a massive ecosystem built around it. Every major IDE and editor has Git support. There are tons of third-party tools built around Git, that use Git language, that work with Git’s commands and Git’s templates. These integrations are how most people work with Git in 2025: they’re not using git log
directly, but instead relying on GitLens/IntelliJ/Tower/etc. to provide them a useful log and let them filter. They’re probably not using git stash
or git add -p
, they’re highlighting chunks in their IDE to add to the index. And so on. And the moment you try to have your cake and eat it too by using Jujutsu’s colocated repositories, you have to keep both Jujutsu, and Git in your head at once. And…yeah, that’s complicated.
Anyway, tl;dr: I don’t think Jujutsu is that complex, and I think most of these tutorials are from people trying to bring their Git workflow to Jujutsu. But I do think that adopting Jujutsu at the moment means you’re a command-line user, and that it strictly adds complexity unless you can avoid working with colocated repositories.
(And just to be honest, my background here: I’ve contributed to Mercurial, used Git and Hg since ~2005, cofounded a (failed) GitHub competitor in 2010, and wrote a transparent Git/Mercurial translator, so I’m aware that this kind of thing is my bread and butter and may bias me a bit.)
There aren’t annotated tags.
Hmm, this made me wonder how I would sign a release.
jj can sign commits but I couldn’t spot anything about signing bookmarks or tags in the documentation.
Also I thought jj bookmarks were basically git tags, since they are names for revisions that don’t move automatically. But jj also has tags, however I couldn’t find any explanation for what jj tags are and how they differ from bookmarks.
I’m not aware of jj having tags.
To use git tags, right now the simplest answer is “run git tag” or “click ‘create tag’ on GitHub.” Eventually there will be something native.
https://jj-vcs.github.io/jj/latest/cli-reference/#jj-tag
Eventually there will be something native.
So I guess I should understand the lack of a way to sign release tags/bookmarks not as a deliberate design choice but as a result of jj being still relatively new?
I have mild reservations about jj bookmarks doing double duty as branches and tags, but I’m still watching jj from afar until it has a magit, so I don’t know if my concerns are much of a problem in practice.
If anything I would prefer better distinctions than git refs support, especially wrt published branches vs merge request branches vs local wip branches, so that the vcs can automatically do more things like avoiding inadvertent commits on published branches, or dealing with changeset evolution chores between versions of a merge request. For example, trying to commit to trunk should automatically create a wip branch (which is what jj does by default) but committing to a wip branch should move its head ref (which is what git does by default). jj sidesteps the latter by not naming wip branches, which reduces the chore of choosing branch names but loses the pithy meaningful name for the wip. On the gripping hand, the way branch names appear in git’s autogenerated merge requests is really ugly, and it would be better to have proper support for cover letters, a dummy commit at the head of a wip branch that can be used as the summary for the merge request, and the prototype for the merge commit, and whose subject line replaces the branch name as the short description.
Anyway, just thinking out loud. I like what I have read about jj, it’s clearly a great improvement, but I’m not an early adopter of this kind of tool.
So I guess I should understand the lack of a way to sign release tags/bookmarks not as a deliberate design choice but as a result of jj being still relatively new?
Yes.
I have mild reservations about jj bookmarks doing double duty as branches and tags
It is entirely possible that bookmarks will be just tags and topics will be branches, but topics aren’t even designed yet. In git, branches and tags are nearly identical, so I don’t find it that confusing in jj. But I’m surprised there’s a tag command in the docs, I’m pretty sure the answer to this question on discord was always “use git or GitHub for now to create tags.”
or dealing with changeset evolution chores
Jj used to have changeset evolution like hg, but in practice, immutable heads is much simpler and replaced it. It doesn’t cover all of the cases, but is a good trade off for the moment.
Having run through some tutorial material the other day, my impression is that jj is definitely more elegant than git, and it provides enough benefits to be worth using instead, but I could only recommend it to people that are either experienced enough or curious enough to appreciate it.
what tutorial did you use? I still feel… under-documented on jj
Steve Klabnik’s. It’s incomplete but points out lots of things to appreciate.
Thanks! Yeah I’ve been working on a v2 for… months. I just don’t have much time these days, so progress is slow.
I’m very excited for your tutorial v2!
insert Dave Chappelle drug addict meme template: Y’all got any more of them… Steve Klabnik books?
No pressure though ;-)
May I ask what the target audience of v2 is going to be? Is it still for people who are basically experienced with git? I’ve been wanting to recommend jj to coworkers who don’t have much VCS experience at all, but there isn’t any “from first principles” learning material for jj. I’ve been playing with the thought of writing something like that, but it would be a waste of time if you’re already cooking.
Haha, thank you!
It’s going to be for software developers that are git familiar. That said, even if it wasn’t, I still think there’s value in multiple tutorials, so if you’re thinking about writing something, you should! If you end up doing it, please let me know.
In support of concise log lines:
[template-aliases]
# Show the shortest possible unique prefix
'format_short_id(id)' = 'id.shortest()'
a user on the jujutsu discord chat also shared this template to shorten timestamps further: 2h
or 1d
.
My issue with jj was I gave it a shot, it broke in a weird way, I lost work.
I’d mistakenly thought that wasn’t easy with jj, but it was. I need a one pager on using it and a one pager on how to fix common mistakes. It just seems like those using it don’t make mistakes.
The entire state of a jj repository is under version control with the operation log. Run jj op log
to view a list of states your repo was in. Copy an ID from it and run jj op restore <ID>
to revert to a previous state of a repo. The op log can do a lot more, but this is the basic thing that should easily get you out of any kind of trouble.
And because jj
’s op log records snapshots of changes to your working copy, even your working copy edits can be reverted, which really blew my mind.
Note that JJ snapshots the working copy every time any JJ command runs, so not every save will be recorded, but a lot will be. There is a configuration setting that will run a file watcher on the repository and automatically snapshot after every change, although I have run into odd issues with this when using collocated repositories and (I think) other tools that also run git commands on file changes.
Some sort of middle ground where it snapshots once an hour or something sounds like a great idea.
Just went into that repo to see and I’m not sure what happened. It was 8 months ago, and I was definitely using git and jj in the same repo (with –collate), which I thought was safe. Perhaps not? It looks like jj amend
is what got me into trouble.
I was kind of hoping to be able to use it without documentation (just –help), but it just gave me a sharp edges feeling, similar to SVN, CVS, Git, SCCS, etc. I was hoping it would be a sort of “hold everything not ignored” revision control, but right now I’m afraid the vscode edit history is better for me in that respect. (defaults to diff view)
Perhaps this cheatsheet will help: https://justinpombrio.net/src/jj-cheat-sheet.pdf At any rate all of these replies seem to point to jj as being worth learning, so I’ll give it another shot.
It looks a bit like I might have had this sort of problem with the auto adding: https://github.com/jj-vcs/jj/issues/323
It was 8 months ago, and I was definitely using git and jj in the same repo (with –collate), which I thought was safe. Perhaps not?
There’s not much that can go “wrong” per se, but some things can get lost in translation. The recommendation is to use jj to read & write to your repository, while git should only be used for reading if possible. For example, if you do an interactive rebase in git, the commits will lose their change-id and the next time you run jj, it will think the rebased commits are completely new. You will then end up with “dangling” commits that you have to manually jj abandon
. It’s also not the end of the world, but to stay safe, only use git to read the repo.
I was kind of hoping to be able to use it without documentation
I’m not sure if that’s even a goal of jujutsu. The goal is to be simple and powerful. Not so fanatically simple that no up-front learning is required at all. I reckon that would lead to extremely limiting UX tradeoffs. A straight-jacket git GUI would fit that use case probably much better.
all of these replies seem to point to jj as being worth learning, so I’ll give it another shot.
I highly recommend Steve Klabnik’s tutorial (of “The Rust Programming Language” fame).
I make mistakes all the time with it. Did jj revert
and/or rolling back with jj log …
commands not work for your case?