Most active commenters
  • paradox460(5)
  • jennyholzer(3)

←back to thread

Jujutsu for everyone

(jj-for-everyone.github.io)
434 points Bogdanp | 24 comments | | HN request time: 1.298s | source | bottom
1. jennyholzer ◴[] No.45084302[source]
I've seen some posts about Jujutsu recently, but I haven't gone deep into specific workflows.

Are there specific advantages to using Jujutsu over Emacs Magit?

All other Git UIs I've used have been severely lacking, but Magit has made me significantly more productive with Git, and has convinced me of the "magic of git".

Is Jujutsu interested in competing with this experience? Or is it intended as an alternative to the (to be clear, extremely poor) git user experiences outside of Emacs?

replies(7): >>45084369 #>>45084385 #>>45084405 #>>45084556 #>>45084694 #>>45085631 #>>45089962 #
2. paradox460 ◴[] No.45084369[source]
Jujutsu isn't really a git UI, and in some ways it's rather bad at being one (no support for making tags, submodules, or a few other things)

It's a whole new VCS, that just so happens to be backwards compatible with git, and uses git as it's backend

Similar to how git brought us cheap branching over svn, JJ brings cheap rebasing. Conflicts are no longer stop the world operations, and you can rebase, rearrange, and manage commits like never before.

If you've used tools like stacked diffs before, JJ will feel right at home. Making stacked diff PRs is almost trivial in jj

replies(2): >>45084398 #>>45091434 #
3. jennyholzer ◴[] No.45084385[source]
Are there "central concepts" in the Jujutsu design?

I'm having a hard time wrapping my mind around what specific details would cause me to choose Jujutsu over Git, in particular because of Git's industry standard status.

I think this is a very interesting concept, but I think it could go farther with some more targeted marketing along these lines. Of course, if Git power users are not Jujutsu's intended audience, then this comment may be irrelvant.

I think one of Git's great weaknesses is its unfriendliness to newcomers (jargon, deep features, lack of discoverability, lack of accessible GUI frontends), so there's probably a lot of potential for a VC solution that is easier for a newcomer to jump into.

replies(3): >>45084557 #>>45084575 #>>45084937 #
4. jennyholzer ◴[] No.45084398[source]
Stacked diffs is a great feature. Thanks for the response!
replies(1): >>45084511 #
5. nchmy ◴[] No.45084405[source]
here's a few links that you might find useful. But it would be worth exploring the other recent hn discussions on the topic - i and other unabashed evangelists have shared a lot.

A great "Megamerge" workflow

https://v5.chriskrycho.com/journal/jujutsu-megamerges-and-jj...

https://ofcr.se/jujutsu-merge-workflow

And an absolutely fantastic TUI that wraps jj cli. Might be the best TUI ive ever used, and consistently getting better.

https://github.com/idursun/jjui

6. paradox460 ◴[] No.45084511{3}[source]
No worries.

JJ tends to fit modern software engineering a bit better than git, I've found. Here's sort of an example of what I do when I'm working with it

I'll open an empty change on top of the main branch, not really sure about where this feature is going to go but knowing that it needs to be new changes. Usually this is already done for me automatically because my main synced with the remote, and therefore is an immutable commit. As I'm writing code I'm not really concerned with how I'm going to commit it to the graph, it's just a big pile of things all changing at the same time. Maybe I do features that are unrelated, or only tangentially related, to the actual story I'm working on.

If I get interrupted, I might go over to JJ and describe my changes, typically something along the lines of work in progress with a list of what still needs to be done and what I've been trying to do, basically a capture of my state of mind at the time. I'll then create a new change on top of that, for when I can come back later.

Once I'm finished with all of the story and it's working to my satisfaction, I probably have a big ball of changes that need to be split up and organized properly. First thing I do is look at what changes are necessary for this story, which are dependence for it, and which are just things I did because it was convenient to do them at the time. I'll split the dependencies out first putting them into their own changes. Then I'll make the actual story related changes, and then I'll make the ones that are just one offs. With a little bit of rebasing, I now will typically have three or four different bookmarks, which is the JJ analog of branches, some in parallel and some dependent on each other, that I can push up to my remote repository and open up pull requests.

I made a couple shell scripts to handle some common things, like recursively splitting a change into parts, but you don't really need them, as they're just wrappers around built in JJ stuff or adaptations to some of my workflows. I touch on them in a blog post that's mostly about JJ: https://pdx.su/blog/2025-08-13-the-quiet-software-tooling-re...

replies(1): >>45085579 #
7. veqq ◴[] No.45084556[source]
jj is similar to a magit cli, brought to the rest of the world. There's no benefit to switching from magit.
8. senekor ◴[] No.45084557[source]
> I'm having a hard time wrapping my mind around what specific details would cause me to choose Jujutsu over Git, in particular because of Git's industry standard status.

Jujutsu is Git-compatible, so there's nothing to lose. It can literally create the `.git` directory next to the `.jj` directory to fool all your existing tools into thinking this is a git repository.

There are a few limitations... Jujutsu currently ignores submodules, for example. So you have to run `git submodule update` sometimes. And when you yourself update the submodule, you need to `git commit` instead of `jj commit`.

Git LFS is also not supported. Apart from that, it's smooth sailing AFAIK.

> I think this is a very interesting concept, but I think it could go farther with some more targeted marketing along these lines. Of course, if Git power users are not Jujutsu's intended audience, then this comment may be irrelvant.

Git power users are definitely part of the target audience, most Jujutsu users today are retired Git power users. Because that's not the target audience of my tutorial though, I didn't write much about that. Some of the features jj users are most excited about include: - Conflicts are non-blocking. Merge and rebase always succeed, conflicts are recorded in the commit itself. You can work on something else and come back later to solve them. - There is `jj undo` and `jj redo` which work like Ctrl[+Shift]+Z in GUI apps and text editors. They affect the whole repository, because that has basically its own linear history. Reflog on steroids, basically. - `jj absorb` can find the most recent commit that touched the same lines and squash your changes into it. It's magical if you're working on several things in parallel (by merging the separate branches together, just for development.)

These are just some examples that come up the most in the "appreciation" channel on the Jujutsu discord.

> I think one of Git's great weaknesses is its unfriendliness to newcomers (jargon, deep features, lack of discoverability, lack of accessible GUI frontends), so there's probably a lot of potential for a VC solution that is easier for a newcomer to jump into.

Yes! I think Jujutsu has a lot of potential there as well. But there's a lack of learning material for that target audience... hence why I wrote this tutorial :-)

9. veqq ◴[] No.45084575[source]
jj is akin to a wrapper of coherent aliases thrown over git. No one else knows you're using it, because it uses git under the hood. It's just a simpler abstraction without insane naming and flag conventions.
replies(2): >>45084773 #>>45084893 #
10. wry_discontent ◴[] No.45084694[source]
I switched from Magit to jujutsu. The only difference for me is that stacking PRs has become simpler. It's also made me more conscious of making smaller changes and shrinking what I consider "worth shipping".

Overall a positive experience, but if Magit is working for you, there's no killer feature that makes it worthwhile.

I'm also using https://github.com/bolivier/jj-mode.el which lets me do enough of what I need with jj from within Emacs.

replies(1): >>45085750 #
11. senekor ◴[] No.45084773{3}[source]
I mean, it certainly is that, but not only that. Jujutsu has more to offer than a consistently designed CLI. You can't do non-blocking merge/rebase conflicts with Git aliases. You can't do `jj absorb` with Git aliases. And you can't automatically rebase all descendants of a branch without first merging them all together, which may cause conflicts that then prevent you from performing the actual rebase. Just some examples of "more than a bunch of Git aliases" ;-)
12. baq ◴[] No.45084893{3}[source]
it's much more than that. jj decouples the tree snapshot (git commit) from the patch id (jj change id); this allows workflows that are possible in git, but hard or inconvenient; if you add deferring conflict resolution, the most efficient jj workflow is similar but very much not the same as the most efficient git workflow.
13. thramp ◴[] No.45084937[source]
(disclosure: I started a jj company but I don’t have anything to sell yet.)

> Are there "central concepts" in the Jujutsu design?

I think a central concept in jj is that everything is a commit: there’s no staging index, stashes, or unstaged files, only commits. This has a few pretty neat implications: - changes are automatically to recorded to the current commit. - commits are very cheap to create. - as others have already said, rebases (and history manipulation in general!) are way cheaper than in git. It helps that jj as a whole is oriented around manipulating and rewriting commits. Stacked diffs fall out of this model for free. - Since everything is now a commit, merge/rebase conflicts aren’t anything special anymore because a commit can simply be marked as having “a conflict” and you, as the user, can simply resolve the conflict at your own leisure. While I’m sure you know already know thus, I’d rather make subtext text: in git and mercurial, you’d need to resolve the conflict as it got materialized or abort the rebase entirely. - because everything is a commit, jj has a universal undo button that falls out effectively, for free: `jj undo`. It feels so incredibly powerful to have a safety net!

> All other Git UIs I've used have been severely lacking, but Magit has made me significantly more productive with Git, and has convinced me of the "magic of git".

I can’t speak to this personally, but I’ve had friends who are magit users tell me that jj isn’t a big enough improvement (on a day-to-day, not conceptual, basis) over magit to switch at this time. It’d be really cool to have a magit-but-for-jj, but I don’t think anyone has written one yet.

14. nchmy ◴[] No.45085579{4}[source]
Glad I'm not the only one who uses it to tidy up the chaos that is my iteration process... I have almost exactly the same workflow. jj just lets me work and not worry AT ALL about commits, vcs etc...
replies(1): >>45085856 #
15. aseipp ◴[] No.45085631[source]
If you are already a heavy Magit user, then most of the basic ideas will probably be appealing and jj will let you bring those ideas to the command line. It will let you do some acrobatics you thought weren't possible before, ones that many users have come to love -- like rebasing a 5-way octopus merge with 2 extra leaves that result in conflicts you don't have to solve yet. (This is a technique known and popularized as "Mega Merge", which I suppose I am responsible for "inventing" along with its semi-silly name.)

I think Magit is an interesting parallel to jj. You say the "magic of git", but for both of them I think most of the "magic" has less to do with Git and more to do with the "design language" exposed to users, and by that I mean the tools that allow you to manipulate, navigate, and arrange commits (and diffs!) Git is more like a physical storage layer for both Magit and jj, but beyond that a lot of the special sauce is unique to their algorithms, their UX, and their "nouns and verbs".

In my experience, Magit users are generally harder to sell because for them jj isn't so revolutionary; die-hard Git powerusers who have been exclusively slugging it out on the command line to perform 10-stack rebases for the last 5+ years tend to be very easy to sell, in comparison. But all these users tend to understand and appreciate the power of a well-designed set of tools for commit graph manipulation. Git powerusers tend to be some of our most hardcore converts and advocates, really.

Full disclosure but I'm one of the jj maintainers and my opinion is that it's pretty good. Maybe try it out for a few days (perhaps without using Magit, if you can :)

replies(1): >>45092179 #
16. trueismywork ◴[] No.45085750[source]
How do you incrementally resolve merge conflicts in magit?
replies(1): >>45092984 #
17. paradox460 ◴[] No.45085856{5}[source]
What's even more interesting is how ally coworkers now know I'm "the guy who can sort out branch complexity"

They'll ask me to merge a dozen PRs into a test branch or whatever and it's a piece of cake in jj

18. arialdomartini ◴[] No.45089962[source]
You will be probably excited to give https://github.com/bolivier/jj-mode.el a try.
19. stavros ◴[] No.45091434[source]
I use jj, but I haven't gotten into conflicts much yet. What do you mean by "they aren't stop-the-world operations"? I do like how chill jj is about them (as in, it doesn't interrupt what I'm doing), but I always resolve them immediately. Can I not?
replies(1): >>45093415 #
20. skydhash ◴[] No.45092179[source]
I think git was meant to be used as a base layer. You design your workflow and then add you aliases on top, making it more semantically significant for you.
21. wry_discontent ◴[] No.45092984{3}[source]
I don't know what that means. I haven't changed how I resolve conflicts with jj.
22. paradox460 ◴[] No.45093415{3}[source]
If you're doing a rebase or merge or any other operation, and a conflict comes up, in git you have to resolve it right now, or discard everything. You can't just leave the conflicts in place while you work on something else, they effectively freeze your entire repo. JJ is the opposite. You'll get conflicts, it will tell you about them, but it's up to you to choose when to work on them. You can even keep piling new changes on top of a conflicted one. Your program probably won't work, being full of conflict markers, but you can keep working still
replies(1): >>45094121 #
23. stavros ◴[] No.45094121{4}[source]
Ahh nice, I didn't realize it'd carry the conflict markers along. That's great, I really like jj.
replies(1): >>45095377 #
24. paradox460 ◴[] No.45095377{5}[source]
You can also resolve the conflict markers in a variety of different styles, not just edit in place.

Say I'm doing a dependency update, and someone else updated different dependencies, and our change sets merge. I want both sets of updated versions, but our lockfiles probably conflict, and I don't want to edit them by hand. I can just leave the conflicted lockfiles till the end of the rebase/merge, then purge them and regenerate them using tooling, and then split them up and apply them down to their respective conflicting changes.

Sure beats having to toss the lockfile, regen it, then let the rebase continue only to find you have to do it AGAIN