Sometimes it feels like the least-bad alternative.
e.g. I'm currently working on a substantial framework upgrade to a project - I've pulled every dependency/blocker out that could be done on its own and made separate PRs for them, but I'm still left with a number of logically independent commits that by their nature will not compile on their own. I could squash e.g. "Update core framework", "Fix for new syntax rules" and "Update to async methods without locking", but I don't know that reviewers and future code readers are better served by that.
It seems to me the "Not Rocket Science" invariant is upheld if you just require all PRs to be fast-forward changes. Which I guess is an argument in support of rebase, but a clean merge counts too. If the test suite passes on the PR branch, it'll pass on main, because that's what main will be afterward. Ideally you don't even test the same commit hash twice.
If you have expensive e2e tests, then you might want to keep a 'latest' tag on main that's only updated when those pass.
In mercurial you could have those in phase hidden for future reference.
In jujutsu you can have those in a local set, but not push upstream. Only unfortunate thing with jujutsu is because it is trying to be a git overlay, you lose state that a mercurial clone on another machine would have.
e.g. I'm currently working on a substantial framework upgrade to a project - I've pulled every dependency/blocker out that could be done on its own and made separate PRs for them, but I'm still left with a number of logically independent commits that by their nature will not compile on their own. I could squash e.g. "Update core framework", "Fix for new syntax rules" and "Update to async methods without locking", but I don't know that reviewers and future code readers are better served by that.