Hacker News new | ask | show | jobs
by senekor 295 days 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.
3 comments

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.

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!

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.

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.

> 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.

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.

I've taken to summing it up as "jj makes everyone the git guru".
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.

> 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.

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.
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.

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.

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

> 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?

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.

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.

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

> 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!".

"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.

> 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.

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!)

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

Yes, Emacs' Magit and Git Cola.

vim-fugitive
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.

A couple of them seem more complicated, like the example further up on the page for postponing merge conflicts. In git I'd just abort the merge and do it later.

I also found the exchange about named branches funny, that ends with:

> Ok, you need to call `jj bookmark set -r@ XYX` (or `jj b s -r@ XYX`), so what?

Apparently this is excusable, but people like to complain about git's commands being too obtuse - as far as I understand the git version is "git checkout -b XYX", right? (Or I guess "git switch -c XYX" with the new commands)

> as far as I understand the git version is "git checkout -b XYX"

The difference is actually worse than that. There is not the regular git equivalent, because this step is just done implicitly for you, normally. That is, with jj, just because you had checked out the head of main and then you added a new commit, doesn't mean your new commit is now the new head of main. `jj bookmark set -r@ main` is the way you tell jj to actually advance main to your latest commit.

But you are right - `git switch -C main` would be more or less the equivalent in git if you were working in detached head mode, which is how jj normally works (note the `-C`, not `-c`, to forcefully update main to point to this commit).

That’s backwards, your git command is “move to this branch” and the jj command is “update where the branch points to,” so git reset —hard.
The git commands are "create new branch at HEAD and switch to it", and the context of the thread above sounded like that's the functionality they wanted?
“jj bookmark set” doesn’t create a new branch and switch to it. It updates the head of an existing branch to a new place.

jj doesn’t have a “name a new branch and switch to it” command, because you usually don’t bother naming branches until you’re using them up to a forge, and there’s no “current branch” concept. I creat new named branches with “jj git push -c” which names it for me, and switching branches is closest to jj new or jj edit.

They're closer to the right command than you are. `git reset --hard` will move HEAD to the given branch. The right command would be `git checkout -B branch` / `git switch -C branch`, to create or update `branch` to point to the current commit (except for the side effect that future commits will then go onto `branch` in git, while they won't in jj).

Basically, jj is just like working with git in detached head mode as far as I can tell.

You know, I was in the middle of some long flights and missed the -b! You’re right about that part, that’s my bad! I’m starting to forget git details at this point, haha. (I never used switch, always checkout -b)
do you know about git rerere? if yes, you might like jj.
This made me laugh. Thank you.
It’s funny because it’s true! ;)
There isn't a single thing in jj that's as complicated as git. I could go on to list a few features, but it would sound underwhelming, because you could do all that in git.

It's kind of like asking "why would I buy a digital camera when my film camera does all the same things? I can already see what the photo will look like when I take it, and developing my own film isn't that much of a hassle", yet film cameras have gone the way of the dodo, except for the occasional nostalgic enthusiast.

I don't think this is what the person you responded to is asking.

Their question is more, "why would I buy a digital camera that takes pictures in a new format that only a few cameras understand? All my tooling, 3rd parties, and other camera I own use the standard format. Even though I can see why the new format has advantages, I am still going to have to use the other format for all these other photos I have to work with, and there aren't equivalent tools in the new format for all these other photos things I need to do. Even if I buy this new camera, I am still going to have to work with the old format, so I'll have to learn how to use two formats now, and get used to two tool chains. Since the existing format is something I am going to have to use either way, how is it worth it for me to have to use two formats?"

You don't have two formats, though. Jj transparently works with git. I use it for everything and none of my collaborators is even aware that I'm using jj.
If you say that you can work only with JJ and never use git, you are delusional. For one, where is that JJ forge (i.e., the equivalent of Sourcehut)?
GitHub, or sourcehut, or whatever you prefer.

Maybe you feel that jj git fetch and jj git push are using "git" but it means you avoid the git cli in favour of the IMO better designed jj cli.

I could respond to this uselessly pedantic comment, but then nobody wins.
> more powerful than git

> not missing out on power

Two very different claims, and it only makes me more skeptical.