Most active commenters
  • BeetleB(5)
  • steveklabnik(4)
  • senekor(3)
  • nocman(3)
  • nchmy(3)
  • 1718627440(3)
  • KingMob(3)
  • socalgal2(3)
  • MangoToupe(3)

←back to thread

Jujutsu for everyone

(jj-for-everyone.github.io)
434 points Bogdanp | 45 comments | | HN request time: 0.629s | source | bottom
Show context
marcuskaz ◴[] No.45084298[source]
> 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.

replies(7): >>45084316 #>>45084327 #>>45084439 #>>45084678 #>>45088571 #>>45092597 #>>45093098 #
senekor ◴[] No.45084439[source]
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.
replies(3): >>45084539 #>>45084685 #>>45087146 #
1. jennyholzer ◴[] No.45084539[source]
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.

replies(3): >>45084724 #>>45087011 #>>45088109 #
2. senekor ◴[] No.45084724[source]
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!

replies(1): >>45085346 #
3. nocman ◴[] No.45085346[source]
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.

replies(4): >>45085518 #>>45085779 #>>45087984 #>>45091664 #
4. nchmy ◴[] No.45085518{3}[source]
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

replies(1): >>45086891 #
5. BeetleB ◴[] No.45085779{3}[source]
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.

replies(2): >>45086184 #>>45086767 #
6. touristtam ◴[] No.45086184{4}[source]
> 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?

replies(1): >>45086227 #
7. BeetleB ◴[] No.45086227{5}[source]
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.

replies(3): >>45086667 #>>45087058 #>>45091805 #
8. 1718627440 ◴[] No.45086667{6}[source]
So you essentially do a fast-forward until the first commit with a merge commit and then take the previous one?

Sounds like something that could also become a flag for git merge.

replies(2): >>45087968 #>>45088746 #
9. nocman ◴[] No.45086767{4}[source]
> In git, if you get a conflict, you feel like you have to resolve it now.

I guess I view that as a positive rather than a negative. I'm not saying that dealing with merge conflicts is a picnic -- it isn't. I just find it difficult to believe that ignoring them and resolving them later will improve the situation in the long run.

replies(4): >>45087538 #>>45087964 #>>45089871 #>>45090681 #
10. nocman ◴[] No.45086891{4}[source]
> for me, everything git is a pain point

Yeah, I was looking for something (or "things") specific. An "I hate everything about it" explanation doesn't really compel me to try out the alternative.

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

I read through one megamerge link you shared ( https://v5.chriskrycho.com/journal/jujutsu-megamerges-and-jj... ). So the argument seems to be (forgive me if I'm reading this wrong), if you have multiple versions of a single set of source files that all have differing changes, for you JuJutsu makes it easier (easier then git, that is) to merge them into the final commit you want to end up with. Is that correct?

Just trying to make sure I understand. Honestly, after reading that article I am still not feeling the need to try Jujustu out. I'm still open to being convinced, but have yet to see anything that makes me go "wow, I need to try that!".

replies(3): >>45087517 #>>45089162 #>>45097666 #
11. EMM_386 ◴[] No.45087058{6}[source]
> When you feel you have the energy to deal with the conflict

So you just kick the can down the road and end up with possibly an even more difficult conflict resolution?

replies(2): >>45087653 #>>45088598 #
12. nchmy ◴[] No.45087517{5}[source]
"multiple versions" = feature branches, possibly all in progress, probably all related. In a couple seconds, you can create a merge on top of all of them to join up their combined functionality/changes, work on top of that ON ALL OF THEM AT ONCE, and then squash all the relevant changes into the respective PRs that others (who are just using git) can review and merge into main.

At this point A LOT has been written in this and other threads, as well as lots of essays and tutorials about how jj just completely transforms your workflow. If you're curious, you'll seek it out. If not, that's fine as well.

replies(1): >>45088708 #
13. hellcow ◴[] No.45087538{5}[source]
It's not about "ignoring" conflicts. In jj you're often working with stacked diffs, and merge conflicts can impact a dozen "branches" all at once. This is trivial to resolve in jj and a nightmare in git. It lets you work on them one piece at a time and upon resolving it, instantly see the conflicts fixed across all your branches at once.
14. BeetleB ◴[] No.45087653{7}[source]
> So you just kick the can down the road and end up with possibly an even more difficult conflict resolution?

That sentiment is true for pretty much anything in life one may decide to defer till later :-)

More concretely, it's often not hard to tell if deferring it will make it worse, or merely the same.

The whole point of version control is to give your mind some peace in not worrying about things ("Let's make this change and we can always revert if it doesn't work out"). Conflicts are no different. There's no fundamental reason a conflict needs to be treated like an emergency.

15. steveklabnik ◴[] No.45087964{5}[source]
It’s about giving you choice. If you want to then fix them immediately, you can. But you don’t have to if you don’t want to.

But really, it’s about something deeper: rebase is a first-class operation in memory, and not a serious of patch applications via the file system. They’re therefore lightning quick, and will always succeed, which is nice. If you get partway through resolving a conflict and want to change to something else for some reason, that’s possible and simple.

16. steveklabnik ◴[] No.45087968{7}[source]
Git won’t let the portion of the branch that’s still conflicted remain in conflict while you go and work on the other part.
replies(1): >>45090471 #
17. stavros ◴[] No.45087984{3}[source]
For me, it's two things:

1. I understood git better after ten minutes of jj than after fifteen years of git. Git just doesn't expose its underlying data model as well as jj does. I guess, if you already know git well, this isn't going to make a difference for you.

2. This question is a bit like asking what can I do with a calculator that I can't do with pen and paper? Technically, nothing, but everything will be so much easier that you'll be much more likely to use it. Even though I can, technically, stash my worktree and jump to another commit with git, it's so fiddly to unstash (especially with multiple stacked switches/stashes) that I just never did it.

With jj, I leave commits in the middle and jump to other commits (to fix a bug or make a small change I noticed I need while working on a larger change) all the time, because there's zero friction.

jj just removes all the friction that's prevalent in git. Things are easy in jj that in git are merely possible.

replies(2): >>45088720 #>>45089117 #
18. johnisgood ◴[] No.45088109[source]
> If you're interested in becoming a Git expert, I cannot recommend Emacs Magit strongly enough.

Yes, Emacs' Magit and Git Cola.

replies(1): >>45097101 #
19. sunshowers ◴[] No.45088598{7}[source]
Or none at all, if you decide to abandon that work (as has happened to me a bunch).
20. typpilol ◴[] No.45088708{6}[source]
What does the history look like then? Just a single merge from a ton of branches or?
replies(1): >>45089169 #
21. BeetleB ◴[] No.45088720{4}[source]
> With jj, I leave commits in the middle and jump to other commits (to fix a bug or make a small change I noticed I need while working on a larger change) all the time, because there's zero friction.

For git users who are wondering "What friction? I just git stash and jump to another branch":

In jj, you just jump without needing to type any command like git stash.

replies(1): >>45089997 #
22. riwsky ◴[] No.45088746{7}[source]
No. The GP making a commit off of the first non-conflict isn’t the essence of the feature he’s talking about, just an example of what he can do next.

He’d also be free to edit upstream to not commit, or split a change in two so that parts unrelated to the conflict are in their own change. The big idea is that he doesn’t need to blindly decide that before seeing what the conflict is.

23. KingMob ◴[] No.45089117{4}[source]
I've taken to summing it up as "jj makes everyone the git guru".
24. KingMob ◴[] No.45089162{5}[source]
> I'm still open to being convinced, but have yet to see anything that makes me go "wow, I need to try that!".

You might not find that feature, but I'd suggest giving it a go anyway. The list of jj technical superiorities is short, but the numerous quality-of-life DX improvements all add up to pleasant, fearless version control.

Even without editor support or a UI, I abandoned git forever last year after using jj for a couple weeks.

Just my $.02.

replies(1): >>45091651 #
25. KingMob ◴[] No.45089169{7}[source]
The parent is describing the megamerge pattern, which is a way to work on multiple branches at once.

You don't have to do that, and you rarely push it to others. History looks the same as git, usually, although I end up rebasing more than I ever did in git, since it's easier and safer.

26. raylu ◴[] No.45089871{5}[source]
the thing about rebasing/cherry-picking (including just popping the stash) in git is that you only have 2 choices: fix the conflict now or abandon the entire rebase/cherry-pick

with jj, you have the option to fix half of it and come back later. you can take a look and see how bad the conflicts are if you go a certain route and compare to another option

replies(1): >>45091729 #
27. socalgal2 ◴[] No.45089997{5}[source]
git stash is not that simple. you'd need to remember what branch that stash applies to to get back to where you were.

I'm new to jj. I'm still mixed on if I like it not. I think it's mostly familiarity. For example, switching to a commit puts things in the state before the files were committed. All my projects have a presumit step that says "hey! commit your files!" so they are all incompatible with jj at the moment or at leas the default. I end up having to do temp stuff like `jj new` (ok, now they're committed). Now run my presubmit scripts. Then `jj undo` so I don't have this unneeded commit. That said, I'm sure there's a better way, I just haven't gotten used jj yet.

Others have said this, `jj undo` and `jj op restore` have been lifesavers though. No matter what I do I can get back to where I was before I messed up.

replies(3): >>45091695 #>>45091791 #>>45092309 #
28. 1718627440 ◴[] No.45090471{8}[source]
I would just abort the conflict resolution.
replies(1): >>45096669 #
29. MrJohz ◴[] No.45090681{5}[source]
I think the word "later" is unhelpful in this situation because it implies all sorts of different timescales. You don't want to be resolving merge conflicts three weeks after you've created them, you're right!

Typically for me, "later" means "immediately after the rebase command has finished", which is very similar to git's "while the rebase command is running", but has some subtle and important differences.

For example, because the rebase completes first, I get to see roughly what the end-state of the rebase is before I start doing the hard work of fixing conflicts. This is useful as a sanity check - sometimes the reason I'm getting a bunch of merge conflicts is because I was rebasing the wrong things in the first place and included an extra commit somewhere. Seeing the result first gives me the chance to sanity check what I'm doing.

Another thing is that my repository is never in a broken state where I can't continue doing other things. There's no way in git to stash a rebase, say because I've realised a different approach might work better or just because I urgently need to work on something different. I either need to cancel the rebase and start it again later, or keep on going until it's over. In jj, because the conflicts are automatically checked in as part of the commits, I can easily jump backwards and forwards between the work I'm doing resolving my conflicts, and anything else.

Another way of thinking about it is that git is very modal. You check out a branch and are in the "branch" mode, and then you start a rebase and are in the "rebase" mode, and then you do a bisection and are in the "bisect" mode - it's difficult to move freely between these modes, and there's certain things you can only do in some modes and can't do in others. In contrast, jj has exactly one mode: "there is a commit checked out". The different operations like rebasing all happen atomically, so you never see the halfway state. But because things like conflicts can be encoded in the commit itself, you still have all the same power that the modal approach had, just with a simpler conceptual model.

30. nchmy ◴[] No.45091651{6}[source]
Jjui is an incredible TUI for jj. Its the only way I interact with jj
31. senekor ◴[] No.45091664{3}[source]
Yes and no.

Before I started using Jujutsu, I didn't have any pain points with using Git. I didn't understand what all the fuss was about. Git works well! So I totally understand how most Git users have that same reaction when hearing about Jujutsu.

I think the reason I even tried it out in the first place was because Steve Klabnik wrote a tutorial about it. I have a lot of respect for him, because the Rust book is really good. So I though: If Steve thinks it's worth it, I should probably check it out.

Now that I'm used to jj, going back reveals like 100 things that are immediately super annoying when using git. I don't feel like writing it all down TBH. :-) In a general sense, Jujutsu get's out of your way much better than Git. There are a lot of situations where Git blocks you from continuing to work. Have a merge conflict? Stop working, fix it right now. Want to check out another branch? Nu-uh, clean up your dirty worktree first. jj doesn't do that. Have a conflict? I'll record it in the commit, fix it whenever you like. Checking out another branch? No worries, I'll keep your work in progress safe in a commit.

32. skydhash ◴[] No.45091695{6}[source]
> git stash is not that simple. you'd need to remember what branch that stash applies to to get back to where you were.

I use the stash for changes I like or for small experiments, not tied to anything. For any other changes, I just create a wip commit and switch. It’s trivial to switch back and soft reset.

replies(1): >>45097251 #
33. skydhash ◴[] No.45091729{6}[source]
Are you using your editor or a special software/plugin for resolving conflicts. I used Sublime Merge in the patch, but now I’m using Magit+ediff. Resolving conflicts is quite trivial in that case. And I can always ‘rebase -i’ to revert some of the decisions I’ve taken.
34. MangoToupe ◴[] No.45091791{6}[source]
> git stash is not that simple.

It's a stack of diffs.

Anyway, I've probably used this to transfer changes between branches thousands of times. Once you grasp the underlying data model all these abstractions introduced by jujutsu seem more confusing.

That said, I do understand most people aren't going to take the day or so to read through any of the hundreds of detailed "explain the data model" articles online.

replies(2): >>45095062 #>>45095176 #
35. MangoToupe ◴[] No.45091805{6}[source]
Isn't this equivalent to simply hard resetting to before the pull? (Or the commit before the conflict?) Plus then you don't end up with an extraneous branch.
36. arcbyte ◴[] No.45092309{6}[source]
> git stash is not that simple. you'd need to remember what branch that stash applies to to get back to where you were.

This quote confused me for a while. I was thinking "git stash isn't branch specific its just a single bucket". But I realoze you must be making lots of little changes that are highly branch specific and then not wanting to commit those, but instead stashing them. Which would leave you with a hellscape of stashes that can't just be unstashed.

The biggest problem with git is people just inventing asinine ways to do things and ending up with absolutely stupid problems like that. No sane person does these things but yet I do keep encountering people digging holes and falling in them. It's a bit like people who invent the clever idea of having one repository with multiple code bases on different root branches. It's possible but you dont deserve to be working in this industry if you think its a good idea.

Git is simple. It's stupid simple. That's its problem.

replies(1): >>45107021 #
37. socalgal2 ◴[] No.45095062{7}[source]
Yes I know git stash is a stack of diffs. I’m responding to this

>> With jj, I leave commits in the middle and jump to other commits (to fix a bug or make a small change I noticed I need while working on a larger change) all the time, because there's zero friction.

> For git users who are wondering "What friction? I just git stash and jump to another branch"

git stash is not equivalent to jumping to another commit in jj

38. BeetleB ◴[] No.45095176{7}[source]
> Anyway, I've probably used this to transfer changes between branches thousands of times.

You could just use cherry pick.

replies(1): >>45095183 #
39. MangoToupe ◴[] No.45095183{8}[source]
That involves having to commit
40. steveklabnik ◴[] No.45096669{9}[source]
Then you’re back to the state before the rebase. Which is fine, the point is just that they’re not equivalent!
replies(1): >>45106167 #
41. mcepl ◴[] No.45097101[source]
vim-fugitive
42. steveklabnik ◴[] No.45097251{7}[source]
This is easy in jj too, I’ll often try something, jj new @- to try something else, and jj abandon whichever version I don’t end up using.

The nice thing is that all of this is part of the commit graph, not buried in stashes hidden from sight.

43. yencabulator ◴[] No.45097666{5}[source]
My read on jj so far has always been "convenience wrapper over a preexisting Git concept" and simultaneously "alternate CLI that might be easier to learn".

Much like BitKeeper was sort of like an automated set of conventions on top of SCCS, (and Git and BitKeeper are near-interchangeable if you don't look at any of the details,) jj is like an automated set of conventions on top of Git.

(I personally wish the jj project had leaned harder into "it's just Git operations, made easier" instead of the whole "abstraction over storage layers" spiel, which needlessly scares a person familiar with Git, and makes the project sound very wishy-washy. When you peek under the hood, it's just Git! If it wasn't, I probably wouldn't use it!)

44. 1718627440 ◴[] No.45106167{10}[source]
Yes. What's the equivalent would be to just keep the successfully rebased part. Right now you need to do keep the ref yourself.

> Sounds like something that could also become a flag for git merge.

45. socalgal2 ◴[] No.45107021{7}[source]
> But I realoze you must be making lots of little changes that are highly branch specific and then not wanting to commit those, but instead stashing them

No, I'm specifically responding to the person above who claimed "git stash" is the same as switching to another commit in jj. It's not.