I agree that running expensive operation on commit doesn't make a lot of sense (temp commits and whatnot), but it's nice to bail out quickly before pushing.
for small repos, running linters and such on pre-push is great because you definitely don't have unlimited CI agents, so a lag of 10 seconds for a "git push" might mean you actually gain 30 minutes and not wait for an agent to be available and you also save your team some good minutes with a silly CI job failing with "missing whitespace".
PS: if you want to skip the pre-push hook once in a while, just run "git push --no-verify"
This is both very fast locally and very accurate. Plus, a dev that didn't bother to install pre-commit won't ruin the entire codebase, they will instead have to go through lengthy fix/push/wait/refix cycles, so they're incentivized to install pre-commit locally to run the linters quickly.
The other way - committing, pushing, waiting on the CI, just to see the pipeline fail when all you want is to get a hotfix out to the server... it would make me furious.
The one without hooks is so much better in my opinion. Sure, once in a while you forget to run the linter and the CI fails, but its worth it if the alternative is to have every git commit you ever make take 5 seconds and every git push take 30 seconds (our test suite is slow).