I can understand if you need to run a CI or unit tests locally. Is that it?
I am not attacking JJ, I genuinely can't understand its value in my current workflow.
I find jj overall most useful for separating the concept of a machine-level commit history that saves every change from a human-readable commit history . jj has really nice tools for cleaning up your commits for review while still retaining all the mechanical changes in case you need to get more granular. (Of course, there are many other tools to do this, like magit – I just find jj to work best with my brain.)
Workspaces/worktrees are best when you have long-running tasks where the state of the disk is important. Local "CI" is a good example – kick off a long test run on one workspace while starting a new task in another. Another example these days is stuff with Agentic LLMs, e.g. I might create one workspace and ask Claude Code to do a deep investigation of why our AWS costs went up.
1. Stacked PRs. I like to be kind to my reviewers by asking them to review small, logically-contained pull requests. This means I often stack up chains of PRs, where C depends on B depends on A, and A is being reviewed. If I receive feedback on A, jj enables me to incorporate that change within A, and flows those changes down into my dependent branches. I can then merge and close out A, whole continuing to work on B and C. Achieving this in raw git is labour intensive and error prone.
2. Easily fix up commits. I like to work with atomic commits, and sometimes I realize that I've made a typo in a comment, or a small error, or missed a test case. Jj makes it really trivial to timewalk back to the commit in question, fix it and resume where I left off.
3. Decompose a big PR into multiple PRs. This is the flip side of point 1: I can take my own big PR and rearrange and partition the commits into A, B and C so that they can easily be reviewed.
In general, jj seems to encourage and reward you for being disciplined with your commits by enabling you to be more flexible in how you stage, review and ship your code.
On the flip side, if you're the kind of person who is used to typing `git commit --all --message "xxx"` you might not get as much value from jj until that changes.
Maybe from the kind of work I do? either CI is failing because of something really simple, or something really complicated that means getting a product setup and producing debug messages. If it's a critical fix on branch A, then I'm not working on branch B. I'm testing branch A locally while CI does its thing
> I don't see how creating a worktree in a new folder and opening a new editor is more convenient than creating a branch at a certain commit.
Worktrees are about being able to work on multiple branches at the same time, fundamentally. When you want to be doing something on one branch and something else on another branch simultaneously.
That does mean it's, IMHO, a fairly niche feature.
https://github.com/tdhopper/wt
with some custom shell aliases to make it easier.
There is a lot more to jj that makes it nicer than git, but it's mostly a bunch of small things that jj does nicer, that cumulatively add up to a significantly nicer experience.
Your far better off just having a clone of your primary repo, and have your primary repo as a local remote. Both can have a remote for GitHub and a separate remote for each other.
I personally find this annoying. I usually like to keep one pristine and always current working copy of main (and develop if applicable) around for search and other analysis tasks[1]. Worktrees would be ideal and efficient but due to the mentioned restriction I have to either waste space for a separate clone or do some ugly workarounds to keep the worktree on the branch while not keeping it on the branch.
jujutsu workspace are much nicer in that regard.
[1] I know there are tons of ways search and analyze in git but over the years I found a pristine working copy to be the most versatile solution.
Also, if you end up relying on it for space reasons, worth knowing that cloning from a file:// url switches the hardlink mechanism off so you end up with a full duplicate again.
git worktree add ..\repo -b wt-main --track origin/main
And to be honest, after being disciplined to always do that, I very rarely get error message saying that the branch I want to check out is already checked out in other worktree. Before that, I regularly had a situation when I checked out main branch on second worktree to see the current state of the repo (because my main worktree had a work in progress stuff) and after some time when I finished work on main branch, I tried to check out main branch on my main worktree and got the error. Because I totally forgot that I checked it out some time ago in the other worktree.
You can detach the worktree from the repo, and checkout multiple branches at the same time to different locations. Not sure if this also allows checking out the same branch to multiple locations at the same time. You can also have a swallow clone, so you don't have to waste space for the full repos history. So at the end you still have to waste space for each worktree, but this isn't something jujutsu can avoid either, or can it?
Tools should adapt to us and not the other way around, but if you are stuck with git, there's a slightly different workflow that supports your use case: detached head. Whenever I check out branches that I don't intend on committing to directly, I checkout e.g. origin/main. This can be checked out in many worktrees. I actually find it more ergonomic and did this before using worktrees: there are no extra steps in keeping a local main pointer up to date.
The complication comes from trying to stay current. With a regular worktree I could just pull, but now I have to remember the branch, fetch all and reset hard to the remembered branch.
author me tions that git cli require multiple steps when there are unstaged changes.
I don't know if git has one liner cli command for it as i myself use gitextn to create worktrees
That's not really true in this case, as the worktree feature from jujutsu is not implemented on top of git worktrees.
(I personally think jj shouldn’t support collocated repositories, but happy to learn what others see in them…)
1) Various read-only editor features, like diff gutters, work as they usually do. Our editor support still just isn't there yet, I'm afraid.
2) Various automation that tends to rely on things like running `git` -- again, often read-only -- still work. That means you don't have to go and do a bunch of bullshit or write a patch your coworker has to review in order to make your ./run-all-tests.sh scripts work locally, or whatever.
3) Sometimes you can do some kind of nice things like run `git fetch $SOME_URL` and then `git checkout FETCH_HEAD` and it works and jj handles it fine. But I find this rare; I sometimes use this to checkout GitHub PRs locally though. This could be replaced 99% for me by having a `jj github` command or something.
The last one is very marginal, admittedly. Claude I haven't had a problem with; it tends to use jj quite easily with a little instruction.
wasn't git compatibility it's main pro?
I think the easiest way to conceptualize it is to think of Git and jj as being broken down into three broad "layers": data storage, algorithms, user interface. Jujutsu uses the same data storage format as Git -- but each of them have their own algorithms and user interface built atop that storage.
Google uses it with Piper, their centralized VCS.
Being compatible and being purely a frontend aren’t the same thing.
> but for some reason I cannot proceed on it while eg the CI is running, but I also don’t want to leave the commit and close my code editor etc. It would be simple to just stash everything and later pop the stash, but it still feels disruptive.
I have been using jj as my git client for 2 years now (wow), and I have never considered this to be disruptive. I just immediately switch to a new commit where I want to go, rather than making a new workspace to work in. Maybe it's a difference in the editor that I use (GNU Emacs) that makes this more natural?
or things like just keeping the terminal history consistent with a change if you look at things like compile command outputs etc.
In the worktree there is no .git directory, just a .git file which has a single line: "gitdir: <path to gitdir>".
If your sandbox doesn't have access to the gitdir, you're golden.
You could always use an overlayFS with the main (non-worktree) repo as the lowerdir (and then remove the remotes in the overlayFS), but that relies on you not trying to keep working on the git repo at the same time.
I have a script that takes Github issues and spins them out into their own worktrees with corresponding stack.
I can then run individual instances of Claude Code in each and easily flip between them.
Heck with the ai, I even have it spin up a dev and test db for that worktree in a docker container. Each has their own so they don’t conflict on that front either. And I won’t lie, I didn’t write those scripts. The models did it all and can make adjustments when I find different work patterns that I like.
This is all to the point of me wondering why I never did this for myself in the past. With the number of times I’m doing multiple parts of a codebase and the annoyance of committing, stashing, checking out different branch and not being able to go more quickly between when blockers are resolved.
I'm following this Jujutsu project, I'm genuinely curious to see what it can bring to the SVC scene.
How so? I worked with Git all my professional life and I can't deny its efficacy. However, I would not call it un-improvable given all types of corner case issues I have had with it over the years.
Anyway, sorry for triggering you with the first bold statement! I actually wanted to emphasize the curiosity over jj.
Do you imagine someone to be triggered any time they correct you? Like, a sort of trigger you respond with whether accurate or not?
Thanks for the comment.
People does not have to be triggered to ask follow up questions. Its ok to even ask a challenging question as a response of a statement, without being an indication of their mood.
Git isn't bulky in terms of RAM usage but it is bulky in terms of mental capacity that has to be allocated to it.
It's good but I wouldn't call it incredible.
I hope some day we do get a better SCM.
That said, the first thing I do now in a repo is jj init --colocate. The fact alone that there is an operation log in jj, so you can easily revert your last command, or go back to any point you want, is mind blowing coming from git and having experienced frantically digging through the reflog.
But that aside, the way to work with branches ahem bookmarks, commits, conflicts, just makes so much sense in a world where simultaneous feature branches are a thing.
Example: jj snapshots the working copy on any jj command but not any git command
It’s a leaky abstraction
I speak specifically of the UI. Obviously the underlying system works. Yet it's totally within reason that the UI has wasted trillions of money and many person years in lost productivity.
Napkin math. It's easy to waste 30 minutes figuring out what the heck is going on after a command didn't work, or explaining what a detached head is to a newbie, or any number of completely avoidable issues were the UI better.
Consider the 26.9 million developers in North America[1]. How does one estimate the average salary across NA? Some in SV make 3x that. Elsewhere, it's conceivable that people make considerably less. Let's just say 100k. That's 100,000÷52÷40=48/hr or 24 per half hour. Anyone with git, I think it's safe to say, has had at least one stupid issue that took 30 minutes because of the UI. That's 26.9×24=645,600,000 monies.
In my experience and what I've seen of anyone who'a used git, 30 minutes is a gross underestimate. And people use git outside of NA. It's easily trillions in waste.
https://en.wikipedia.org/wiki/Software_engineering_demograph...
> I usually use it when I’ve got one task I’m working on, but for some reason I cannot proceed on it while eg the CI is running, but I also don’t want to leave the commit and close my code editor etc. It would be simple to just stash everything and later pop the stash, but it still feels disruptive.
Sorry, but I don't get the improvement.
There's also like, some features of git aren't features in jj, but that doesn't mean you can't do that stuff with jj, it just works differently. The index or stashes, for example. In a literal sense, that's not parity, but in a logical sense, it is.
“de facto” please.