7 ms·
Jujutsu megamerges for fun and profit
- incognito124 5mo agoFinally
- dbt00 5mo agothis is great stuff. I've been ad hoc building a version of this workflow, and it is quite fantastic. I'm still not as smooth at figuring out conflicts on mega-rebase.
- grim_io 5mo agoIf this works like I think it does, it might be the missing piece I've been waiting for, for actually trying jj. Thanks!
- icorbrey 5mo agoAwesome! Tbh other than GitButler idk where I'd even start if I had to recreate this with vanilla Git
- VerTiGo_Etrex 5mo agoMakes me happy to see the influx of jj posts as of late. Great tool. Roughly this workflow is how I convinced a few friends to finally loosen their death grip on git and try something new.
- taberiand 5mo agoHow does the megamerge handle the case where two included branches overlap in changes and a new commit is made that applies to the overlap?
- nvahalik 5mo agoThe mega merge wouldn't handle that based on the way the article shows. You COULD have a revset that includes stacked changes, though. That does work and is what I currently do.
- nchmy 5mo agoCould you please elaborate on how you do this?
- nvahalik 5mo agoIf you have a dependency tree like this: / A \ -- B - Megamerge \ C / There is nothing stopping you from doing this: / A - D \ -- B ----- - Megamerge \ C - E / (Edit, or even this:) / A - D \ -- B ----- - Megamerge \ C ----/ \ E / Where E stacks on C and D stacks atop A. In the case above, A-E are revsets of either 1 or more commits. JJ doesn't care if they are or not. You'd generally bookmark the revset on the final "commit" as the pointer. / features/add-widgets / / features/add-widget-integration / A - D \ -- B ----- - Megamerge \ C - E / \ \ feature/add-new-page \ feature/rework-navigation In the example above, let's say you rework the navigation. You could have it exist alongside the navigation rework, but changes are you don't want to do the work twice. You just say "hey, this depends on the nav rework" and so it's there inside of the repo. The thing is there is another way to do this where you end up with 4 different parents in a megamerge and your nav rework touches the megamerge and your new page is yet another revset is just a fork off of it. But yeah... JJ gives you a lot of flexibility in this manner.
- nchmy 5mo agoThanks!
- nvahalik 5mo agoGreat article, Isaac! If anyone is JJ-curious, I also can't recommend the Discord[1] enough. The community is very helpful and welcoming. [1]: https://discord.com/invite/dkmfj3aGQN https://discord.com/invite/dkmfj3aGQN
- nchmy 5mo agoSome fantastic tricks in this article. Will definitely improve my Megamerge game. Thanks! Though, I'd be remiss not to mention that this (and any other) jj workflow would be much easier with jjui. It's the best TUI around, not just for jj I proposed incorporating some of this article into it. https://github.com/idursun/jjui/discussions/644 https://github.com/idursun/jjui/discussions/644
- juped 5mo agoIt's interesting to see the strange workflows that come from jujutsu users, as someone who works on git workflows. There's some counterproductive stuff in there from my perspective but at its core you're keeping up a throwaway integration branch, which is helpful practice if you'll ever care about an integration. It's annoying with git because the interface for updating your throwaway integration branch is very clunky and easy to get wrong.
- LoganDark 5mo agoI saw Jujutsu on HN a few days ago and gave it a try. I picked a bunch of it up in just a couple hours and a couple days later I've completely switched to it for all my projects, it's not even close. Git is dead to me. I just wish Jujutsu supported git tags rather than only supporting bookmarks as branches. And I also wish that Jujutsu supported preserving commit dates during rebases. One of my absolute favorite things about Jujutsu is how easy it is to manipulate the commit graph remotely without having to manually checkout each commit first. I've been working on some pull requests to their built-in diff editor lately trying to improve the user experience enough that most conflicts will be fixable without having to use a text editor. Also, the lack of a special staging area means you also never have to fucking stash your changes before you can do practically anything. Your changes always have a place, you can always go somewhere else and you can always come back.
- notmywalrus 5mo ago> git tags There are commands for manipulating tags (jj tag set, jj tag delete), and recently [1] support for fetching / pushing [1]: https://github.com/jj-vcs/jj/pull/9279 https://github.com/jj-vcs/jj/pull/9279
- LoganDark 5mo agoOh? That's incredibly recent. Thank you for letting me know. As it turns out, I just built jj from source earlier today, so ironically I should already have tags. I'll give it a try.
- icorbrey 5mo agoRe: commit dates, fundamentally those always change when rebasing because you're rewriting the commit object, but we don't touch the author date unless you explicitly reset it with metaedit
- LoganDark 5mo agoI'm not sure which date GitHub displays, but whenever I change something early in history, the entire repo loses every date.
- forrestthewoods 5mo agoGreat post. Thanks for sharing.
- icorbrey 5mo agoThanks!
- techpulselab 5mo ago[dead]
- huflungdung 5mo ago[dead]
- uhhhd 5mo agoI love this stuff as a hobbyist, but professionally I can't help but think this is all obsolete in the age of agent-driven development. I wish jj was around a decade ago.
- MeetingsBrowser 5mo agoI disagree. Easily reviewing and combining multiple streams of parallel work is more valuable than ever.
- riwsky 5mo agoWith jj worktrees, you can even have agents working on each of those sub-megamerge branches in parallel.
- rndhouse 5mo agoI've been playing around with agent-native source annotation to specifically address the massively parallel work problem. Check it out here: https://github.com/draxl-org/draxl https://github.com/draxl-org/draxl
- uhhhd 5mo agoYou don’t need jj for this anymore. The whole premise of optimizing human workflows around source control is becoming obsolete. When LLMs are driving development, source control stops being an active cognitive concern and becomes a passive implementation detail. The unit of work is no longer “branches” or “commits,” it’s intent. You describe what you want, the model generates, refactors, and reconciles changes across parallel streams automatically. Parallel workstreams used to require careful coordination: rebasing, merging, conflict resolution, mental bookkeeping of state. That overhead existed because humans were the bottleneck. Once an LLM is managing the codebase, it can reason over the entire state space continuously and resolve those conflicts as part of generation, not as a separate step. In that world, tools like jj are optimizing a layer that’s already being abstracted away. It’s similar to how no one optimizes around assembly anymore. It still exists, it still matters at a lower level, but it’s no longer where productivity is gained.
- sukit 5mo agoBeen trying to get into jj lately, but I rely a lot on VS Code's git gutter to review changes as I code. Doesn't look like jj has an equivalent in VS Code. Anyone got tool recommendations?
- deleted 5mo ago[deleted]
- altano 5mo agovisualjj, it’s fantastic
- joshka 5mo agojjk or jjview I have a PR up for jjk that does the full change as a review changes, and there's another user's PR that allows diffs over arbitrary ranges (i.e. when working out whether the commits that make up a PR are good as a whole rather than individually)
- FiloSottile 5mo agoI just use the VS Code git integration with the jj colocated git repo. HEAD is @- and the changes in @ are considered working copy changes. It works for all I was using the VS Code integration for.
- nchmy 5mo agoSame experience here
- paradox460 5mo agoThere are a number of jj plugins for vsc. VisualJJ and Jujutsu Kaizen are probably the two most popular https://www.visualjj.com/ https://www.visualjj.com/ https://github.com/keanemind/jjk https://github.com/keanemind/jjk
- KPGv2 5mo ago> jjk what's next, "oh! my gitess"? "chainsvn man"?
- chaychoong 5mo agoGreat writeup! I've been using `jj parallelize` [1] a lot (and wrote about it here [2]) to fan out a sequence of commits to set up a megamerge, but your stack alias sounds super useful to create them on the fly, rather than at the very end of a work stream. Thanks for the tips! [1] https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize [2] https://blog.chay.dev/parallelized-commits https://blog.chay.dev/parallelized-commits
- rixtox 5mo agoI found octopus megamerge hard to collaborate - my colleagues don't use JJ so they may introduce changes that would cause conflitcts to my megamerge. When you have a conflict on a change that has more than 2 parents, the conflict resolution becomes unmanageable very quickly. No merge tool can handle more than 3-way merge, so you have to do that manually. Eventually I settled on a tree-like megamerge that's more practical: merge 2 branches at a time and merge the merged branch with the next branch. This way I only need to handle 2-way conflicts at a time which is more manageable. Also you have to be very careful to decide the order when you (and your colleagues) are going to land the branches, or if you expect any new features other people are working on that's going to conflict with your branches. When using megamerger workflow, most of the problems come from coordinating with other colleagues.
- icorbrey 5mo agoFwiw I've not had this experience, I use megamerges in teams of 8+ devs without much issue
- b1temy 5mo agoI do not understand the appeal of the workflow of working on separate things in parallel, then splitting it off into branches/commits. imo, isn't it better to fully focus on one thing at a time, even if it is "simple"? I imagine if I follow this workflow, I might accidentally split it off in a way that branch A is dependent on some code changes in branch B, and/or vice versa. Or I might accidentally split it off in a way that makes it uncompilable (or introduce a subtle bug) in one commit/branch because I accidentally forgot there was a dependency on some code that was split off somewhere else. Of course, the CI/CD pipeline/reviewers/self-testing can catch this, but this all seems to introduce a lot of extra work when I could have just been working on things one at a time. I'm open to changing my mind, I'm sure there are lots of benefits to this approach, since it is popular. What am I missing here?
- faangguyindia 5mo ago>I do not understand the appeal of the workflow of working on separate things in parallel, then splitting it off into branches/commits. imo, isn't it better to fully focus on one thing at a time, even if it is "simple"? because agents are slow. I use SOTA model (latest opus/chatgpt) to first flesh out all the work. since a lot of agent harness use some black magic, i use this workflow 1. Collect all issues 2. Make a folder 3. Write each issue as a file with complete implementation plan to rectify the issue After this, i change from SOTA to Mini model Loop through each issue or run agents in parallel to implement 1 issue at a time. I usually need to do 3 iteration runs to implement full functionality.
- KPGv2 5mo ago"because AI" isn't really a good answer since JJ was not created for AI, and most people who use JJ aren't just AI bots.
- jhhh 5mo agoIt does seem to introduce a lot of complexity for its own sake. This kind of workflow only survives on the absorb command and like you said it doesn't really cover all the interplay of changes when separated. It's a more independent version of stacked diffs, with worse conceptual complexity.
- qsera 5mo ago>The absorb command will do a lot of this for you by identifying which downstream mutable commit each line or hunk of your current commit belong in and automatically squashing them down for you. This feels like magic every time I use it (and not the evil black box black magic kind of magic where nothing can be understood), and it’s one of the core pieces of Jujutsu’s functionality that make the megamerge workflow so seamless. IUUC This is already implemented for git as an extension. https://github.com/tummychow/git-absorb https://github.com/tummychow/git-absorb I think this is such a basic thing that should be part of any DVCS implementation.
- thierrydamiba 5mo agoSomething really magical about “Distributed Version Control System” sharing an acronym with “Disney Vacation Club Services”.
- mhw 5mo agoI've worked with git using the mega-merge approach, and one thing I found is that git-absorb won't merge commits into anything that precedes a merge. It works fine for absorbing changes into earlier commits on a feature branch, but not from the WIP branch back into the multiple feature branches that are the parents of the mega-merge. jj handles this with no problems. From this comment on the git-absorb issue tracker I wouldn't expect it to be fixed soon either: https://github.com/tummychow/git-absorb/issues/134#issuecomment-2547130841 https://github.com/tummychow/git-absorb/issues/134#issuecomm...
- ksymph 5mo agoSemi off-topic, but does anyone know of good resources for jj that don't assume git knowledge? Steve's and others are high quality, but often things are explained in terms of git equivalents or describe workflows that I struggle to fully understand the purpose of, as someone who knows only the barest basics of git necessary to work on personal projects. If none exist, I think there's a great opportunity there, for anyone with the knowledge and motivation to make some absolute beginner guides. Already jj is infinitely more user-friendly, and as the tool matures, it isn't far fetched to think a new generation of programmers could go straight to jj without knowing their way around git first.
- quicksnap 5mo agoI'm not immediately aware. There's a certain amount of git-ness embedded in it with it being a DAG, having commits, and being compatible with git remotes. And, since the industry still runs on git, most people will need to learn it somewhat, anyway.
- dbt00 5mo agoHonestly, until JJ is 1.0, I wouldn't recommend it for beginners. There's significant changes happening to the interface still.
- maleldil 5mo agoI've been using it in relatively the same way for a while now. The only meaningful changes were native support for `tug` and `absorb`, neither of which significantly changed my workflow.
- dzaima 5mo agoeh, there have been a good amount of breaking changes. `-d`/`--destination` → `-o`/`--onto` (the former isn't yet deprecated though); deprecated `--allow-new` on push (or, forcibly making it the default for `--bookmark`); deprecated `jj bookmark track foo@bar` (and `jj bookmark track foo` having a really-weird system (I personally just call it broken, even though the behavior is intentional) of sometimes tracking the bookmark on all remotes; really I'd call jj's entire system of bookmark tracking/pulling/pushing quite incomplete outside of the trivial cases); various changed revset functions over time that break configs; and a really-annoying thing of `jj git fetch` sometimes abandoning ascendants of `@` leaving you in a confusing state (if not one with conflicts), with the solution being a future `jj git sync`. It's certainly very usable despite all that, and the changes are simple enough to adapt to, but it's a pretty new thing.
- Guvante 5mo ago"Evil" merged are only evil if your tooling skips over merge commits as "unimportant" which is a common tactic to try and prune some of the crazy trees you get when hundreds of people are making merge commits into a repo which then creates its own commits for automation reasons...
- SipitenoMK 5mo ago[flagged]
- quicksnap 5mo agoTrying out jj is super low-risk--since it uses git as a backend, you can test it out and bail back to git without any drawbacks other than a detached head state. And I hope you do. It is so much better than git in every way. It enables working with stacks and the aforementioned megamerges so easily, allowing me to continue working forward while smaller units of work are reviewed/merged. When I first tried to use jj, I wasn't entirely committed and switched between jj and git. Finally I hit a breaking point being fed up with stacks/merges and tried jj _for real_. I recommend to give it a serious try for a few solid days and use it exclusively to really understand it. You won't go back. The jj Discord is a very helpful place. Thanks to everyone there. Great article Isaac!
- onair4you 5mo agoI’ve been loving it for personal projects. But for work, some of our homebrew tooling relies heavily on hashes. So any operation that causes snapshotting to occur tends to lead to breakage that utterly confounds Claude. I tried giving it rules and instructions to make sure to sync git up to the correct commit for the current snapshot, but as soon as the signal for that is too week in the context it blows a gasket trying to figure out what has gone wrong.
- eru 5mo ago> Trying out jj is super low-risk--since it uses git as a backend, you can test it out and bail back to git without any drawbacks other than a detached head state. Btw, the risk of trying out other modern version control systems is nearly as low: most of them are compatible with git and you can convert back and forth. That definitely includes mercurial etc.
- locknitpicker 5mo ago> That definitely includes mercurial etc. People tried mercurial. They went back to git.
- eru 5mo agoSome did, sure. I made a more limited claim: you can convert back and forth between mercurial and git.
- anthrofract 5mo agoI enjoyed this article a lot, gave me some new ideas for my Jujutsu TUI, Majjit: https://github.com/anthrofract/majjit https://github.com/anthrofract/majjit
- umvi 5mo agoI don't get JJ. Every time it's posted people gush about how JJ enables some super complicated workflow that I can't wrap my head around. I have a simple feature branch/rebase workflow in git that has served me well for decades so I guess I don't understand why I would want to complicate things with (in this case) an "octopus merge/megamerge". Wouldn't that make it more difficult to reason about the repository/history?
- anthrofract 5mo agoI stick to basic workflows most of the time, and it's still much better.
- socalgal2 5mo agoSounds like a SVN user complaining about git
- surajrmal 5mo agoIf you wrangle a lot of in flight changes that are not yet merged into your teams primary git repo, it's very helpful. I have some 10-30 changes in various states at any time. Sometimes they have dependencies on each other sometimes they don't. Placing them all into one branch can work but it's a lot less ergonomic in many ways. jj makes my life simpler because it accommodates my workflow in a way git doesn't. Honestly, if you don't find it appealing you don't need to use it. I think a lot of folks don't find vim appealing and stick to vscode and that's okay too.
- CodeCompost 5mo agoI was skeptical at first but when I dragged and dropped a bookmark in `gg` then a light went on in my head. Also the fact that jujutsu does everything in "detached mode" locally means that you can't mess up your remote git repo (unless you force push all yolo from git itself, but you're never expected to do that).
- krupan 5mo agoI reluctantly stopped using mercurial 10 or so years ago, and reading this brings a little tear to my eye. Mercurial was just about where jj seems to be now. It had revsets. It had just gotten the concept of mutable and immutable commits. It had absorb. It had bookmarks. It never had an "index". The commands had human readable options like I see in this post. It could work with git repositories. Man I miss it. I'm hesitant to pick jj up in case it ends up losing to git like mercurial did. But it's very tempting.
- thunderbong 5mo agoIt can't really lose to git, because underlying it is git
- rstuart4133 5mo agoAccording to the guy who wrote JJ, he copied all the ideas you mentioned from hg. That included a lot of ideas from hg's add ons. So the similarities are no accident. But then he added a twist - he didn't just delete the index, he dropped "hg commit" as well. I can't see it going anywhere. It is in many ways "just" a different porcelain for git. The plumbing is the same. It's also safer to use: no JJ command can lose data another JJ command can't recover.
- chrishill89 5mo agoSometimes I have several pull requests to review and none of them have any meaningful overlap (e.g. they touch code in different places, no apparent risk of overlap). So I've started making integration branches to test all of them in one go. But then I sometimes find things to improve upon. Then I might make a few commits on top of that. And then later I have to manually move them to the correct branch. I might also remove them from the integration branch, but git-rebase(1) is likely to just drop them as already-applied. My mind was a little blown when I read about the megamerge strategy in Steve Klabnik's tutorial.[1] Yes, Jujutsu's approach of autorebasing changes is very nice. Now all I have to do is to try it myself. † 1: https://steveklabnik.github.io/jujutsu-tutorial/advanced/simultaneous-edits.html https://steveklabnik.github.io/jujutsu-tutorial/advanced/sim...
- eddd-ddde 5mo agoWith JJ I sometimes make a 'jj new a b c' to work on top of multiple changes. Then as I tweak things 'jj absorb' to automatically patch the right changes. Insanely easy and effective.
- vaylian 5mo agoOne of the golden rules of git is: Don't rewrite public history (for example by rebasing and force-pushing already published commits). The article hints at immutable and mutable commits (https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-and-profit#user-content-fn-4 https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-an...) but I am unsure about how fundamental this protection is. I don't want to ruin my co-worker's day by accidentally rewriting public history.
- jamienicol 5mo agoThere's a configurable setting for which changes are marked as immutable. The default works perfectly for my workflow (pull-only from upstream, rewrite and push freely to my fork). other workflows may presumably need to tweak it https://www.jj-vcs.dev/latest/config/#set-of-immutable-commits https://www.jj-vcs.dev/latest/config/#set-of-immutable-commi...
- vrnvu 5mo agoJujutsu is immutable for public changes by default. You can force changes with a ‘—ignore-inmutable’ flag.
- taberiand 5mo agoDon't rewrite shared public history It's ok to force-push a branch that only you have worked on (and even in the case of others working on the same branch it can be fine as long as you communicate with them)
- vaylian 5mo agoI agree. This is a valid exception.
- rstuart4133 5mo agoRewriting immutable commits is only "fundermental" if it's enforced upstream. You can always break the rule locally. That said, jj will warn you if you try to edit an immutable commits, and you can configure what it considers immutable.
- 5mo ago
- bilekas 5mo agoI think I'm missing some major selling point of jj, to me it's just git with a different flow that might be more suitable for a rare few cases where heavy parallel work is happening, and even then git is fine if people know what they're doing, the idea of no staging areas doesn't appeal to me, mutable commits seems actively negative to me personally. I understand if people are enjoying it great, but the amount of praise and 'this is revolutionary' comments I see makes me really feel I'm missing a beat.
- jychang 5mo agoDid you read the article? > Basically, in the megamerge workflow you are rarely working directly off the tips of your branches. Instead, you create an octopus merge commit (hereafter referred to as “the megamerge”) as the child of every working branch you care about. This means bugfixes, feature branches, branches you’re waiting on PRs for, other peoples’ branches you need your code to work with, local environment setup branches, even private commits that may not be or belong in any branch. Everything you care about goes in the megamerge. It’s important to remember that you don’t push the megamerge, only the branches it composes. > You are always working on the combined sum of all of your work. This means that if your working copy compiles and runs without issue, you know that your work will all interact without issue. You don't even push the megamerge to the origin. Or perhaps you don't even need to push it. You can just... work off it.
- bilekas 5mo ago> You don't even push the megamerge to the origin. But why would I do that with git anyway ? My local branch is what I'm working of, if I'm not ready to push, why would I ? I can as you say just work off it.. And when I'm ready to push, I prep my commit, because I'm expecting it to be immutable and pulled by others 'as-is'. Again, I must be missing something. I think the tool is just not for me, yet at least.
- dwattttt 5mo agoI've often found myself needing to work on two features at once, esp. where one has a dependency on the other. Maybe that branch is the real goal, and the other branch is an independent chunk of work that the feature needs. Both get iterated on, because it's hard to know everything about a feature before it's done; maybe you find bugs that need fixing, or you realise you were missing something. Rebasing the dependent branch onto the tip of the other branch gets you there, but as a workflow it's not pleasant, especially if you're not the only person working on the features... It's a recipe for conflicts, and worse that rebased branch conflicting with another person's view of it.
- polskibus 5mo agoCan this technique help with fixing a bug on master then having to merge it easily to older release-branches , without resorting to cherry-picking (and losing all history)?
- jiggunjer 5mo agoStrange advice not to push the mega merge. It's what I call my release branch. One thing I like is there's many ways to achieve the same result. E.g. author uses a fancy rebase to graft a new branch between trunk and merge point. I could do the same by: 1) rebase -s onto trunk, 2) merge new branch with mega merge, 3) squash old megamerge upwards into new merge. No cryptic revset needed.
- zeristor 5mo agoSetting up 6 AI worker agents and as ever they end up committing over each other, really slows down my parallel work process using git. Next up once my Sunday morning token allowance is to look at using git.
- domysee 5mo agoIt sounds like the same workflow that GitButlers UI has. Can anyone with more knowledge than me confirm or deny that?
- PinkFluffyLlama 5mo agoJJ's mega-merge was inspired by GitButler, so yes! It is very similar.
- icorbrey 5mo agoIf you inspect a GitButler repo with JJ you can see that it's topologically identical actually! https://bsky.app/profile/isaaccorbrey.com/post/3m33wrahz4222 https://bsky.app/profile/isaaccorbrey.com/post/3m33wrahz4222
- Futurmix 5mo ago[dead]