49 comments

[ 28.5 ms ] story [ 1143 ms ] thread
I must be getting old because I really don’t think git needs a simplified model. But hey, if people find value from this, more power to them. The blog is well written too.
I’ve been trying unsuccessfully to convert my team to jujutsu. I feel like what would be great is a page that really shows some common but complicated operations in git and how much easier they are in jujutsu. Something like the elevator pitch here but expanded on without the depth of Steve’s tutorial.

Maybe what I need to do is do a demo so people can see and ask questions.

I feel pretty dense, because I still struggle to get my head around automatically adding changes to a revision. Sometimes, I'll make a change locally to a file that I'll use during the development process that I have no intention of committing. With regular git, I never stage that file so there's no danger of accidentally pushing my change to the remote repo, but it seems with jj I'll need to somehow unstage that change or something to prevent this. Perhaps it's just habit, but I feel more comfortable explicitly saying what I want to commit rather that defaulting to everything. Or have I totally misunderstood jj?
I've been using jj for two weeks now and it's kinda exciting, because for the first time I'm comfortable with using version control just via the command line. With Git I always had to use a GUI (preferably Git Graph in VSCode) and launch all operations by right clicking items, but jj was simple and consistent enough that I could just start using it after reading Steve Klabniks tutorial.

The thing I'm running into right now is that I should really learn the revset language, so that I don't have to constantly copy paste ids from jj log

I've been using jj for a few weeks, and recently made an auto-commit-message script for it[1]. Just today I started working in an old git repo and thought that I should port the script to git. It turns out that jj made the script trivial because of immutable commits, and mt script would need to automatically do that with git: I use a rebase/amend/clean history workflow at work, so I would need the script to determine when to commit or when to amend. It's obviously possible, but I don't want to expend the effort - I just re-cloned it with jj.

It's amazing how quickly I forgot about the commit vs. amend papercut.

[1]: https://codeberg.org/jcdickinson/nix/src/branch/main/home/co...

JJ is brilliant.

I reluctantly moved to git from mercurial when host-after-host dropped mercurial support. git is a user-hostile POS that I never got used to. A thousand needless complications including nightmare merges, and an inscrutable command interface.

JJ eliminates all the git bullshit. Some incredible features:

* Merges never fail as conflicts are a first class feature. You can come back and resolve them at any time.

* You can reset the state of the repo to any particular point in history as JJ maintains a complete operations history.

* You can insert new changes anywhere and deal with the repercussions at leisure.

I started with Steve's tutorial but found it a bit wordy. So I used Gemini to produce a simple guide for me with: "You are an expert at DVCS systems like JJ. Act as my guide for the system and answer my questions with simple cookbook-style recipes."

I have been using JJ for a month and am never going back to git. It is such a pleasure to work with a DVCS that you don't have to fight at every turn.

I want to be excited about Jujutsu, but what always bothers me about JJ is that if you search the page you can find 'jj' 47 times and 'git' - 49.

Is there a good explanation of Jujutsu without referring to git? May be with some pictures? Am I the only one bad with memorizing SHAs when reading? Also, does it work with other people? Would it work in repo with 5 contributors? 20? 500?

EDIT: I am looking for tutorials with explanation on how JJ works, preferably without referring to Git, and even more preferably with some visual explanations, which, there are plenty for Git. It seems I am not very good in reading text trees. It is my issue, not yours, but may be you know something which would help.

For anyone who's debating whether or not jj is worth learning, I just want to highlight something. Whenever it comes up on Hacker News, there are generally two camps of people: those who haven't given it a shot yet and those who evangelize it.

You will be hard-pressed to find someone who stuck with it for a week and decided to go back to git. You will not find a lot of people who say they switched but just stayed out of inertia. Of course both of these do happen—nothing is perfect—but they are by far the exception. From my own personal anecadata, I have seen a 100% conversion rate from everyone who gave it a serious try.

I encourage you to let today be the day that you decide to try it out. It is far less effort to make the switch than you probably think it is: I was productive the same day I switched and within a week I had no remaining situations where I needed to fall back to git commands. You will quickly be more productive and you will find yourself amazed at how you ever got by without it.

I did that and went "back".

Most of the projects I do for money are on Github and Gitlab.

I got my hands on things like YT videos explaining, official docs, cheatsheets.

About 4 hours exploring, trying to use with some side projects.

I did the same decades ago from CVS/SVN to git (even tried Hg). At that time it was obvious the "revolution" + "evolution" effect. Also git provided some transition tools that were easier to use from my pov.

Now it's just "evolution".

I see the added power to work with different "branches" simultaneously, move commits in different order in a way that is easier to have some better management logic, etc.

This is basically compelling if you work on different facets on big monorepos.

But I want to work on one thing a time nowadays, do something reliable, instead several features simultaneously, even with AI assistance, so the gains are not that huge, yet.

Like you I ended up using git commands again naturally. Stopping using svn commands eons ago felt amazing.

I tried it a year or two ago and went back to git. I didn't dislike JJ, it just didn't cover all the things I needed to do my usual workflow at the time, and being the only dev on my team using it was a bit tricky

I've been meaning to give it another shot, and probably will after this article

Is there a magit equivalent? I heavily use magit's interactive features and extensions to the git UI (like spinoff, absorb, or the auto-backup thing)
I'm confused what this is?

Is it just a git frontend for people who are confused by git?

It says it abstracts the backend, but it's not clear how something so git-influenced will have abstractions that work with something like a centralized system like Perforce or Piper that has auto-increment numeric commits.

Some of the design decisions are also not great. Working copy as commit means you have no quality control. The whole point of a commit is that... you commit it. So now you need a separate repo or filter to remove the worthless changes from the ones that you actually intend to commit. Bad commits polluting git histories is already a big problem.

The biggest problems with git IMO are it scales poorly and it encourages commit pollution. Presumably jj isn't trying to tackle those problems, which is totally fine. But I am confused about which problems it is tackling. That's why I'm wondering whether it's just a frontend that the author finds more to their liking.

I legit ask myself how many folks avoid Github Desktop for some dogmatic reasoning equivalent to "having an UI makes it worse", when it does the core of common flows extremely easily and clear.

To be clear where it ties to this post: it makes git far more convenient with nearly 0 learning curve.

I’ve had a lot of success using https://graphite.dev/. Been pretty easy to pick up and slots right into our usual GitHub workflow. I end up using the vscode extension to manage it. Anyone have opinions how jujutsu compares?
Lately I've been hearing more people are getting into jj because of how much easier it is to keep track of the code generated with tools like cursor or claude code.
I tried it out on one of my personal repos and I need to give it more time. I do like the way it tracks work, it feels like it would help me to make more commits as I work, cause I’m really bad about that
Isn't it supposed to be called Ju-Jitsu, instead of Jujutsu?
Any tips for a magit fan who wants a positive second experience with jj?

I’m used to sorting through the changes I have made and making separate commits for each unrelated one (eg bug fix for several files, some WIP work, other parts actually done and ready to be “shipped”/reviewed)?

Do I need a better workflow?

Should I just be using the command line?

JJ needs a GUI.

I tried twice to switch for a project, both times came back to git. But then, I am still not fully grokking the "why bother", and suspect that if I had a UI it would be both less friction, and more understanding.

For a decade now I've been lamenting that git won the source control war. My complaints fall in two main categories:

1. The mental model is too complex: rebase or merge, detaching head, etc. A good UI can hide away some of this uglyness. It sounds like jj helps here.

2. Any source control in a terminal is just horrible, since you have no view of the state you're working with. I honestly never fully understood why developers have such religious elitism for the command line. Where would you draw the line on something having a complex enough state to need a UI?

The change to git that I'm hoping for is a GUI on top of a simpler wrapper like Jujutsu.

The main things that drives me crazy about jj is that all changes are always staged implicitly. This is what SVN did back in the day, and git was a huge improvement by staging changes explicitly.

I almost always have more changes in my repository that those which I want to include in the next commit. With git, I just add the changes I want. With jj (and svn), there’s not obvious way around it—you have to manually copy-paste changes outside of the repository before committing.

I think the workflow in JJ is a bit different in this case, you can try to have a base commit `jj new -m 'base'`, then create an anonymous commit on top `jj new`, then make some changes in the anonymous commit and when you are ready to send out a PR/MR you squash `jj squash` or split `jj split` and squash what you need in the base commit.
I'm torn on this - I don't know if there's a simple solution.

Having to stage things every time was always a real pain for me (coming from Mercurial).

Having it autocommit is what I need well over 90% of the time. But then there are always those pesky files that for various dumb reasons I'm not allowed to put in .gitignore.

I could disable autoadding files, but life will be worse that way.

Damned if you do, damned if you don't.

> I could disable autoadding files, but life will be worse that way.

``` [snapshot] auto-track = 'none()' ```

This is what I do, and I don't think it is worse. I prefer not having all my ignored files auto-tracked when I accidentally go back to a commit without them in the .gitignore

Some other solutions (which aren't simple at all): - Remove specific files from auto-track - Have a private commit with changes to the .gitignore and work on top of a merge commit - Like last one, have a private commit with the files you don't want to push (+ merge)

I have it setup where any commit with a description that starts with "IGNORE:" is private.

snippet from my config: ``` [git] private-commits = ''' description(regex:"(?x) # (?x) enables the x flag (verbose mode) allowing comments and ignores whitespace # see: https://docs.rs/regex/latest/regex/#grouping-and-flags

  # Ignores commits starting with:
  # (case-insensitive) PRIV: or PRIVATE:, or IGNORE:
  ^(?i:PRIV(ATE)?):
  | ^IGNORE:
 ")
''' ```
This is actually the main reason it exists in the first place, so given that fact, you should probably not use it?
> The main things that drives me crazy about jj is that all changes are always staged implicitly.

That's one way to look at it, but I would encourage you to think about it a bit differently.

JJ does not have a concept of "staging", it only has changes and commits. Yes, it automatically snapshots the workspace commit, but I wouldn't use the workspace commit as your staging area. If you want to do explicit staging use the parent commit (@-) as your staging area. You can move changes from the workspace commit (@) to the staging area (@-) explicitly, just like in Git. And you can "commit" (Git terminology) your staging area by starting a new staging area.

The difference here really is "only" that the workspace, the index, and committed changes are modeled with the same concept. And that is very powerful. Admittedly you have to make an informed decision on how to map your workflows onto the model, but that is what comes with the powerful flexibility that it gives you.

jj is unusable at least because there is tooling built around git repositories specifically
I've never tried jj, but recently I discovered lazygit which in my opinion comes pretty close to perfection.

Rebasing can be done instantly (reorder commits, fixups, squash), I can extract and reverse custom patches from previous commits, I can partially stage files, undo.

One think I like is that it explains what it does in terms of git commands. So it helps a little to have a good git mental model, and as such I guess it doesn't solve the same thing as jj.

(comment deleted)
That's a very clear up-to-date intro, great work.