Jujutsu megamerges for fun and profit
Posted by icorbrey 12 hours ago
Comments
Comment by umvi 4 hours ago
Comment by stouset 3 hours ago
Comment by ehnto 34 minutes ago
I don't layer my utensils for example, because a spoon is fit for purpose and reliable.
But if I needed to eat multiple different bowls at once maybe I would need to.
For my personal use case, git is fit for purpose and reliable, even for complex refactoring. I don't find myself in any circumstances where I think, gosh, if only I could have many layers of this going on at once.
Comment by jychang 59 minutes ago
Comment by surajrmal 3 hours ago
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.
Comment by SOLAR_FIELDS 3 hours ago
The jj lovers can go build their massive beautiful branches off in a corner, I'll be over here building an SDLC that doesn't require that.
Old man yells at cloud moment is over
Comment by chrishill89 1 hour ago
Programs to manage “stacks of patches” go back decades. That might be hundreds that have accumulated over years which are all rebased on the upstream repository. The upstream repository might be someone you barely know, or someone you haven’t managed to get a response from. But you have your changes in your fork and you need to maintain it yourself until upstream accepts it (if they ever call back).
I’m pretty sure that the Git For Windows project is managed as patches on top of Git. And I’ve seen the maintainer post patches to the Git mailing list saying something like, okay we’ve been using this for months now and I think it’s time that it is incorporated in Git.[1]
I’ve seen patches posted to the Git mailing list where they talk about how this new thing (like a command) was originally developed by someone on GitHub (say) but now someone on GitLab (say) took it over and wants to upstream it. Maybe years after it was started.
Almost all changes to the Git project need to incubate for a week in an integration branch called `next` before it is merged to `master`.[1] Beyond slow testing for Git project itself, this means that downstream projects can use `next` in their automated testing to catch regressions before they hit `master`.
† 1: Which is kind of a like a “megamerge”
Comment by surajrmal 3 hours ago
Comment by SOLAR_FIELDS 3 hours ago
Comment by dwroberts 1 hour ago
That’s why it’s always the same confusing hype when it’s discussed, because it’s AI/LLM hype effectively
Comment by baq 2 hours ago
Turns out these two differences combined with tracking change identity over multiple snapshots (git shas) allow for ergonomic workflows which were possible in git, just very cumbersome. The workflows that git makes easy jj also keeps easy. You can stop yelling at clouds and sleep soundly knowing that there is a tool to reach for when you need it and you’ll know when you need it.
Comment by lucianbr 59 minutes ago
Yeah, and? Not everyone is in control of the culture of the organization they work in. I suspect most people are not. Is everyone on HN CEOs and CTOs?
Comment by uasi 3 hours ago
Comment by RicDan 2 hours ago
Comment by jnpnj 2 hours ago
Comment by p_l 3 hours ago
And better conflict resolution means it often becomes viable to just have mega merge add next release
Comment by dwb 2 hours ago
Comment by anthrofract 4 hours ago
Comment by edu 2 hours ago
Comment by socalgal2 3 hours ago
Comment by locknitpicker 3 hours ago
This. Things like stacks and mega-merges are huge red flags, and seeing enthusiastic people praising how a tool is more convenient to do things that raise huge red flags is perplexing.
Let's entertain the idea of mega-merges, and assume a tool fixes all tool-related issues. What's the plan to review the changes? Because what makes mega merges hard is not the conflicts but ensuring the change makes sense.
Comment by jamienicol 1 hour ago
What's the red flag about a stack?
Comment by bilekas 1 hour ago
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.
Comment by jFriedensreich 55 minutes ago
Comment by dzaima 49 minutes ago
Won't get you much if you don't like to mutate commits in general, of course; at that point it's just a different committing workflow, which some may like and some dislike. (I for one am so extremely-happy with the history-rewriting capabilities that I've written some scripts for reinventing back a staging area as a commit, and am fine to struggle along with all the things I don't like about jj's auto-tracking)
As a fun note, git 2.54 released yesterday, adding `git history reword` and `git history split` in the style of jj (except less powerful because of git limitations) because a git dev discovered jj.
Comment by jychang 1 hour ago
> 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.
Comment by bilekas 39 minutes ago
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.
Comment by quicksnap 5 hours ago
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!
Comment by Brajeshwar 3 hours ago
Comment by stouset 3 hours ago
Comment by eru 3 hours ago
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.
Comment by locknitpicker 3 hours ago
People tried mercurial. They went back to git.
Comment by eru 2 hours ago
Comment by e40 45 minutes ago
Comment by onair4you 5 hours ago
Comment by nchmy 10 hours ago
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
Comment by chrishill89 2 hours ago
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/sim...
Comment by ksymph 7 hours ago
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.
Comment by quicksnap 5 hours ago
Comment by incognito124 2 hours ago
Comment by dbt00 5 hours ago
Comment by VerTiGo_Etrex 11 hours ago
Comment by sukit 8 hours ago
Comment by FiloSottile 8 hours ago
Comment by nchmy 7 hours ago
Comment by paradox460 6 hours ago
Comment by KPGv2 6 hours ago
what's next, "oh! my gitess"? "chainsvn man"?
Comment by joshka 8 hours ago
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)
Comment by altano 8 hours ago
Comment by anthrofract 5 hours ago
Comment by the_data_nerd 6 hours ago
Comment by chaychoong 8 hours ago
[1] https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize [2] https://blog.chay.dev/parallelized-commits
Comment by b1temy 7 hours ago
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?
Comment by quicksnap 5 hours ago
When I have discrete, separate units of work, but some may not merge soon (or ever), being able to use mega merges is so amazing.
For example, I have some branch that has an experimental mock-data-pipeline thingy. I have yet to devote the time to convince my colleagues to merge it. But I use it.
Meanwhile, I could be working on two distinct things that can merge separately, but I would like to use Thing A while also testing Thing B, but ALSO have my experimental things merged in.
Simply run `jj new A B C`. Now I have it all.
Because jj's conflict resolution is fundamentally better, and rebases are painless, this workflow is natural and simple to use as a tool
Comment by jhhh 7 hours ago
Comment by duskdozer 6 hours ago
Comment by baq 1 hour ago
Your repo is small and/or your CI is fast. You’ll understand in a big repo or when CI has to run overnight to get you results.
Comment by faangguyindia 7 hours ago
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.
Comment by KPGv2 6 hours ago
Comment by amonks 4 hours ago
You’re right that I have to make sure that the backend changes don’t depend on the mobile changes, but I might have to be mindful of this anyway if the backend needs to stay compatible with old mobile app versions. Megamerge doesn’t seem to make it any harder.
Comment by kalstone 7 hours ago
Comment by usernametaken29 6 hours ago
Comment by socalgal2 3 hours ago
In other words, I effectively was working on one thing, but at a quicker easier pace.
Comment by conradludgate 2 hours ago
Comment by BeetleB 5 hours ago
I gather one scenario is: You do a megamerge and run all your tests to make sure new stuff in one branch isn't breaking new stuff in another branch. If it does fail, you do your debug and make your fix and then squash the fix to the appropriate branch.
Comment by baq 5 hours ago
Comment by juped 4 hours ago
Comment by qsera 7 hours ago
IUUC This is already implemented for git as an extension. https://github.com/tummychow/git-absorb
I think this is such a basic thing that should be part of any DVCS implementation.
Comment by thierrydamiba 7 hours ago
Comment by nvahalik 11 hours ago
If anyone is JJ-curious, I also can't recommend the Discord[1] enough. The community is very helpful and welcoming.
Comment by krupan 3 hours ago
I'm hesitant to pick jj up in case it ends up losing to git like mercurial did. But it's very tempting.
Comment by thunderbong 3 hours ago
Comment by vaylian 2 hours ago
Comment by taberiand 44 minutes ago
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)
Comment by jamienicol 2 hours ago
https://www.jj-vcs.dev/latest/config/#set-of-immutable-commi...
Comment by vrnvu 1 hour ago
You can force changes with a ‘—ignore-inmutable’ flag.
Comment by polskibus 1 hour ago
Comment by grim_io 11 hours ago
Comment by icorbrey 11 hours ago
Comment by Guvante 7 hours ago
Comment by rixtox 8 hours ago
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.
Comment by icorbrey 8 hours ago
Comment by CodeCompost 4 hours ago
Comment by taberiand 11 hours ago
Comment by icorbrey 10 hours ago
Comment by uhhhd 9 hours ago
Comment by MeetingsBrowser 9 hours ago
Comment by riwsky 8 hours ago
Comment by rndhouse 8 hours ago
Comment by uhhhd 7 hours ago
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.
Comment by qsera 7 hours ago
It better be, now and going forward for people who use LLMs..because they will need it when LLM messes up and have to figure out, manually, how to resolve.
You ll need all the help (not to mention luck) you need then..
Comment by surajrmal 6 hours ago
Comment by skydhash 6 hours ago
You're bashing the old way, but you do not provide any concrete evidence for any of your points.
> The unit of work is no longer “branches” or “commits,” it’s intent.
Insert <astronaut meme "always has been">.
Branching is always about "I want to try to implement this thing, but I also want to quickly go back to the main task/canonical version". Committing is about I want to store this version in time with a description of the changes I made since the last commit. So both are an expression and a record of intent.
> Parallel workstreams used to require careful coordination: rebasing, merging, conflict resolution, mental bookkeeping of state.
Your choice of words is making me believe that you have a poor understanding of version control and only see it as storage of code.
Commits are notes that annotates changes, when you want to share your work, you share the changes since the last version everyone knows about alongside the notes that (should) explain those changes. But just like you take time to organize and edit your working notes for a final piece, rebasing is how you edit commits to have a cleaner history. Merging is when you want to keep the history of two branches.
Conflict resolution is a nice signal that the intent of a section of code may differ (eg. one wants blue, the other wants red). Having no conflict is not a guarantee that the code works (one reduces the size of the container, while the other increase the flow of the pipe, both wanted to speed up filling the container). So you have to inspect the code and run test afterwards.
Discard the above if you just don't care about the code that you're writing.
Comment by nozzlegear 6 hours ago
Comment by baq 5 hours ago
Comment by quicksnap 5 hours ago
Comment by dbt00 11 hours ago
I'm still not as smooth at figuring out conflicts on mega-rebase.
Comment by juped 10 hours ago
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.
Comment by incognito124 11 hours ago
Comment by LoganDark 10 hours ago
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.
Comment by notmywalrus 9 hours ago
There are commands for manipulating tags (jj tag set, jj tag delete), and recently [1] support for fetching / pushing
Comment by LoganDark 9 hours ago
Comment by icorbrey 9 hours ago
Comment by jordwest 7 hours ago
Probably my favourite thing that has really changed my workflow is being able to write empty commits in advance then just switch between them. It helps me remember what I’m doing and whats next whenever I get distracted or take a break.
Comment by forrestthewoods 9 hours ago
Comment by icorbrey 9 hours ago
Comment by techpulselab 9 hours ago
Comment by huflungdung 9 hours ago