[HN Gopher] Jujutsu worktrees are convenient (2024)
___________________________________________________________________
Jujutsu worktrees are convenient (2024)
Author : nvader
Score : 115 points
Date : 2025-12-03 23:26 UTC (4 days ago)
(HTM) web link (shaddy.dev)
(TXT) w3m dump (shaddy.dev)
| akabalanza wrote:
| I consider git the best software ever written. I used to work
| with some other SVCs, and I cannot thinking on leaving git now.
| Somehow, I feel it like a limitation for my mind.
|
| I'm following this Jujutsu project, I'm genuinely curious to see
| what it can bring to the SVC scene.
| DarkNova6 wrote:
| > I consider git the best software ever written.
|
| 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.
| akabalanza wrote:
| Maybe "best ever" is too bold, but both proven efficacy and
| mainstream popularity for over 15 years, without being a
| bulky thing everybody just accept (like vscode), I don't see
| many other software examples.
|
| Anyway, sorry for triggering you with the first bold
| statement! I actually wanted to emphasize the curiosity over
| jj.
| gilrain wrote:
| > Anyway, sorry for triggering you with the first bold
| statement!
|
| Do you imagine someone to be triggered any time they
| correct you? Like, a sort of trigger you respond with
| whether accurate or not?
| notrealyme123 wrote:
| Found myself resonating with this a lot. Food for
| thought.
|
| Thanks for the comment.
| oblio wrote:
| > without being a bulky thing everybody just accept
|
| 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.
| DarkNova6 wrote:
| Not triggered at all, I was just asking a curious question
| :-)
| fastasucan wrote:
| >Anyway, sorry for triggering you with the first bold
| statement! I actually wanted to emphasize the curiosity
| over jj.
|
| 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.
| skrebbel wrote:
| No software that has 3 names for the same thing (git stash
| --cached vs --keep-index wtf!?) deserves to be described as
| "the best ever written"
| 1718627440 wrote:
| That is not the same thing, --cached means use only the
| version cached in the index, --index means also use the
| index. What is the third thing you have in mind?
| Hammershaft wrote:
| I think Git is incredible version control hiding behind a
| terrible interface.
| oblio wrote:
| An incredible version control system would probably be able
| to version empty folders, too. And other limitations I'm
| forgetting right now.
|
| It's good but I wouldn't call it incredible.
|
| I hope some day we do get a better SCM.
| OvbiousError wrote:
| Having worked with cvs and svn, git has been an absolute blast.
|
| 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.
| gcr wrote:
| Keep in mind that you still need to occasionally run jj
| commands, even in collocated repositories
|
| Example: jj snapshots the working copy on any jj command but
| not any git command
|
| It's a leaky abstraction
| steveklabnik wrote:
| Colocation is the default these days, by the way.
| regularfry wrote:
| My journey was CVS->SVN->darcs->Hg->git. I can thoroughly
| recommend at least playing around with the others to see what
| you're missing. Darcs in particular I remember as having a much
| nicer model than either git or mercurial, but it had a horrible
| corner case behaviour. Pijul is supposed to fix that, but I
| haven't tried it yet.
| spit2wind wrote:
| Have you used fossil? If so, what are your thoughts?
| aj_hackman wrote:
| What motivated you to move from Mercurial? I'm still using HG
| for personal projects because it's so easy to self-host on a
| Raspberry Pi. Just `hg serve -p 8001` or whatever and I'm
| able to use TortoiseHG from any machine to easily stage
| commits.
| steveklabnik wrote:
| A lot of us who like jj felt similarly about git. Two pieces of
| software can both be good :)
| spit2wind wrote:
| That's interesting. I consider git the worst software ever
| written!
|
| 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.9x24=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...
| IshKebab wrote:
| Git is a clever idea with a terrible implementation. Definitely
| not the best software ever written.
| spider-mario wrote:
| > I've been using Jujutsu(jj for short) as my defactor git cli
| frontend for a while now.
|
| "de facto" please.
| turboponyy wrote:
| Even better is "" since it's not really adding anything
| Zambyte wrote:
| I'm glad they found a workflow that works for them, but
|
| > 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?
| rafaelmn wrote:
| Build cache, packages and a few of other things get messed up
| when switching branches - if you need to do a "quick bug-fix
| and get back into the main thing" worktrees are really nice.
| Zambyte wrote:
| I see. The projects I have been working on in the last few
| years don't take very long to compile, so build cache has not
| been a very big factor for me. I could see it being more
| important for projects that take a long time to build though.
| arccy wrote:
| if you don't do much in terms of accumulating open
| buffer/window sets, editor open at the specific line you were
| working on etc, then you'll feel it less.
|
| or things like just keeping the terminal history consistent
| with a change if you look at things like compile command
| outputs etc.
| rafaelmn wrote:
| So how is this different from git worktrees exactly ?
| rk06 wrote:
| there is no difference as jj is only a frontend to git.
|
| 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
| dubi_steinkek wrote:
| > there is no difference as jj is only a frontend to git.
|
| That's not really true in this case, as the worktree feature
| from jujutsu is not implemented on top of git worktrees.
| Macha wrote:
| This is kind of unfortunate in this case as it breaks some
| tooling since the extra trees are not collocated with git,
| like editor inline history/blame or agents that know to
| look in git history to fix their mistakes
| gcr wrote:
| isn't it strictly better to use your editor's JJ support
| and ask Claude to use jj?
|
| (I personally think jj shouldn't support collocated
| repositories, but happy to learn what others see in
| them...)
| Macha wrote:
| jj support in editors is way behind git support.
| aseipp wrote:
| I think the biggest benefits of colocation are, in rough
| approximation of the order I encounter 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.
| steveklabnik wrote:
| The fix for having worktrees be colocated is in progress.
| Not sure when it'll be done but it's coming.
| rk06 wrote:
| wtf? it can diverge from git?
|
| wasn't git compatibility it's main pro?
| SatvikBeri wrote:
| You can still use git worktrees in a colocated
| repository. jj workspaces are a different, but similar
| capability that provide some extra features, at the cost
| of some others.
| steveklabnik wrote:
| Yes, jj is its own VCS with pluggable backends.
|
| Google uses it with Piper, their centralized VCS.
|
| Being compatible and being purely a frontend aren't the
| same thing.
| aseipp wrote:
| To be technical, it's more that it can read and write the
| on-disk Git format directly, like many other tools can.
|
| 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.
| gcr wrote:
| jj may use git as (one of) its backing stores, and its
| collocation offers some compatibility at the cost of
| important tradeoffs, but it isn't intended to be a git
| frontend.
| weinzierl wrote:
| In git you can have only one worktree per branch. For example,
| if you have a worktree on _main_ you cannot have another one on
| _main_.
|
| 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.
| htgb wrote:
| That sounds like a nice improvement, just like many other
| aspects of jj!
|
| 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.
| weinzierl wrote:
| The detached head is what I meant with keeping it on the
| branch while not keeping it on the branch.
|
| 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.
| rafaelmn wrote:
| OK nice to know. Don't find this limiting for my flow but
| will keep in mind if I decide to give JJ a try.
| PurpleRamen wrote:
| > In git you can have only one worktree per branch. For
| example, if you have a worktree on main you cannot have
| another one on main.
|
| 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?
| regularfry wrote:
| You probably know this, but for others that don't: local git
| clones will share storage space with hardlinks for the
| objects in .git. The wasted space wouldn't be a doubling, it
| would be the work tree twice plus the (small) non-hardlinked
| bits under .git. No idea how LFS interacts with this, but it
| can be worth knowing about this mechanism.
|
| 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.
| mpawelski wrote:
| This restriction of git worktrees is annoying but I just
| learned one simple rule to follow: Never check out the main
| development branch (main/master/develop/etc) in other
| worktrees (non "main worktree", using git-worktree
| nomenclature)). Use other name with "wt-" prefix for it. Like
| in:
|
| 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.
| et1337 wrote:
| This is a perfect microcosm example of why I like Jujutsu.
| Useful git tips and tricks like this are just the default
| behavior in jj.
| 1718627440 wrote:
| > In git you can have only one worktree per branch.
|
| Well, that is true, but a branch is nothing more than an
| automoving label, so I don't see how that is limiting at all.
| You can have as many branches as you like and you can also
| just checkout the commit.
| mentalgear wrote:
| Re Worktree/Spaces alternative: Why not just open up a new editor
| window ?
|
| > 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.
| arccy wrote:
| your editor works on files on disk. worktrees / workspaces are
| what manage those files on disk in relation to your git repo.
| michaelbuckbee wrote:
| The usage of worktrees is seeing a big comeback in the era of AI
| assisted coding.
|
| 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.
| jackschultz wrote:
| Same. Never used worktrees before, but mapping a worktrees to
| tickets I'm assigned to for Claude to work on is really great.
|
| 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.
| wolfwyrd wrote:
| Phil Haack has a neat script called tree-me[0] that takes a lot
| of the pain out of this in vanilla Git
|
| [0] https://haacked.com/archive/2025/11/21/tree-me/
| jandudulski wrote:
| `jj workspace add ../project-name-2` vs `git worktree add
| ../project-name-2`
|
| Sorry, but I don't get the improvement.
| bialpio wrote:
| The author doesn't mention this as an improvement to git, just
| showcases that an equivalent feature exists in jj. This is
| useful to me, a jj noob that was not aware it's possible.
| baq wrote:
| there isn't any. it's just possible in jj, which does not have
| feature parity with git and probably doesn't aim to have it
| anytime soon, if ever (not a contributor, so please don't quote
| me)
| steveklabnik wrote:
| It depends on what you mean by "feature parity." jj has some
| features git doesn't, and git has some features jj doesn't.
| That's likely to be the case into the future, for sure.
|
| 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.
| amluto wrote:
| I want a variant of this where I make a worktree that has no
| ability to push anywhere including its parent. Instead the parent
| worktree pulls from it automatically. That way I can run some
| sandboxed workflow that might arbitrarily corrupt the work tree,
| possibly overwriting everything in it and symlinked from it,
| without losing data.
| Normal_gaussian wrote:
| The easy way to do this is to create a worktree and then just
| run it in some form of sandbox - e.g. a Docker container.
|
| 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.
| gcr wrote:
| What if the sandbox needs access to the history? Imagine
| asking for help bisecting something, for example
| Normal_gaussian wrote:
| Then you'll probably want a clone; which will cost in more
| space. Just remember to remove the remotes.
|
| 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.
| amluto wrote:
| Or if I want the sandbox to be able to create commits,
| which is extremely useful.
| gcr wrote:
| Don't you just want a clone in that case?
| amluto wrote:
| By itself, that doesn't help if the thing in the sandbox does
| useful work for two hours and then does rm -rf /
| tonyhart7 wrote:
| I like jujutsu kaisen too
| janquo wrote:
| It's not really usable to me as the workspace folder doesn't have
| .git in it, even though original repo is collocated and hence the
| git tools don't work there. I am forced to use git work trees
| with separate collocated JJ repo each.
| gcr wrote:
| Why are you using git tools within collocated jj repositories?
| I never understood that use case tbh
| janquo wrote:
| Some company tooling / git oneliners from internet / and
| probably most relevant for me is git plugins for neovim /
| some personal scripts I would have rewrite to work both in
| .git and .jj repos
| charlie-83 wrote:
| JJ doesn't support git LFS is a common reason.
| steveklabnik wrote:
| The fix for this is in progress.
| donatj wrote:
| I found worktrees unnecessarily painful in Git with little
| advantage over just having two copies of the repo.
|
| 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.
| dylanowen wrote:
| I use work trees so my prototype can be open while I build my
| final code, but I never thought of local remotes! That'll be so
| much easier!
| loeg wrote:
| It's very useful when your repos are a significant fraction of
| disk space.
| actinium226 wrote:
| Genuinely curious, what did you find painful about it? A while
| back I found it annoying that I'd get errors when cleaning out
| my branches because they were checked out in a worktree I'd
| forgotten about, but git now highlights branches checked out in
| worktrees and has done so for a while.
| fusslo wrote:
| I don't understand the workflow that makes JJ more useful than
| git. I dont think I've even had the idea of having multiple
| worktrees going at once. What is the use case? The author
| mentions being blocked by CI flow. Don't you have CI running on
| gitlab or github? just commit and push the branch and run CI. The
| author mentions stashing the changes, but like.. if you're
| running against CI, isn't it in a state that is commitworthy? 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.
|
| 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.
| mastax wrote:
| You push branch A, then switch to branch B and start working on
| that. CI failed on branch A, so you stash branch B and switch
| back to branch A to fix it.
| fusslo wrote:
| thanks, that makes sense. I don't see how a worktree is more
| convenient in that case.
|
| 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
| neandrake wrote:
| Worktrees are useful particularly because they look like
| entirely separate projects to your IDEs or other project
| tooling. They are more useful on larger projects with lots
| of daily commits. If you just use branches then whenever
| you switch, in the worst case, your IDE has to blow away
| caches and reconstruct the project layout or build the
| project fresh. On large projects this takes significant
| time. But switching your IDE to a different project, there
| are now two project and build caches to switch between.
| fusslo wrote:
| ah interesting. our codebase is over 10gb with about 8
| years of history. But, we only have 2-3 merges per week.
| SatvikBeri wrote:
| "When is jj useful" is a different question from "when are
| workspaces/git worktrees useful"
|
| 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.
| Zambyte wrote:
| For what it's worth, I have been using jj as my primary git
| client for two years at this point, and have only use
| workspaces to see how they work, and then never touched them
| again.
|
| 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.
| steveklabnik wrote:
| I wrote a very popular tutorial for jj, and I didn't use
| workspaces until a few weeks ago. They're useful for the same
| reasons git worktrees are: most recently, people use them for
| doing work with multiple AI agents in parallel, but
| historically, I've seen people use them for things like "this
| project's build takes 30 minutes so I want to work on something
| else while I wait for that".
|
| > 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.
| jfb wrote:
| I think it shouldn't be, and the poor affordances in git have
| hidden this for a long time.
| steveklabnik wrote:
| What kinds of things do you use it for? I'm always open to
| learning about newer and better ways to work.
| jfb wrote:
| I keep my agent workflows distinct; we have (for historic
| reasons) a lot of non-git controlled context that differs
| between branches, and moving all that around on checkouts
| is untenable. I use this tool:
|
| https://github.com/tdhopper/wt
|
| with some custom shell aliases to make it easier.
| loeg wrote:
| I've used multiple worktrees with plain git; it's not a unique
| jj feature anyway. It's handy for working on multiple things at
| the same time with somewhat less cognitive overhead to switch
| back and forth.
| DHRicoF wrote:
| I don't know what JJ brings over git, but what sold me
| worktrees around 2 years ago was this article:
| https://matklad.github.io/2024/07/25/git-worktrees.html
| nvader wrote:
| Specific workflows that I use in jj vs git:
|
| 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.
___________________________________________________________________
(page generated 2025-12-08 23:01 UTC)