54 comments

[ 2.7 ms ] story [ 57.2 ms ] thread
> 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.

It's also quickly followed by:

> Jujutsu is relatively new and doesn't cover 100% of the features of Git yet.

So it's more powerful except when it's not.

Other do a lot of nitpicking in workflows (with responses that are expected, like "but who cares" or "in git I could do the same"), but not answer this:

JJ is MORE powerful than git because has a BETTER SEMANTICS & ABSTRACTION.

That its. Is like when git emerge, it was more powerful than svn because was distributed.

I wanna make the point clear: Is NOT about the "amount of features or specific workflows" that with pain can be made on git and with effort could be retrofitted on jj eventually (if today are missed, like a equivalent of GitHub!).

The power is what abstraction made jj that is different to git: We work on "commits" all the time, and not need to manually sync the state. Everything derive from this.

And because is a better abstraction, it make more sense and is easier to understand.

The UX derive from this.

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?

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

re: `fd` I also find it a lot better to do something like `fd -e py -X ruff format` than `find -name '*.py' -exec ruff format {} +`.

Part of it is that `find` seems to come from before we standardized on `--foo --bar` having an equivalent in `-fb`, and the nagging about some flags being positional, but also just the general syntax of their `-exec`, which _requires_ the `{}` to be present, but it can only ever be in one position for the `+` variant.

My one nag about `fd` is that it has two optional positional arguments, so the way I use it I sometimes wind up with `fd -e $ext "" /path/to/search`. (`fd -e $ext --search-path /path/to/search` might be a clearer alternative I should habituate myself to.)

IME positional arguments are always less ergonomic than flags/options, _especially_ if there are more than one of them and they're not mandatory.

But they're still better than the `find` syntax.

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

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.

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.

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.
One way (there are other ways to do some things):

`jj log` if needed to see what revision ID you need to use

`jj new <starting revision> -m <message>` to create a new change with a given message with <starting revision> as the parent. (you can also use the `--insert-before <revset>` and/or `--insert-after <revset>` to set the parent & child revison(s) for the new revision).

`jj bookmark set <feature 1 name> --revision <revset>` to make a bookmark (a branch name) on the revison you just made.

Make changes on this branch as desired. `jj new` for each new change you want to have its own revision.

If you added more revisions to the branch, `jj bookmark move <feature 1 name> --to '@'` (you can also use the change ID instead of '@', '@' just means "the current change you're editing").

`jj edit <starting revset>` to go back to your starting revset.

`jj new -m <message>` to make a new revset on top of the starting revset (the starting revset now has two children: it has branched)

`jj bookmark set <feature 2 name> --revision <revset>` to name the second branch you just created.

Make changes as desired. `jj new` for each new change you want to have its own revision.

If you added more revisions to the branch, `jj bookmark move <feature 2 name> --to '@'`.

`jj new <feature 1 name> <feature 2 name> -m "merge feature 1 & feature 2"` to make a new revision with the feature 1 & feature 2 bookmark revisions as its parents (this is a merge).

Alternatively, you could use `jj rebase` to move any number of commits to anywhere in the commit graph you want.

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/

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?

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”.
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.
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.
thought i was gonna learn how to fight for a second lol
> 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.

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

OT, but are there agent-specific versioning systems? Or are people just retrofitting git/jj?
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.
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.
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.

> When was the last time you used a different VCS than your coworkers without having them switch to it too?

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

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.