> I've got a feeling you are not being fully serious, so on that assumption instead of me explaining why this really not at all the case, how about you provide an example of a workflow that you think crucially depends on merging rather than rebasing, and we can discuss that?

I'm completely serious. Fundamentally any workflow where you have multiple long-lived branches and want to cross-merge between them (e.g. branches for several mostly-independent long-term features, per-client branches) is impossible with rebase; rebase necessarily only works if you have a single central master branch, at which point you're doing something more or less equivalent to SVN (I didn't mean "you might as well just use SVN" as flippantly as it sounds; I genuinely do think SVN is a reasonable choice if your use pattern fits within its limitations and you place a very strong value on the simpler history model). More specifically if you can ever have a scenario where two different people resolve the same conflict (e.g. developer C merges from feature-A and feature-B into feature-C, developer D merges from feature-B and feature-A into feature-D), you end up in a lot of trouble if you're rebasing, IME.

Now of course it's generally good to avoid long-lived branches as much as possible. But even if your branches are short-lived, being able to freely cross-merge between feature branches makes development much nicer - you can anticipate and resolve or avoid potential conflicts earlier, while they're smaller, rather than hitting them only after a feature is code-complete.

Merging rather than rebasing also makes bisect (especially automated bisect) much more effective - if you rebase a branch that has a semantic conflict with master then it's very common for the rewritten commits to not even compile, so you end up with lots of non-compiling commits scattered through your history. Worse, those non-compiling commits tend to be in long chains, so bisect can only tell you that the commit you're looking for lies somewhere within that chain.

> Sure: given a test command, show me a simple git bisect invocation that finds the merge commit that broke master.

Why would that ever be what you want, and how does rebase make it any easier? In a merge workflow you still have the history to use something like https://gist.github.com/ayust/2040290 if you really want to (and I'm sure a builtin command could be added if there was a convincing use case for one), whereas it's completely impossible in a rebase workflow.

> I think this is a useful criterion, but one that tends to be only clear-cut for things like shrinkwrapped software (and it's not the only thing that matters). If you run a service of any complexity and with any sort of uptime requirements, you will not ship everything together, even if its part of a single feature and often you will have different versions of the same service in production in parallel as well.

I'm not worried about having multiple versions running for a few minutes while a deploy is in process (though I favour having a rule that there can only be one deployment of a given system ongoing at the same time, every deployment must have an owner, and that owner is responsible for leaving the system in a consistent state when they're finished, whether that means finishing the deploy, rolling back, or something else). But if you're happy with having foo deployed on version X and bar deployed on version Y then I'd say that foo and bar are separate systems and the VCS model should reflect that: if anything, if your changes to foo are going to be deployed independently from your changes to bar then I'd rather you had to make two separate commits and think about what the code looks like when one change has been applied and the other hasn't, because that's exactly what's going to be happening at runtime.

> A strange objection. Surely the point of having a super-repo would be that the subrepos at any one commit in the super repo would form a consistent state of the world, rather than you pinning inconsistent versions of different repos in the same commit of your super-repo?

In the case of an internal library there most likely isn't a single consistent version, because different components will depend on different versions of it. More subtle versions of the same thing happen as soon as you have two services that talk to each other but are deployed independently - you can see the code for A and B, but not the code for B as A depends on it. Consistent states exist for things that are deployed in lockstep, but are, I think, misleading for things that aren't.

> At the most basic level you could think about the sup-repos like a pinned (yarn, poetry, budler, ...) dependencies and the super-repo as a lockfile with extra benefits (such as 'git diff HEAD^' presumably showing you all the source changes in the sub repos since the last time you committed their versions in the super-repo).

That sounds like something with quite different characteristics from a git repository. I'm not necessarily against having tools that can deal with multiple repositories at the same time, but I don't think presenting them as a single repository is helpful for that.