Jujutsu for Everyone

212 Bogdanp 147 8/31/2025, 3:31:04 PM jj-for-everyone.github.io ↗

Comments (147)

idoubtit · 1h ago
I've now seen a dozen of articles that explain that jj is wonderful and better than Git for everything. This tutorial is of the same kind. Now that I've read extensively about the good part, I'd be more interested by the bad and the ugly. Because my experience with jj was more balanced.

When I tried jj, I found a few pain points that made me return to Git. For instance, I was sharing a branch with a co-worker where we were just piling commits as soon as they were ready (after `pull --rebase` if necessary). Since jj doesn't have names branches, that workflow was easy with git and tedious with jj – even with the `tug` alias. The process in the "Tracking remote bookmarks" chapter of this tutorial still doesn't look nice to me.

Another pain point was that jj could not colocate with light clones, like `git clone --filter=blob:none`. Maybe that's fixed now.

shepherdjerred · 40m ago
One thing that has bitten me a few times is jj randomly losing my changes. As in, I'll be working in Cursor, not run any mutating jj command (maybe I'll run jj status or jj log, but nothing else), and later on my changes are gone from my repository (often times with a message about a stale workspace).

I'm not sure if this is somehow related to my IDE, working in a huge monorepo, or something else, but it has been quite painful.

Aside from that, though, I do really like the flexibility jj provides.

stouset · 42m ago
I’m slightly confused. jj has named branches. They’re just called “bookmarks”.

Once you track the remote bookmark, `jj git fetch` will update your local one to match the remote.

Disposal8433 · 35m ago
> Since jj doesn't have names branches

False. You need to call `jj branch set -r@ XYX` manually which can be a PITA but you only need to do that once you push. Or there is `jj git push --named XYZ=@` which moves the branch.

wocram · 53m ago
https://github.com/jj-vcs/jj/discussions/3549 exists to simplify the tug workflow somewhat.
pokipoke · 23m ago
> Another pain point was that jj could not colocate with light clones, like `git clone --filter=blob:none`. Maybe that's fixed now.

It's not

a022311 · 1h ago
Nice work! I've been using Jujutsu for almost 5 months and have completely replaced git. In fact, I've interacted with Git only 52 times (41 if we exclude my invocations of `--help` xD) since then vs 582 with Jujutsu.

Instead of having to adapt to a particular workflow, Jujutsu is flexible enough to support pretty much any workflow. Even when mostly using it like git, I have the freedom to jump around commits and branches (no stashing required), rebase easily (this may be simple for git power users, but I really appreciate being able to do this without VSCode's git tools) and just... get work done without extra headaches caused by VCS. And all that while writing my changes to an actual git repository just like everybody else's, that git tooling can interact with. When was the last time you used a different VCS than your coworkers without having them switch to it too?

While there are some rough edges regarding tags, submodules and LFS (I might be missing something else here), it's certainly worth a try.

wocram · 1h ago
What is the replacement for `git branch --set-upstream-to`?
nchmy · 1h ago
try jjui out and you'll interact with jj nearly 0 times going forward. Its amazing.
a022311 · 1h ago
haha, not interacting with a UI is a benefit for me. I do plan on trying it though.
cube2222 · 1h ago
Jujutsu is pretty excellent. I’ve tried it a couple months back (and written about, along with a couple common patterns [0]) and have been using it since.

It’s just a very “consistent” experience. I never really had issues with git (so didn’t expect I’d stay with jj), but for anything more advanced I’d generally have to google. In jj everything is based on a couple primitives, and it’s easy to combine them to do history reshaping of arbitrary complexity.

My workflow used to be very stash-oriented, and with the way jj changes work, auto tracking, and letting me switch between changes, it ends up being much more pleasant than git.

Rebasing with conflict resolution is generally much nicer too (esp. in the stash-like workflow).

Anyway, very recommended, and effort required to switch is very small.

[0]: https://kubamartin.com/posts/introduction-to-the-jujutsu-vcs...

marcuskaz · 3h ago
> Jujutsu is more powerful than Git. Despite the fact that it's easier to learn and more intuitive, it actually has loads of awesome capabilities for power users that completely leave Git in the dust.

Like? This isn't explained, I'm curious on why I would want to use it, but this is just an empty platitude, doesn't really give me a reason to try.

senekor · 2h ago
Hi, author here. Since the target audience is people with little to no Git experience, a detailed comparison would not make sense. I did simply make that claim because the weirdness of Git's UI is usually justified by saying how powerful it is. So this statement is just intended to ease the readers mind that they're not missing out on power by choosing a tool that's easier to learn.
jennyholzer · 2h ago
I appreciate this perspective.

IMO, the authors and evangelists of Git are essentially correct when they argue about its power.

However, I think that it's extremely difficult to gain practical experience with using Git in a high-powered, high-agency way, mostly because there are a lot of abstract concepts at play and there is no easily accessible place where these concepts can be "discovered".

Basically, Git is as good as it's cracked up to be, but only if you're an expert.

If you're interested in becoming a Git expert, I cannot recommend Emacs Magit strongly enough.

If not, I think Jujutsu could be an quicker road to a high-agency version control workflow. It's at least worth considering. I feel confident that Jujutsu can succeed, in particular because of Git's harsh difficulty curve.

senekor · 2h ago
Thanks, but I consider myself a Git expert already :-) I read the Pro Git book cover to cover. I have a gluten-free, artisanal, free-range git config that I've grown and cared for over years. single character aliases all the important commands, "log all graph oneline", "commit amend no-edit", interactive rebase (ofc. with autosquash, autostash, updaterefs and rebasemerges), reset hard, push force-with-lease... Also: commit signing, url rewriting, conditional configs for different orgs, all that jazz. I was super productive with it and loved it.

And then Jujutsu came along and casually doubled my VCS productivity. I didn't see it coming!

nocman · 1h ago
Is there a particular pain point (or set of pain points) that you have using git which is removed when you use Jujutsu?

I am interested to know, because there seem to be a small number of people who really seem to like it, and up to this point I haven't been able to understand what it is that they are all so excited about.

BeetleB · 46m ago
I would think the obvious answer is how jj deals with merge conflicts.

In git, if you get a conflict, you feel like you have to resolve it now.

With jj, most of the times I get merge conflicts, I simply ignore them and deal with them later. A conflict is not at all a blocker.

touristtam · 8m ago
> With jj, most of the times I get merge conflicts, I simply ignore them and deal with them later.

Sorry? You what? How do you know which bit from which source goes where?

BeetleB · 4m ago
Here's a typical scenario.

You do a git pull, just so your branch isn't so out of sync. Immediately you get merge conflicts. You then tell jj "Hey, I'll deal with this later", and make a branch off of the last commit that was conflict free and continue your work there. jj stores the conflict as is, but your branch is conflict free.

When you feel you have the energy to deal with the conflict, you switch to the branch that has the conflict, and fix the issue(s). Then you can manipulate the graph (rebase, whatever) so you can have everything in one branch - your changes and the changes you pulled in.

nchmy · 1h ago
for me, everything git is a pain point. But its not so much painpoints that it addresses, as it is that it just makes entirely new things dead-simple to do, especially via jjui.

"megamerges" are one such example. ive shared many links, here and in other posts

marcuskaz · 2h ago
I suppose I want the article written for the experienced developer, convince me why I should try something different than the huge defacto standard that is git. I'm totally open to trying something new, but need a compelling case.

Beyond `jj undo` everything else in this thread feels just as complicated as git.

baq · 2h ago
do you know about git rerere? if yes, you might like jj.
pkulak · 2h ago
Say you start on Main, then make a new branch that you intend to be a PR someday. You make commit 1. Then another. Maybe 6 more. Now you realize that something in commit 1 should have been done differently. So, you "edit" commit 1. All the other commits automatically rebase on top and when you go back to your last commit, it's there. Same with _after_ you PR and someone notices something in commit 3. Edit it, push, and it's fixed.

You can do all that in Git, but I sure as hell never did; and my co-workers really appreciate PRs that are broken into lots of little commits that can be easily looked over, one by one.

lrobinovitch · 2h ago
You have to force push each time you do this, right? How do your coworkers find the incremental change you made to commit 1 after you force push it, and how do you deal with collaborative branches effectively this way? And if I don't want to work this way and force push, are there other benefits of jj?
Disposal8433 · 1h ago
IIRC it's push force with lease, ie non destructive push force. No one will be bothered or notice what you did.

And if you have conflicts, it's really easy to rebase and fix any issue.

baq · 2h ago
the heuristic is 'if you know about rerere and especially if you use it, you should try jj'. if you never force push, you might not see value in jj. (I basically always force push.)
lrobinovitch · 2h ago
That makes sense, good to know, thanks.

> I basically always force push

How do your colleagues deal with this, or is this mostly on experimental branches or individual projects?

smw · 1h ago
It's generally fine if you force push a branch that you're the only one working on. In many projects, there's an expectation that the 'PR Branch' you create in order to make a github pull request is owned by you, and can be rebased/edited/force-pushed at will. It's very common to do things like `git commit --amend --no-edit` to fix a typo or lint issue and then force push to update the last commit.

This has it's problems, and there's a reason things like Geritt are popular in some more sophisticated shops, as they make it much easier to review changes to PRs in response to reviews, as an example.

baq · 1h ago
The PRs are either small enough that it isn’t a problem or large enough that it isn’t a problem… the odd in-between PR experience sucks and it’s one of the cases when I sometimes add more commits instead of force pushing.

+1 to sibling gerrit recommendation; I used to use it a decade ago and it was better then than GitHub PRs today.

whateveracct · 1h ago
People barely ever work off my branches.
ileonichwiesz · 1h ago
Okay, sure, but if I realize I should’ve done something differently in commit 1, why wouldn’t I just make a new commit with the fix?
paradox460 · 46m ago
You can actually do that in JJ too. And you can take a change that's full of changes to other files, run a single command, and have those changes automatically put into the most recent change (save the one you're working on) that modified it recently.
tomstuart · 1h ago
Do you want another person (or yourself in the future) to be able to read your commits, in order, to get a clear account of what changed & why? If so, you should fix up those commits to address mistakes. If not, it doesn’t matter.
KallDrexx · 1h ago
Not the OP but for me, no I don't actually.

In a PR branch, my branches usually have a bunch of WIP commits, especially if I've worked on a PR across day boundaries. It's common for more complex PRs that I started down one path and then changed to another path, in which case a lot of work that went into earlier commits is no longer relevant to the picture as a whole.

Once a PR has been submitted for review, I NEVER want to change previous commits and force push, because that breaks common tooling that other team mates rely on to see what changes since their last review. When you do a force push, they now have to review the full PR because they can't be guaranteed exactly which lines changed, and your commit message for the old pr is now muddled.

Once the PR has been merged, I prefer it merged as a single squashed commit so it's reflective of the single atomic PR (because most of the intermediary commits have never actually mattered to debugging a bug caused by a PR).

And if I've already merged a commit to main, then I 100% don't want to rewrite the history of that other commit.

So personally I have never found the commit history of a PR branch useful enough that rewriting past commits was beneficial. The commit history of main is immensely useful, enough that you never want to rewrite that either.

christophilus · 1h ago
It’s useful for me to see the mistake and the fix, as it is a good way to jog my memory about the “why” of things. Pristine commit history is not important to me.
adastra22 · 2h ago
I do this every day in git. “git rebase -i [hash]” fyi.
baq · 2h ago
you think you do, but you don't; jj edit is much, much better than an edit step in a rebase - it essentially keeps rebasing while you're editing, so you can always see which changes get conflicts, then you are free to resolve them, or not, at your convenience.
8n4vidtmkvmk · 21m ago
Jj edit isn't even the jj way of doing things. Should be jj new. Unless you have changes stacked after then you'd do jj new -A. And squish when you're done
adastra22 · 2h ago
So you get all merge conflicts at once? How is that better?
baq · 2h ago
it's exponentially better because you don't need to resolve them until you're ready. conflicts are committed to the local repo like everything else, commits with conflicts are noisily warned about and you can fix them whenever instead of having no other option than immediately.
ec109685 · 1h ago
To the sibling comment that is too deep to reply to, this covers why delayed conflict resolution is advantageous: https://news.ycombinator.com/item?id=45084835

It’s for other branches that hang off the commit that introduced the conflicts.

adastra22 · 2h ago
How does your repo work with conflicts? How does it compile?
baq · 1h ago
The edited commit, assuming it doesn’t have conflicts with predecessors, builds just fine. Successor commits with conflicts that you just introduced predictably don’t - but you aren’t editing them, so it isn’t a problem. In fact, that’s exactly why this feature is so compelling.
philwelch · 2h ago
I do that in Git all the time. JJ might be easier in some sense but “more powerful” implies that it can do things that are impossible in Git.
sunshowers · 38m ago
If you're in the middle of a git rebase -i of a stack of 20 commits, and realized while editing commit 15 that you made a mistake at commit 8, how do you go back and edit commit 8 without having to complete the rebase -i?

This is not contrived — this is an entirely realistic scenario that I use jj to handle all the time.

Vinnl · 1h ago
I think generally when people say that for jj, they mean it can do the same things with fewer concepts.
sswatson · 39m ago
The author lists that as a separate benefit, though.

My interpretation is that jj makes certain useful operations convenient to use that would be so complex in git as to be completely impractical. Something like jj undo would be a simple example: jj users can do it, and git users can’t, even though it’s logically possible in both systems.

jennyholzer · 3h ago
I agree. I'm willing to give them the benefit of the doubt to some extent because existing Git UIs are pretty poor in my opinion. But I'd like to see some more meat on the bone, in particular a demonstration of why this is easier/more powerful/more convenient to use than the alternatives.
tcoff91 · 2h ago
The main thing that makes it more powerful imo is that you can accomplish insane rebases with 1 command that would be really difficult with git.

Like let’s say you have 4 separate PRs in review that have no dependency on each other. You then work on new stuff on top of an octopus merge of all 4. You are exploring different approaches to a solution so you have several anonymous branches where you have tried different things. You want to rebase on master, so you just run jj rebase -d master. All 4 PR branches, the octopus merge, the anonymous branches, they all get rebased with that 1 command. If there are conflicts the first class conflicts mean that you can fix the conflicts whenever you want. If one of your experimental anonymous branches is in conflict but you are unlikely to go with that approach, just leave it in a conflicted state unless you change your mind that you want to actually go that direction.

kyrra · 3h ago
One example: Merge conflicts can be submitted as a proper entry and dealt with later: https://jj-vcs.github.io/jj/latest/conflicts/
paradox460 · 3h ago
I've been enjoying JJ recently, after giving it another try. I'd tried it when it was new, and the sharp corners were still a bit too sharp for my liking.

JJ seems to be part of a new "era" of tooling that's just really good. I mused about this a bit in a blog post:

https://pdx.su/blog/2025-08-13-the-quiet-software-tooling-re...

sunshowers · 2h ago
Nice article! I do think standards for tooling have gone up a lot in the last few years. Rust is certainly a part of it.
nchmy · 3h ago
im glad to see you also use and love mise.

Mise, jj (and its phenomenal jjui TUI, which I see you mentioned there), and uv for python are nothing short of revolutionary, as far as I'm concerned. Just beautiful tools.

paradox460 · 2h ago
I probably should mention things like atuin and fish, which bring, if not joy, absence of frustration when using my computer
nchmy · 1h ago
Atuin is great too! I recently switched to it from fzf.

zoxide is similar and beautiful as well. I use both all day.

paradox460 · 44m ago
I love zoxoxe, and even have it plugged into my Alfred, with minor tweaks
ItsHarper · 56m ago
I'd definitely include nushell in this
yard2010 · 1h ago
Bun leads this movement.
shepherdjerred · 38m ago
Bun is great, but that's overselling it
paradox460 · 41m ago
While bun is extremely impressive, I'd not say it leads the movement more than anything else. For me then biggest sea change in developer QoL has to be Mise, followed by JJ. Everything else is more niche, but I use mise and JJ in every project.

Don't get me wrong, I really like bun. I run my blogs asset pipeline on bun, and run my home automation on it as well, but at the end of the day it's a js runtime, competing with the also excellent deno

8n4vidtmkvmk · 25m ago
It's more than a runtime. It's a test runner, package manager and build tool and shell interpreter. The first 2 in particular are big for me. Build tool needs work.
BeetleB · 2h ago
I had used jj for only a month before I switched back to git for a particular project at work. I felt that jj was *really* nice, but nothing more.

After returning to vanilla git, I was missing the jj convenience within hours.

https://blog.nawaz.org/posts/2025/Aug/the-jujutsu-effect/

andai · 1h ago
>but nothing more

What does that imply?

BeetleB · 1h ago
What I mean is that using jj didn't seem like a radically new thing - it was simply a nicer git.

But when I had to go back to git, I learned that all those little niceties really added up.

lemonberry · 1h ago
From their post:

"Within hours, I found myself being exceedingly cautious about everything. I missed the confidence jj undo gave me. I missed the simplicity of jj new and jj describe."

nchmy · 1h ago
You missed the point - the question was, if jj is really nice, then why "nothing more"?
incognito124 · 2h ago
Something about appreciating only after losing
ysofunny · 1h ago
also, demonstrating a marked improvement in the experience.

it really does seem like we all gonna be using jj soon enough

I recall pijul.org that was another working prototype of better git

and I wonder how much overlap is there in the way they have made the improvements.

hooper · 58m ago
Jujutsu has "first class conflicts", but it's different from Pijul's "theory of patches". As far as I know, the other big stuff like "working copy is a commit" and the "operation log" (which allows for `jj undo`, safe concurrency, etc) is not present in Pijul. The approaches to Git interop are very different.
baq · 1h ago
pijul is one of the projects that I’d just sponsor a team for a few years if I was a megacorp or a government research agency because it’s just so damn cool in theory, but has too many rough edges in day to day practice (IOW I’d like to try it but would need pijul colocate for it to make sense)
ivanb · 1h ago
Supposedly, Pijul doesn't have the "force-push to trunk" problem. This alone makes it interesting.
fiddlerwoaroof · 1h ago
pijul uses a completely different model of version control than git (stores diffs rather than snapshots). And so the cost of switching and interoperation is a bit higher than jj which basically acts like a nice UI over git.
jennyholzer · 3h ago
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?

paradox460 · 3h ago
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

jennyholzer · 3h ago
Stacked diffs is a great feature. Thanks for the response!
paradox460 · 2h ago
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...

nchmy · 1h ago
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...
paradox460 · 39m ago
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

aseipp · 59m ago
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 :)

nchmy · 3h ago
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

jennyholzer · 3h ago
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.

senekor · 2h ago
> 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 :-)

veqq · 2h ago
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.
baq · 2h ago
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.
senekor · 2h ago
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" ;-)
thramp · 2h ago
(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.

wry_discontent · 2h ago
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.

trueismywork · 49m ago
How do you incrementally resolve merge conflicts in magit?
veqq · 2h ago
jj is similar to a magit cli, brought to the rest of the world. There's no benefit to switching from magit.
tombert · 58m ago
Interesting; despite being chronically online I hadn't actually heard of Jujutsu before. I like the idea of a better VCS still using Git under the covers, if for no other reason so that I can continue to use Github or Gitlab to back up and share my code with people. I've never been able to stick with Fossil or Bitkeeper even though they are both very neat because they've never been "sufficiently better" to override the network-effect of Git's popularity.

I'll need to play with this. I don't know that I'll stick with it but I'd be happy enough to be wrong.

ec109685 · 40m ago
This tutorial is excellent. It’d be helpful to also include how jj flows map to pull requests in the GitHub/GitLab model, since many new jj users collaborate via PRs with main protected by default.

What’s the best way to represent a stack? How do you model jj’s editing a commit at the bottom where everything above implicitly rebases when pull requests are open?

One of the most intimating things is fumbling around with your vcs when an expert is reviewing your code.

collinmcnulty · 2h ago
I’ll hop on the train and say that I’ve been using jj recently as well, and it’s given me that feeling of safety and freedom I got when I first started using version control 10 years ago. That sense that “well this is a crazy idea but I’ll just commit now and try it, I can always roll back”.
amadeuspagel · 1h ago
> Jujutsu is compatible with Git. You're not actually losing anything by using Jujutsu. You can work with it on any existing project that uses Git for version control without issues. Tools that integrate with Git mostly work just as well with Jujutsu.

If I use git from zed and jj from the command line, will that just work?

paradox460 · 37m ago
Generally. JJ will sometimes leave git in a detached head state, but it's usually pretty easy to recover from on the git side. The one thing I'd caution on is making sure you keep your bookmarks on the JJ side up to date. These translate to branches, which git needs to know where it is

You might want to set up this feature: https://github.com/jj-vcs/jj/discussions/3549

layer8 · 2h ago
One showstopper for me is that Jujutsu doesn’t support .gitattributes (https://jj-vcs.github.io/jj/latest/git-compatibility/).
mdaniel · 1h ago
In every one of these threads I learn some new axis of git that JJ doesn't support, so I really do wonder if JJ should have squatted upon a different DVCS given how much it wants to do things the JJ way leading to folks with git experience being sad
nchmy · 1h ago
nah, git was absolutely the right thing to squat on - its ubiquitous, so making it seamlessly powerful and easy to use makes for easy adoption. If it was built on pijul or whatever, I'd never have given it a try.

to the extent that niche things might not be supported (yet), so be it. It suits the needs of the vast majority of people. Moreover, if you need those things, I BET you can just do it via git and then carry on working in jj, since jj sits on top of git

verdverm · 1h ago
or LFS, hooks, submodules, shallow clones
xmonkee · 1h ago
Does jj effectively support stacked diffs on github? I've been paying through the nose for Graphite lately because it does, and the feeling I get is I'm just paying for their nice cli tool. `gt create` and `gt sync` is all I need. I don't really fully agree that their interface is entirely necessary or worth the $3500 per year it costs right now for my team.
paradox460 · 34m ago
Kind of. You can do most of it by hand, and there are some community made tools that improve the experience and basically give you graphite lite

https://github.com/keanemind/jj-stack

baq · 1h ago
GitHub needs to redesign PRs to properly support stacking them. It isn’t a client problem, but jj does make rebasing multiple branches correctly trivial, so if GitHub supported this workflow in a non-pretend fashion, it’d work.

If rebasing correctly is enough to support your use case, then the answer is ‘it’ll work’.

shepherdjerred · 36m ago
jj is great, but it doesn't quite fill the void of Graphite.

I've heard good things about https://abhinav.github.io/git-spice/

palata · 1h ago
> Jujutsu is more powerful than Git

Depends on your workflow, I guess. I need to sign with different security keys, and for that I use "defaultKeyCommand" in git. Doesn't exist in Jujutsu.

mdaniel · 1h ago
I was one of the early adopters (cause I enjoy kicking the tires on things) and brought awareness of the need for gpg signing at all into JJ, so I wouldn't overlook the value in bumping https://github.com/jj-vcs/jj/issues/6688 so they can eventually get you there
Ericson2314 · 2h ago
I want to read "Jutustsu for Git experts"

For example, will the committing of conflicts (a good idea I agree), mess up my existing git rerere?

Also I agree that the staged vs unstaged distinction is stupid and should be abolished, but I do like intentionally staging "the parts of the patch I like" while I work with git add -p. Is there a a lightweight way to have such a 2-patch-deep patch set with JJ that won't involve touching timestamps unnecessarily, causing extra rebuilds with stupid build systems?

mdaniel · 1h ago
> Also I agree that the staged vs unstaged distinction is stupid

...

> I do like intentionally staging "the parts of the patch I like" while I work with git add -p

is a mysterious perspective to me. I guess with enough $(git worktree && git diff && vi && git apply) it'd be possible to achieve the staging behavior without formally staging anything but yikes

I just checked and it seems that mercurial 7.1 still doesn't believe in $(hg add -p) so presumably that 'worktree' silliness is the only way to interactively add work in their world

zamalek · 2h ago
I'm a through-and-through JJ convert. One papercut I have experienced a few times (though I am getting much better at avoiding) is what to do when I forget to `jj new`. Assuming that I have pushed the current bookmark to the remote, is there any way to recover a new change that is the diff against the remote? I have tried rebasing, but that leads to bookmark ambiguity instead of the solution I'm looking for.
aseipp · 34m ago
If I understand you correctly, then you can use `jj interdiff --from name-of-branch@remote --to name-of-branch@git` in order to recover the diff between the remote branch commit and your local version of it; you could then turn that invocation into a Git .patch file and reapply it with patch(1). This only works for one commit.

The more general solution you're looking for I guess is some kind of "split based on interdiff" or something like that. I don't believe there's any way to accomplish this in a single stroke, though.

benoitg · 53m ago
I fixed this by changing the default immutable heads to include all remote bookmarks. This way, you cannot edit them and the new commit is automatically created when you push to the remote branch.

  [revset-aliases]
  "immutable_heads()" = "trunk() | tags() | remote_bookmarks()"
dylanhu · 1h ago
I also run into this often, I wonder if there is a simple built-in feature that would allow you to diff against the remote.
abound · 1h ago
There's a few different ways to fix this, but here's what the official docs suggest: https://jj-vcs.github.io/jj/latest/FAQ/#i-accidentally-chang...

TL;DR - `jj evolog` and then restore changes from the relevant secret commit ID

zamalek · 1h ago
But that would undo what I've done, right? I Wang to keep the changes but only diff them against what I've pushed.
dzaima · 39m ago
You can do a `jj new; jj restore --restore-descendants -f commit_id -t @-` with a commit id (not change id!) from the evolog to "inject" a snapshot from the evolog below your current @, leaving the file state at @ (and everywhere else in the log) intact.

Or if you have a commit ID (or otherwise revset; so a "main@origin" or whatever would work) of a specific commit that you want already, can use that instead of course too.

_bent · 10m ago
i guess you can run `jj duplicate` before?
AndrewHampton · 2h ago
Is `jj split` a good option?
zamalek · 1h ago
I've tried it, but then I have to remember what has been pushed.
ivanb · 1h ago
I haven't yet given jj a proper trial, so pardon the ignorance. All I've seen are conveniences regarding the working the copy. Besides the subjectively terrible UI, my biggest gripes with Git have to do with collaboration. A rebase may unintentionally overwrite someone's work. A force-push to trunk breaks every other developer's working copy. With "distributed" being in the name of this whole class of VCSes, I would expect that such things just wouldn't happen, but here we are. As I understand it, jj inherits all of these problems and adds better concepts and UI for manipulating the working copy. I'm not sure this alone is a good enough justification for a switch. Of all the Git's features I use a tiny, proven subset and stay on the beaten path. It makes it bearable enough.
boltzmann64 · 24m ago
I am think you are misunderstanding the entire premise of git. There is no "force push to trunk breaks every other developers' working copy." There is no central repo/trunk where all the commits are pushed. You are probably thinking of svn.

In git, your repo is the canonical repo and that is where you work. You work on a new feature and when you are ready, you "git format-patch" and "git send-email" to the community via the mailing list or other developers. A discussion may happen and people may or may not decide to apply the patch to their own repositories, with "git am." This doesn't break every other developers' working copy because they decide how to apply the patches they got in their email. No central repo, no trunk, guaranteed by the d in git dvcs.

paradox460 · 50m ago
JJ let's you have multiple "versions" of the same branch, although not directly. Typically it comes about when you've made changes and someone else has made changes, and the conflict resolution can't happen cleanly, due to each path taking a difference, unreconcilible approach. You'll have to resolve those and unify the different "branches", but it's no harder than any rebase in git land (generally easier because jj's conflict markers are even better than git's 3 part system)
dzaima · 1h ago
Working copy handling differences is certainly an aspect of jj, but, at least for me personally (esp. given me having grown up with git), it's probably my least favorite difference from git. And yet I've moved most of my personal things from git to jj.

A significant other thing jj does is introduce change IDs (i.e. a (randomly-generated) ID that stays stable even as a commit is amended), with which it should be easier to track changed commits across forks/rebases/edits/pulls/fetches, though I've yet to use jj for collaborative projects to see how much that pans out.

Generally jj makes rebasing things, and generally editing history so much more easy than git, so force-pushes messing with branches is much nicer to "fix" however needed. Being able to leave commits in a conflicted state and resolving only when actually needed also should help.

paradox460 · 30m ago
One of the quiet bit of genius is that JJ change ids use a different set of characters for base16. Instead of 0-9A-F they use k-z
trueismywork · 50m ago
The ability to resolve merge conflicts one part at a time is a game changer itself.

> A force-push to trunk breaks every other developer's working copy.

Only if they pull your broken trunk as well. Otherwise you're just wrong.

> A rebase may unintentionally overwrite someone's work.

No only your copy of someone's work.

quectophoton · 2h ago
Would it be accurate to describe Jujutsu as "a Mercurial-inspired frontend for Git"?

Also, another question I have for people who have used Jujutsu: Is it focused on interactive use, or is it also convenient to use for automatic/non-interactive use?

For example, situations like:

* A CI/CD pipeline that periodically adds stuff to the repo, or a pipeline that modifies files when triggered by specific events.

* Server setup scripts that clone a repo with common config and then make a new commit after applying patches for host-specific changes.

paradox460 · 2h ago
Not really, but it's a strong enough description that people who know what both are would understand

JJ is a whole new VCS, that just so happens to be backwards compatible with git, and currently uses git as it's storage engine

It builds atop the knowledge we gained since mercurial and git were both new, not making mistakes that the others made, as well as knowledge from newer VCS systems like fig and sapling

njaremko · 2h ago
Has anyone who's enjoying Jujutsu tried Meta's Sapling? I've been using it lately with the VS Code plugin, and it's been great. My understanding is that Jujutsu is pretty heavily inspired by Sapling and Google's patch-based git workflow?

https://sapling-scm.com/

sunshowers · 2h ago
I used to work on Sapling and Mercurial while at Facebook. I've been using Jujutsu full time for the last two years.

Jujutsu is in a sense the final form of that style of VCS, which I characterize as making commits first-class rather than branches, and providing powerful tools for managing long queues of stacked changes (git rebase -i is nice but has many limitations that don't exist in Jujutsu).

I go into some more detail in my testimonial, the first one at https://jj-vcs.github.io/jj/latest/testimonials/#what-the-us....

thramp · 2h ago
I’d second Rain’s reply, but having gone from git to sapling to jujutsu, I feel like the jump from sapling to jujutsu was as big as the jump from git to sapling, in terms of “oh, this is a way nicer workflow”. I really like and miss Sapling’s interactive smart log, but I found jj’s conceptual simplicity to be more compelling than ISL. That said, VisualJJ and Jujutsu Kaizen (both listed on https://jj-vcs.github.io/jj/latest/community_tools/) might give you the ISL-style experience you’re looking for.
0-R-1-0-N · 2h ago
I would like to see an example of someone showing the workflow for using jj and doing feature branch. I don’t really get that yet. Most examples only show that they commit once and then push. But what if it requires multiple commits.
alabhyajindal · 2h ago
I don't know anything about Jujutsu but the Git equivalents for some of these commands are more readable:

  jj bookmark move main --to @-
  git add . 

  jj git init --colocate
  git init
Also using `jj git` everytime feels repetitive.
a022311 · 1h ago
This feels like a troll, but I'll answer anyway.

The first command you mention is `jj bookmark move main --to @-`, which apart from the `@-` part, is easily read and does exactly what is written. It moves the main bookmark to the parent commit. The main difference to git here is that updating a branch is an explicit action. Jujutsu supports creating aliases and many users have a `jj tug` alias that moves the current closest branch to point to the parent commit. `git add .` just adds all changed files in the current directory to the current commit. That's an entirely different thing and Jujutsu takes care of doing that automatically.

The second command creates a git repository and while it is longer, I doubt the extra keystrokes will hurt you much. If it's too long, just alias it.

As for using `jj git`, since Jujutsu supports multiple backends, backend-specific commands require the `git` namespace. You generally only need it for cloning, pushing and fetching (with the option for aliases again). You'll rarely need to create a new repository or add a remote.

alabhyajindal · 1m ago
Thanks for the reply! I wasn't trying to be dismissive in my original comment. Just making an observation as someone new to Jujutsu.
thewisenerd · 2h ago
i've been using jj for the past few weeks on a feature heavy project. my entire "workflow" is no more than these 4 commands, rinse and repeat:

    jj new main@github
    jj describe
    jj git push -c {prefix}
    jj git fetch
my couple thoughts:

- i'm forced to be "strict" with my changeset since there's no `git add -P`

- bookmarks are a pain to keep up-to-date with `jj new`, i don't know if i even want to do that. for multi-commit changes, i've defaulted to `jj new` a couple times as needed, and `git push -c` the latest.

- i'm sure some day i'll understand the `@..` and `roots()` incantations but for now the most complex thing i've successfully pulled off is `jj rebase -s 'roots(main@github..@)' -d main@github`

i don't think trying to map your current git flows 1-to-1 onto jj is going to be a very fruitful exercise.

paradox460 · 2h ago
> - i'm forced to be "strict" with my changeset since there's no `git add -P`

JJ split is your friend

> - bookmarks are a pain to keep up-to-date with `jj new`, i don't know if i even want to do that. for multi-commit changes, i've defaulted to `jj new` a couple times as needed, and `git push -c` the latest.

Check out the common community alias JJ tug. It's used enough they're considering adding it as a feature

epolanski · 2h ago
Can't you just add an alias that takes two arguments that takes a message and a bookmark name? I aliased the entire describe, commit, bookmark and push to a single command.
senekor · 2h ago
Just a few tips:

> - i'm forced to be "strict" with my changeset since there's no `git add -P`

Check out the command `jj split` and possibly `jj squash --interactive`.

> - bookmarks are a pain to keep up-to-date with `jj new`

There's a neat alias a lot of people use:

```toml [aliases] tug = ["bookmark", "move", "--from", "heads(::@- & bookmarks())", "--to", "@-"] ```

It finds the closest bookmark and moves it to `@-`. Pretty much exactly what you want when adding more commits on top of an existing branch.

IshKebab · 1h ago
Another question for jj people: one concrete thing I find annoying with Git is that it's completely incapable or rebasing anything with merge commits. Can jj do this? Even very simple merges are too much for git to rebase. It's especially annoying with `git subtree`. If I want to rebase anything to do with that I don't bother now - I just start again from scratch.
aseipp · 22m ago
Yes. I have one repository, which is a fork of an OSS project, with a 7-way octopus merge of various patches I carry, and another 2-way merge on top of that one. Every week or two I pull the latest changes from upstream and I rebase all 9+ branches in a single command. If there are conflicts on any one of the parallel streams of work, I can trivially fix each conflict individually in any order I want.

Jujutsu does not treat merge commits any more or less special than non-merge "1-parent" commits. (We used to do this, actually, and occasionally special case merges, but most users found it very confusing.) This regularity means most commands work fine on merges. 'jj new X' is a new commit on top of X. 'jj new X Y' is a merge commit with X and Y as parents. 'jj new X Y Z...' is a 3-way merge, and so on and so forth for any number of commits. Similarly, 'jj rebase' can handle moving commits and preserving the graph structure no matter how many edges are involved in particular, and can add or remove parents from a given commit. This means that conceptually the jj commit graph is merely a simple, ordinary DAG, and operations are transformations on the DAG like you expect.

Actually, this exact workflow is beloved by many community members, and I guess I can take responsibility for popularizing it originally, the "Mega Merge" technique. Instant, easy rebase is an essential part of making this technique viable.

- https://ofcr.se/jujutsu-merge-workflow - https://v5.chriskrycho.com/journal/jujutsu-megamerges-and-jj...

lvl155 · 1h ago
OT, but are there agent-specific versioning systems? Or are people just retrofitting git/jj?
KolmogorovComp · 1h ago
Why would agents need a specific versioning system?
verdverm · 1h ago
Perhaps because Zed thinks it's a good idea?

https://zed.dev/blog/sequoia-backs-zed

DeltaDB (CRDT based)

jdmg94 · 1h ago
what does "retrofitting" git implies? I am confused by the agent-specific systems bit.
BeetleB · 1h ago
If people want an example of jj being more powerful yet simpler than git:

jj doesn't have an explicit concept of the staging area or the stash, but it supports both and in a more powerful way.

In jj, the staging area is simply a terminal node in the graph. You make the changes you want. And when you are ready to commit, you simply push all the changes to the parent node. The terminal node is your index, the parent is the committed node. This is a construct that is entirely in your mind. You don't have to work this way, but if you really like the concept of a staging area, that's how you do it.

Have you ever done a git add, then made some changes, done a subsequent git add, only to realize you clobbered some important code that was in your first git add? How are you going to recover from this? I don't know if the git reflog has this information.

In jj, everything is saved. Think of each commit in jj as a supernode. Inside the supernode are a bunch of atomic nodes. You can think of each atomic node as the equivalent of doing a git add, with each git add being another atomic node in that supernode. So if you've ever clobbered your changes like this, you simply go and remove the last atomic node or modify it however you want to resolve it.

Effectively, jj gives your index its own version control.

Similarly, in jj, a stash is simply a branch. It's a node in a branch that stores the state of the working directory. If you're in the middle of a feature and suddenly need to stop working on it to work on something else, you simply make a new node off the relevant node you're going to work from. In other words, you will just create a new branch while retaining your work in its own branch.

Have you ever popped from the stash, made some changes, and then realized you clobbered something really important and wished you'd applied the stash instead of popping it? That's not at all a concern in jj. Effectively, you have a version controlled stash, and you naturally stash in jj without ever having to know the concept of a stash.

After I'd been using jj, having a separate concept called "index" and a separate concept called "stash" suddenly seemed ridiculous. I don't know why Git decided to have these distinct concepts. At the end of the day, it's all a graph and you are manipulating nodes and the contents within each node. What you need are operations to help you manipulate those.

I have to really emphasize that a typical jj user gets all this power just by learning a few operations - they don't have to learn so many different concepts.

How many different ways are there to do a git reset? In jj, I've only ever had to do jj undo and it covers pretty much all those use cases.

notallm · 1h ago
thought i was gonna learn how to fight for a second lol
efilife · 1h ago
same, I'm kinda disappointed
firtstea · 2h ago
I wish it were jiu-jitsu for everyone. I was disappointed to see it was a Rust project.
ivanjermakov · 2h ago
> Jujutsu is easier to learn than Git. Git is known for its complicated, unintuitive user interface. Jujutsu gives you all the functionality of Git with a lot less complexity.

Being easier to use does not mean being easier to learn. Complicated workflows requiring deep understanding might be harder to learn because of a higher abstraction.

Disposal8433 · 31m ago
> deep understanding

It took me less than one day to switch from git.