Comment by candiddevmike
11 hours ago
I struggle to see value with git hooks. They're an opt-in, easily opt-out way of calling shell scripts from my understanding--you can't force folks to run them, and they don't integrate/display nicely with CI/CD.
Why not just call a shell script directly? How would you use these with a CI/CD platform?
I tend to work the other way around - what is defined in CI steps gets added to pre-commit. Several tools have already existing configurations or you can use local mode. Sure, I can't force people to use it but it saves them time as CI would fail anyway.
This might be a me problem but I extensively manipulate the git history all the time which makes me loathe git hooks. A commit should take milliseconds, not a minute.
it’s not just you.
i regularly edit history of PRs for a variety of reasons and avoid pre-commit when possible.
put it all in CI thank you please — gimme a big red X on my pipeline publicly telling me i’ve forgotten to do something considered important.
You do seem to be doing it wrong. Extensive manipulation of the record and slow hooks are both undesirable.
I would reckon cleaning up your branch before opening a pull request is good practice. I also rebase a lot, aswell as git reset, and I use wip commits.
Slow hooks are also not a problem in projects I manage as I don't use them.
6 replies →
They're very commonly used in CI. There are dedicated GitHub actions for pre-commit and prek, but most commonly people just invoke something like `prek run --all-files` or `pre-commit run --all-files` in their typical lint CI jobs.
The prek documentation has a list of many large projects (such as CPython and FastAPI, to name a few) who use it; each link is a PR of how they integrated it into CI if you want to see more: https://prek.j178.dev/#who-is-using-prek
You can obviously bypass them, but having precommit hooks to run scripts locally, to make sure certain checks pass, can save them from failing in your pipeline, which can save time and money.
From an org standpoint you can have them (mandate?) as part of the developer experience.
(Our team doesn't use them, but I can see the potential value)
I never understood this argument.
The checks in those pre-commit hooks would need to be very fast - otherwise they'd be too slow to run on every commit.
Then why would it save time and money if they only get run at the pipeline stage? That would only save substantial time if the pipepline is architected in a suboptimal way: Those checks should get run immediately on push, and first in the pipeline so the make the pipeline fail fast if they don't pass. Instant Slack notification on fail.
But the fastest feedback is obviously in the editor, where such checks like linting / auto-formatting belong, IMHO. There I can see what gets changed, and react to it.
Pre-commit hooks sit in such a weird place between where I author my code (editor) and the last line of defense (CI).
> Then why would it save time and money if they only get run at the pipeline stage? That would only save substantial time if the pipepline is architected in a suboptimal way: Those checks should get run immediately on push, and first in the pipeline so the make the pipeline fail fast if they don't pass. Instant Slack notification on fail.
That's still multiple minutes compared to an error thrown on push - i.e. long enough for the dev in question to create a PR, start another task, and then leave the PR open with CI failures for days afterwards.
> But the fastest feedback is obviously in the editor, where such checks like linting / auto-formatting belong, IMHO.
There are substantial chunk of fast checks that can't be configured in <arbitrary editor> or that require a disproportionate time investment. (e.g. you could write and maintain a Visual Studio extension vs just adding a line to grep for pre-commit)
I think there's value in git hooks, but pre-commit is the wrong hook. This belongs in a hook that runs on attempted push, not on commit.
There's a config option for that :) https://prek.j178.dev/configuration/#default_install_hook_ty...
"pre-commit the tool" supports the pre-push hook (as well as the various other hooks).
formatting should definitely be in pre-commit though, otherwise you'll destroy diffs.
Run the light ones on commit, the heavy ones on push.
They integrate well with CI.
You run the same hooks in CI as locally so it's DRY and pushes people to use the hooks locally to get the early feedback instead of failing in CI.
Hooks without CI are less useful since they will be constantly broken.
Why wouldn't I just call the same shell script in CI and locally though? What's the benefit here? All I'm seeing is circular logic.
The pre-commit tool (which prek is based on) has a large ecosystem of off the shelf checks for various language linters and other checks and a convenient way of writing them (including working out which files have changed and which checks to run based off of that)
The benefit to many of having them as a hook is that you discover it's broken before you pushed your changes, and not when you finally get around to checking the CI on your branch and realising it failed after 30s.
There is of course no reason why you have to have it installed as a precommit hook - many people prefer to run it manually, and the pre-commit tool/prek allows for that.
If you had a shell script hook, yes you would also run that in CI.
Are you asking what advantage pre-commit has over a shell script?
Mostly just functionality: running multiple hooks, running them in parallel, deciding which hooks to run based on the commit files, "decoding" the commit to a list of files, offering a bunch canned hooks, offering the ability to write and install non-shell hooks in a standard way.
The point is enforcement. If there's a newcomer to developing your repo, you can ask them to install the hooks and from thereon everything they commit will be compatible with the processes in your CI. You don't need to manually run the scripts they'll run automatically as part of the commit or push or whatever process
pre-commit provides a convenient way to organize running a collection of shell scripts.
Yes, you can run the CI script locally so you detect errors faster.
The value is in finding out something is going to fail locally before pushing it. Useful for agents and humans alike.
Besides during commit, pre-commit/prek can run all hooks with `run`. So in CI/CD you can replace all discrete lint/format tool calls with one to pre-commit/prek. E.g. https://github.com/python/cpython/blob/main/.github/workflow....
This just seems like calling a shell script with extra steps.
I have a shell utility similar to make that CI/CD calls for each step (like for step build, run make build) that abstracts stuff. I'd have Prek call this tool, I guess, but then I don't get what benefit there is here.
I like my pre-receive hooks.