This article is written both for intermediate Jujutsu users and for Git users who are curious about Jujutsu.
I’m a big Jujutsu user, and I’ve found myself relying more and more on what we in the JJ community colloquially call the “megamerge” workflow for my daily development. It’s surprisingly under-discussed outside of a handful of power users, so I wanted to share what that looks like and why it’s so handy, especially if you’re in a complex dev environment or tend to ship lots of small PRs.
In a hurry? Skip to the end for some quick tips.
Merge commits aren’t what you think they are
If you’re an average Git user (or even a Jujutsu user who hasn’t dug too deep into more advanced workflows), you may be surprised to learn that there is absolutely nothing special about a merge commit. It’s not some special case that has its own rules. It’s just a normal commit that has multiple parents. It doesn’t even have to be empty!1
@ my zpxsys Isaac Corbrey 12 seconds ago 6 34e82e2 │ (empty) (no description set) ○ ml lmtkmv Isaac Corbrey 12 seconds ago git_head() 9 47a52fd ├─╮ (empty) Merge the things │ ○ v qsqmtlu Isaac Corbrey 12 seconds ago f 41c796e │ │ deps: Pin quantum manifold resolver ○ │ t qqymrkn Isaac Corbrey 19 seconds ago 04 26baba ├─╯ storage: Align transient cache manifolds ◆ z zzzzzzz root() 00 000000 Gotta put it all together!
You may be even more surprised to learn that merge commits are not limited to having two parents. We unofficially call merge commits with three or more parents “octopus merges”, and while you may be thinking to yourself “in what world would I want to merge more than two branches?”, this is actually a really powerful idea. Octopus merges power the entire megamerge workflow!
So what the hell is a megamerge?
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.
@ mn rxpywt Isaac Corbrey 25 seconds ago f 1eb374e │ (empty) (no description set) ○ wu xuwlox Isaac Corbrey 25 seconds ago git_head() c 40c2d9c ├─┬─╮ (empty) megamerge │ │ ○ tt nyuntn Isaac Corbrey 57 seconds ago 7d 656676 │ │ │ storage: Align transient cache manifolds │ ○ │ p tpvnsnx Isaac Corbrey 25 seconds ago 8 97d21c7 │ │ │ parser: Deobfuscate fleem tokens │ ○ │ zw pzvxmv Isaac Corbrey 37 seconds ago 1 4971267 │ │ │ infra: Refactor blob allocator │ ○ │ tq xoxrwq Isaac Corbrey 57 seconds ago 9 0bf43e4 │ ├─╯ io: Unjam polarity valves ○ │ mo slkvzr Isaac Corbrey 50 seconds ago 75 3ef2e7 │ │ deps: Pin quantum manifold resolver ○ │ q upprxtz Isaac Corbrey 57 seconds ago 53 32c1fd ├─╯ ui: Defrobnicate layout heuristics ○ ww tmlyss Isaac Corbrey 57 seconds ago 58 04d1fd │ test: Add hyperfrobnication suite ◆ zz zzzzzz root() 0 0000000 Scary! Too much merge!
... continue reading