jj – the CLI for Jujutsu

458 points392 comments11 hours ago
tiborsaas

Does JJ really prefer for me to think backwards? It wants me to start with the new and describe command, but with git I first make the changes and name the changeset at the end of the workflow.

I also often end up with in a dirty repo state with multiple changes belonging to separate features or abstractions. I usually just pick the changes I want to group into a commit and clean up the state.

Since it's git compatible, it feels like it must work to add files and keep files uncommitted, but just by reading this tutorial I'm unsure.

show comments
tom_alexander

I'm giving jj a try but one aspect of it I dislike is edits to files are automatically committed, so you need to defensively create empty new commits for your changes. As in, want to browse the repo from a commit 2 weeks ago? Well if you just checkout that commit and then edit a file, you've automatically changed that commit in your repo and rebased everything after it on top of your new changes. So instead you create a new branch off of the old commit and add an empty commit to that branch so any file changes don't end up rewriting the past 2 weeks of history. git is much nicer in that I can do whatever I want to the files and it won't change the repo until _I tell it to_.

show comments
dgb23

The last paragraph might be the most important one:

> There's one other reason you should be interested in giving jj a try: it has a git compatible backend, and so you can use jj on your own, without requiring anyone else you're working with to convert too. This means that there's no real downside to giving it a shot; if it's not for you, you're not giving up all of the history you wrote with it, and can go right back to git with no issues.

show comments
BeetleB

One of my favorite jj features is "jj absorb".

For each change you've made in the current revision, it finds the last commit where you made a change near there, and moves your changes to that commit.

Really handy when you forgot to make a change to some config file or .gitignore. You just "jj new", make the changes, and "jj absorb". No need to make a new commit or figure out where to rebase to.

Oh, and not having to deal with merge conflicts now is awesome. My repository still has merge conflicts from months ago. I'll probably go and delete those branches as I have no intention to resolve them.

show comments
TrysterosEmp

Why should you care about jj? Look, ethereal, balaeric Gothenburg indie from the 2010s may not be important in the grand scheme of things, but their strong hip hop influence was genuinely exciting at the time. When the great chill wave summer of 2009 crested, you definitely cared about jj’s otherworldly grooves and lil Wayne samples. Even if they never did reach the euphoric highs of Washed Out or even label mates The Tough Alliance.

show comments
steveklabnik

Hey folks!

So, I haven't updated the tutorial in a long time. My intent is to upstream it, but I've been very very busy at the startup I'm at, ersc.io, and haven't had the chance. I'm still using jj every day, and loving it.

Happy to answer any questions!

show comments
jiggunjer

I think the mental model is like C vs python. Git gives you a forensic trace back in time. jj gives you a story with chapters. Look under the hood you'll still see forensic map of state transitions, but this not what we want to navigate most of the time. Sometimes we need to rewrite an early chapter to make the latest chapter make more sense.

show comments
compiler-guy

One of the things that makes jj worth trying out is simply the fact that it is different than git, and having exposure to more than one way of doing things is a good thing.

Even if you don't adopt it (and I didn't), it's easy to think that "this way is the only way", and seeing how systems other than your own preferred one manage workflows and issues is very useful for perspective.

That doesn't mean you should try everything regardless (we all only have so much time), but part of being a good engineer is understanding the options and tradeoffs, even of well loved and totally functional workflows.

show comments
zingar

"It's more powerful and easier" is a great claim, but I need examples in this opening page to convince me of the pain I could save myself or the awesome things I'm living without.

show comments
acoustics

jj has made me much more comfortable using non-linear DAGs in my trunk-based development workflow. Several changes with the same parent, changes with several different parents, etc.

I used to have a habit of imposing an unnecessary ordering structure on my work product. My stack of changes would look like A -> B -> C -> D, even if the order of B and C was logically interchangeable.

jj makes DAGs easier to work with because of how it handles conflicts and merges. Now I feel empowered to be more expressive and accurate about what a change actually depends on. In turn, this makes review and submission more efficient.

show comments
pheggs

I was already pretty happy with svn to be honest, I dont see myself switching away from the industry standard today for no substantial reason. in my opinion git was only able to change the standard thanks to github and a popular author (i love git and its branching, but I dont think it would have been enough if it was just for that). I personally believe its going to be very difficult for jj to replicate that.

show comments
kevin_nisbet

I really wanted to like JJ, it was handy for a few months when I used it. But for me in the end I reverted back to regular git.

What triggered me to go back was I never got a really clean mental model for how to keep ontop of Github PRs, bring in changes from origin/main, and ended up really badly mangling a feature branch that multiple contributors were working on when we did want to pull it in. I'll probably try it again at some point, but working in a team through Github PRs that was my main barrier to entry.

show comments
jrockway

jj is great and while it was an adjustment at first, I've never looked back. I feel like when you're working with other people, things never get reviewed and merged as quickly as you'd like. With jj, it's pretty low-cost to have a bunch of PRs open at once, and you can do something like `jj new <pr1> <pr2> <pr3>` to build stuff that requires all 3. This lets me do things like... not do a big refactoring in the same PR as adding a feature. I can have them both self-contained, but still start on the next step before they're all merged. It's easy to add changes on top, switching between the individual PRs as comments come up, etc.

I always liked doing things like this. At Google where we used a custom fork of Perforce, I told myself "NEVER DO STACKED CLs HAVE YOU NOT LEARNED YOUR LESSON YET?" If one CL depended on another... don't do it. With git... I told myself the same thing, as I sat in endless interactive rebases and merge conflict commits ("git rebase abort" might have been my most-used command). With jj, it's not a problem. There are merge conflicts. You can resolve them with the peace of mind as a separate commit to track your resolution. `jj new -d 'resolve merge conflict` -A @` to add a new commit after the conflicted one. Hack on your resolution until you're happy. jj squash --into @-. Merge conflict resolved.

It is truly a beautiful model. Really a big mental health saver. It just makes it so easy to work with other people.

show comments
Aperocky

With agents, my go to is now have multiple of the same repository and each agents must work on a separate one.

Preventing dirty workspace by solving the co-work problem to start with. merges are much more trivial than trying to make agents remember which branch or which folder it is supposed to work on. Disk space is cheaper than mental anguish and token usage.

show comments
justinmayer

Many folks aren’t aware that there is also an open-source, cross-platform desktop GUI application for Jujutsu called GG: https://github.com/gulbanana/gg

I mention it because while the jj command line interface is excellent, there are certain tasks that I find easier to perform with a graphical user interface. For example, I often want to quickly tap on various revisions and see their diffs. GG makes that kind of repository browsing — and certain squash operations — much more efficient for me.

If you’re interested in more information about GG, my co-host and I talked about it in a recent episode of the Abstractions podcast at about the 8:17 mark: https://shows.arrowloop.com/@abstractions/episodes/052-they-...

show comments
dmitshur

What is the current story for serving jj repositories over HTTPS? Git has https://git-scm.com/book/ms/v2/Git-on-the-Server-The-Protoco... . Does jj have something better, equivalent, or nothing (at this time) at all?

show comments
rs545837

jj is genuinely great and I think it deserves way more adoption than it has right now. The mental model is so much cleaner than git, undo actually works the way you'd expect it to, and working with stacked changes feels natural instead of that constant low-grade anxiety of actually breaking something. It's probably the best frontend for version control that exists today.

For the last few months though I've been thinking a lot about what you said at the end there. What if version control actually understood the code it was tracking, not as lines of text but as the actual structures we write and think in, functions, classes, methods, the real building blocks? A rename happening on one branch and an unrelated function addition on another aren't a real conflict in any meaningful sense, they only look like one because every tool we have today treats source code as flat text files.

For enhancing this kind of structural intelligence I started working on https://github.com/ataraxy-labs/sem, which uses tree-sitter to parse code into semantic entities and operates at that level instead of lines. When you start thinking of code not as text there's another dimension where things can go, even a lot of logic at the comiler level with call graphs becomes useful.

shuyang

Has anyone found a good code review workflow with `jj`? My problem is that GitHub doesn't remember the content of the last reviewed SHA, so every time I push a new change from jj, reviewers lose the delta from their last reviewed commit.

To work around this I stopped moving revs (squash/rebase) after review starts, which creates awkward local graphs if I have to merge from main for merge conflicts. Graphite works but it's $$$, and phabricator/reviewable/gerritt all have significant onboarding hurdles.

show comments
misnome

The problems with jj that led me to abandon are:

- All of everything good about it breaks down the instant you want to share work with the outside world. It's git on the backend! Except there isn't any concept of a remote jj so you have to go through the painful steps of manually naming commits, pushing, pulling, then manually advancing the current working point to match. And in doing so, you lose almost everything that gives it value in the first place - the elegant multi branch handling, anonymous commits, the evolog. Even if you want to work on the same project on two machines your only choice for this is without breaking everything via git is to rsync the folder. Yes, you can write alias to do all this like git. I might as well use git if I can't use the nice features.

- All files automatically committed is great until you accidentally put a secret in an unignored file in the repository folder. And then there is no way to ensure that it's purged (unlike in git) - the community response as far as I can tell is "Don't do this, never put a file that isn't in gitignore".

- And adding to .gitignore fails if you ever want to wind back in history - if you go back before a file was added to .gitignore, then whoops now it isn't ignored, is all part of your immutable history, and disappears if you ever switch off of that new commit state.

octocop

Nobody is asking for a git replacement? I keep seeing these posts and I don't know who wants them.

show comments
waynecochran

Anything new or special in jj that allows me to work with large binary files simply? To me, this is still unsolved in terms of providing an elegant solution (e.g. things like Git Large File Storage (Git LFS) are awkward).

show comments
tracker1

Seems interesting, but tbf, I only really use a small subset of git commands as it is... I've tended to practice a few workflows that just reduce the overhead and risk for conflicts.

qezz

For those, who want to/need to keep some files uncommitted, the workaround I found is to put gitignore into some nested directory:

  mkdir junk
  echo '*' > junk/.gitignore
jj won't track those files under ./junk/

Also might be relevant for claude, since it wants to put its settings into the repo itself as `.claude/`:

  mkdir junk/.claude
  bwrap ... --bind "$(pwd)/junk/.claude" "$(pwd)/.claude" ...
For some more common files, I use global gitignore file as

  # ~/.gitconfig
  [core]
    excludesFile = ~/gitconf/gitignore_global

  # ~/gitconf/gitignore_global
  .envrc
  .direnv/*
show comments
swoorup

I love jj, but mostly I use jjui.

I would like more uniformity in the way jjui handles commands when you are viewing changes vs when you are viewing files within a single change.

Often I just make my changes and leave it there without `new`, as I am not sure which file should go in a single commit. I just leave it there and I interactively commit later.

For me to use `new` more, I would like the ability to also simply be able to get a tree view of all changes, which contains file which contains file changes, so I could can have marks that span multiple changes and then either `split` or `commit` or `squash` the change, idk if there is a good word for it. Right now I can only mark within a single change, and I lose it once I navigate up.

show comments
rattray

Has anyone tried both jj and gitbutler extensively yet? Both seem to have some interesting new ideas on top of git.

show comments
theappsecguy

I'm still struggling most with the fact that my day-to-day work involves a git first platform like GitHub.

Although jj as a vcs system, it does feel better, working with git through it still feels like a chore, but to be fair I only gave it a day before going back to git.

Does anyone have any good resources on how to augment a git flow through the lens of a git hosting platform to work smoothly and still reap the benefits of jj?

show comments
tobinfricke

Here are some notes on Jujutsu from Evan Martin that I found interesting/useful:

https://neugierig.org/software/blog/2025/08/jj-bookmarks.htm...

ferfumarma

Can jj iterate through a list of repositories and clone them all to local storage?

It isn't very hard to make a bash script to do it, but I have about six github repos, all of which frequently need to be put on a new machine. that kind of functionality would be cool to have out of the box.

show comments
alunchbox

So glad to see this on HN, here to support it. JJ is amazing, the hardest hurdle was not the tool but the toolchain and ecosystem when I started ~ 2 years ago. It's grown rapidly and is incredible to see the community grow!

rob74

Still not finished unfortunately :( Guess Steve is currently busy writing the next big thing in programming languages (https://steveklabnik.com/writing/thirteen-years-of-rust-and-...) ?

show comments
enbugger

1) Are there any benefits in replacing a personal private project git repo with jj? I usually just commit straight to master in order to just not to lose the changes and be able to roll back. 2) Are there any pros in doing so in a project with many large binary files (3d models, images)?

show comments
mi_lk

Please update the "Stacked PRs" workflow article Steve...

show comments
eranation

For those who switched, what is the main selling point that made you stay with Jujutsu?

show comments
PUSH_AX

If it ain't broke...

show comments
0xnadr

Interesting to see more Rust CLI tools gaining traction. The undo-everything model is compelling. I've lost work to bad git rebases more times than I'd like to admit.

QuiDortDine

> $ cargo install jj-cli@0.23.0 --locked

I won't install Rust just to test your software. Make a debian package like everyone else.

show comments
jancsika

I was going to write a big long comment, but honestly it boils down to this:

Whatever git's practical benefits over SVN and CVS back in the day (and I can go into the weeds as a user if someone wants that), git was the DVCS that took over from the centralized VCS's of that era.

There is nothing in jj, pijul, or Bram Cohen's thing that is anywhere near as dramatic a quality of life improvement as going from VCS to any DVCS. And dramatic improvement is what is needed to unseat git as the standard DVCS.

I mean, if you're not doing something so important[1] that it adds a letter to the acronym, it's probably not the next new thing in version control.

1: I originally wrote the word "novel" here. But it has to be big-- something like guaranteeing supply chain integrity. (No clue if a DVCS can even do that, but that's the level of capability that's needed for people to even consider switching from git to something else.)

aftbit

Nope, git is good enough, and is the global standard. We don't need more new VCS.

show comments
wolttam

What happens when jj introduces this native repository format - break compatibility with all the popular git hosts?

If jj is so great now and works with git as a backend, it’s tough to imagine why it’s worth pursuing a native and presumably incompatible backend.

show comments
systems

its almost impossible for me to tell if this better or worst than git i read few things about jj, and my conclusion

   1. its different
   2. very few user would really care about this difference 
i think git is good (not good enough, good just good, or really good) and unlike shells, i cant think of a reason to have mass migration to it

people use zsh because apple choose it, and pwsh because microsoft settled on it, on linux i am sure we can do better than bash, but it good enough and nothing justified replacing it (that being said, all 3 OSes should have settled non nushell)

in summary, if we couldnt replace bash on linux, i dont think anyone can replace git, git as an scm tool if far better than bash as a shell

show comments
bikelang

Reading threads like this and the GitHub stacked PRs just makes me feel like an alien. Am I the only one that thinks that commits are a pointless unit of change?

To me - the PR is the product of output I care about. The discussion in the review is infinitely more important than a description of a single change in a whole series of changes. At no point are we going to ship a partial piece of my work - we’re going to ship the result of the PR once accepted.

I just squash merge everything now. When I do git archeology - I get a nice link to the PR and I can see the entire set of changes it introduced with the full context. A commit - at best - lets me undo some change while I’m actively developing. But even then it’s often easier to just change the code back and commit that.

show comments
andrepd

Is there a concise introduction / overview of jj? I've read 8 pages of this link and the author is still in preambles and considerations... Not my favourite style of article!

show comments
randyrand

jj sounds awesome. I think I’ll give it a shot.

But I found this article a bit long winded and ended up asking an LLM about it instead.

carverauto

am a big fan, just started using it a few days ago

palata

I tried jj for a few months. It was fun to learn a new thing, but I haven't had a single case of "wow, this would have been a pain with git". Then I went back to git (it's been 6 months now) and I haven't had a single case of "this is so painful, I wish something better existed".

So it felt like the XKCD on "standards": I now have one versioning system, if I learn jj I will have two. What for?

Don't get me wrong: it's nice that jj exists and some people seem to love it. But I don't see a need for myself. Just like people seem to love Meson, but the consequence for me is that instead of dealing with CMake and Autotools, I now have to deal with CMake, Autotools and Meson.

EDIT: no need to downvote me: I tried jj and it is nice. I am just saying that from my point of view, it is not worth switching for me. I am not saying that you should not switch, though you probably should not try to force me to switch, that's all.

show comments
nailer

JJ might be good (this article couldn't convey why in the "What is jj and why should I care?" page) but it's not 10x better than git, so it will likely die. Sorry, nothing personal, Mercurial/hg was a little bit better than git and died too. Network effects.

What has a change is ast-based version control.

You adding a feature to a function that uses a struct I renamed shouldn't be a conflict. Those actions don't confliuct with each other, unless you treat code as text - rather than a representation of the logic.

Ending merge conflicts might make a new version control 10x better than git, and therefore actually replace it.

show comments
jtrueb

Call me crazy, but jj is more confusing than git.

zhaoyongjie

To be honest, JJ is dick in Chinese, literally.

show comments
sam_goody

I use the CLI often enough, but still most of my time is in a GUI. It just makes the diffs easier, the flow simpler, etc.

As such, I wanted to break into jj via the GUI, and only adopt the command line after I could visualize the concepts and differences in my head.

Alas, the GUI I tried - a VSCode plugin - did more to confuse me than to help, and it made it very easy to catastrophically rewrite the history by accident. I tried another UI and it kept failing and leaving me with cleanup work. I couldn't find a third UI that looked promising.

So, I gave up. One less jj user on the planet - no biggie. But I really wonder if it would be worth the effort for some of the jj pushers to try to get a proper UI in place - I bet I am not the only one that likes to learn visually.

ai_slop_hater

Unfortunately OpenAI's models really suck at JJ, while, on the other hand, Opus 4.6 is much better at it, probably due to a later training cut off.

kristo

I followed steve's excellent tutorial about two months ago, and haven't looked back. I have never felt so competent at git (vcs rather) as I do now. jj is so much simpler and easier for me to reason about.

scotty79

Does jj have partial clones of remote repo?

show comments
dhruv3006

this looks pretty interesting.

tucnak

16 year-old me would have been very impressed by this!

show comments
SV_BubbleTime

>You can request to not use the pager by using jj st --no-pager, or if you hate the pager and want to turn it off, you can configure that with

    $ jj config set --user ui.paginate never
In one feature they can’t help themselves from calling it two different things already.

Why do this? Why can’t the very clearly smart people making things step 1/2 step outside themselves and think about it like they are the users they want?

Earlier they talk about the native format and how it isn’t ready… so that to start you need

    jj git init
… but… if they’re planning a native format that makes no sense as a command. It would be ‘jj native init’ later?

Early planning keys/plans imo but those rarely change so as to not accept your early adopters.

These seem like small things but to me it’s a warning.

show comments
fallat

Now that Steve is part of a GitHub competitor to push jj, I see all these posts as just sales pitches.

show comments
newsoftheday

OK I read it, I'm not interested, git does exactly what I want.

show comments
jansan

We all need to give ourselves a push and finally make the next step in version control. Github, Google, Microsoft, Meta (did I forget anyone relevant? Probably) should just join forces and finally make it happen, which should not be a problem with a new system that is backend compatible to Git. Sure, Github may lose some appeal to their brand name, but hey, this is actually for making the world a better place.

show comments
ux266478

Clicked on this hoping it would be the irc client, very disappointed!

For those in the know, how does jujutsu stack up to something like Darcs?

show comments
7e

Is it better for AIs? That’s the only reason I would care.

show comments
Openpic

動画などでわかりやすいものが見たい

butlike

FWIW, it's a pretty decent fried fish chain in Chicago as well.

show comments
demorro

This doesn't seem different enough to be worth the transitional cost, even if you don't need to actually move away from a git backend.

show comments