Hacker News new | ask | show | jobs
by huntedsnark 2510 days ago
This seems so backwards to me. Why not do it as part of your CI process where you're not foisting unnecessary tooling on your developers local machines? The lag involved in spinning up and running the commit hooks is noticeable and disruptive especially if you commit often and rebase locally.
6 comments

Having to wait for your CI to tell you that you've done something wrong takes a lot longer than a pre-commit/pre-push hook.

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.

the article talks about pre-commit hook, but nobody stops you from running these checks as pre-push hook. and nobody says you need to run the all the checks that you'd normally run on CI, but just enough checks to get past the silly errors.

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"

Having to wait 30 mins for a build to run sounds like the real issue here. How would you push out an an emergency release in a timely way for example?
In a real emergency situation, there are all sorts of solutions to get a fix out and fast. But that almost never happens, thus it's not something to optimize for.
That may also depend on how many commits wait in the line. If team is large or monorepo, you need to wait for all pushes to pass in order for your own push to be tested which might take a long time even if single test is fairly fast.
I generally do it on both stages. I run pre-commit (the Python project) locally on just the files that changed, which catches 99% of problems, reformats things with Black, etc. Then, I run pre-commit again on CI, but this time it goes through all files, which catches any problems that might have fallen through initially.

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.

I disagree. You don't need to run the commit-hook on all files, just on the files you changed. It shouldn't take more than to write the commit message (and I wonder if there is a way to run the git hook right when you type the commit message). And you still should do the same checks for all files in your CI.

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.

We have two projects. In one, we have no hooks and just have CI fail if the tests fail or you forgot to lint. The other one has a commit hook to lint and a unit test hook on push.

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).

One example of the use case, which the article hits on, is open source. Most open source projects are relying on free CI resources, tying them up doing linting is a waste and can be rather annoying when you're doing important core work but find there is a deep queue of CI jobs full of stuff that is likely to fail linting or other basic checks.