4 ms·
> Honestly, in practice I haven’t found a single valid use-case for octopus merges which aren’t already covered by sequencing a series of merges, one after the
by chrismorgan 4y ago
> Honestly, in practice I haven’t found a single valid use-case for octopus merges which aren’t already covered by sequencing a series of merges, one after the other. Perhaps there are some integration use-cases out there which really let’s the octopus merge strategy shine. Let me know!
Functionally, the octopus strategy is slightly more conservative than a sequence-of-merges-with-abort-on-conflict, protecting you a bit more from the rough edges of Git’s unsound patch theory; but in practice you’re unlikely to ever trigger or observe the difference (though I did encounter it a number of times as part of a major refactoring—the diffs were just right to trigger it). I don’t think this alone would be particularly worthy of note (though for the sequence of merges, it might still be worth switching to the resolve strategy).
The difference I value is performance.
A few years ago I was working at a place that used labels on merge requests in GitLab to specify which of several pre-production environments that MR should be deployed to, and then on all head or label changes, reconstructed a branch for each environment based on merging the appropriate heads. When I started, it was taking each MR in sequence, fetching from its source repository and branch, and merging it, but this took several seconds per MR, and it wasn’t rare to end up with ten or even twenty include-in-beta MRs, and you couldn’t deploy the beta branch until that process was finished. It was also fiddly to diagnose the problem when you had conflicts (one MR conflicting with master, or two mutually-conflicting MRs), though this was more just a “no one got round to making the script perform the reverse correlation itself” thing. I got fed up when the process was sometimes taking two minutes, so I rewrote it to use a single specific fetch of all the heads (basically `git fetch origin refs/merge-requests/123/head refs/merge-requests/456/head …`, the GitLab API gave the commit hashes already so I let the fetches dangle rather than giving them a local ref, and used their commit hashes in the merge), followed by a single octopus merge. Since an octopus merge failure’s output was basically useless for identifying the problematic MRs, I made it fall back to sequential merges along with implementing the required reverse correlation and telling you which MRs conflicted. (And if the sequential merge succeeded, which is theoretically quite possible, I made it fail noisily, on principle).
The end result of it all:
• What had taken one and a half or two minutes now took under 10 seconds. (And even in the conflict case with its sequential merge fallback, the single fetch meant it’s be up to twenty or thirty seconds faster.)
• The job server performing the branch rebuild experienced vastly slower repository growth, no longer needing periodic aggressively-pruning garbage collection to avoid running out of disk space.
- myme 4y agoThank you for this elaborate explanation and very valid use-case. I did find out that octopus merges have been used quite extensively in e.g. the Linux history as I was trawling the archives for one of the anecdotal remarks I made. I eventually found them both, by the way (post updated): * https://lore.kernel.org/all/Pine.LNX.4.58.0506221433540.2353@ppc970.osdl.org/T/ https://lore.kernel.org/all/Pine.LNX.4.58.0506221433540.2353... * https://www.destroyallsoftware.com/blog/2017/the-biggest-and-weirdest-commits-in-linux-kernel-git-history https://www.destroyallsoftware.com/blog/2017/the-biggest-and... I suppose whenever you've got scenarios where integrating a significant volume of unrelated work (with low probabilities of conflicts) it starts to make a lot more sense. I guess it's not really been that relevant to me personally.