Do Git hooks ring a bell? Or maybe you'd rather watch the CI break on every commit because the dev didn't test on their machine?
Protecting your branches is good. Protecting your CI too. But you can go even faster: by forcing the developer to test their application, whether they like it or not.
What a hook actually is
A Git hook is a script that Git triggers automatically at a precise point in a repository's lifecycle: before a commit (pre-commit), before writing the message (prepare-commit-msg), before a push (pre-push), after a merge (post-merge)… The most useful one day to day is pre-commit: it runs right before the commit is recorded, and if it fails, the commit doesn't happen.
The idea fits in one sentence: at commit time, bam, a script fires to test everything. Lint, typecheck, unit tests — whatever you want. If something breaks, the commit is rejected and the dev fixes it before the code reaches the branch.
Why it speeds up your deployments
Without a hook, the classic scenario is familiar: the dev commits, pushes, and it's the CI that discovers the tests are broken — ten minutes later, with a red pipeline and one more round trip. With a pre-commit, the error is caught on the machine, in a few seconds, before it even leaves.
A pre-commit Git hook that runs the tests turns the CI into a confirmation rather than a discovery: the code that reaches the branch has already passed the tests locally, so the pipeline breaks far less often. Fewer round trips, faster deployments.
You don't drop the CI for it
Beware the misreading: the hook does not replace the CI. First because a hook is bypassable — one --no-verify and it's skipped. Second because it runs in the dev's environment, which is not the reference environment: different versions, local env variables, dependencies not quite up to date.
So the hook and the CI don't play the same role: the hook is a fast net on the developer's side that catches most errors before the push; the CI remains the final authority, in a clean and non-bypassable environment. It's a little extra that secures your code and speeds up your deployments — not a substitute.
Of course… for any of this to be worth it, your projects still need tests to run 🙂.
With Singularity, setup is simplified
Writing a hook by hand stays thankless: you need the right filename, you have to make it executable, manage the runtime (Husky, custom scripts…), and not mess up the shell. That's exactly why hooks are so underused despite being so powerful.
In Singularity, a dedicated menu in the Git interface gives you direct access to the hooks. You see the full list — pre-commit, prepare-commit-msg, commit-msg, post-commit, pre-rebase, pre-push… — the detected runtime (Husky, for example), and the content of each script, editable on the spot.
pre-commit script open on the right, ready to edit.And if shell scripting puts you off: let the AI generate it
For many people the real blocker isn't the idea of the hook — it's writing the script. Singularity removes that friction: you describe what you want in plain language — "run the tests before every commit and reject it if a test fails" — and an AI agent generates the hook for you.
You get a readable, versioned script that you stay free to edit or refine. If Git hooks make you nervous, that's exactly the nudge that gets you over the line: the protection of a pre-commit without writing a line of shell.
In short
Protect your branches, protect your CI, and — on top — force tests at commit time with a Git hook: three nets that complement each other. The hook speeds things up because it catches the error as early as possible; the CI stays the final authority because it can't be bypassed. Singularity gives you the menu to manage your hooks, and the AI to write them for you.
Intrigued? Come try it. It's free.
Frequently asked questions
What is a pre-commit Git hook?
It's a script that Git runs automatically right before recording a commit. You typically put lint, typecheck and tests there: if any of them fails, the commit is rejected and the developer fixes it before the code reaches the branch. It's the most useful safety net day to day.
Does a Git hook replace the CI?
No. A hook is bypassable (for example with --no-verify) and runs in the developer's environment, which is not the reference environment. It catches most errors before the push and speeds up deployments, but the CI remains the final authority, in a clean and non-bypassable environment. The two are complementary.
How does Singularity help set up hooks?
Singularity offers a dedicated menu in its Git interface: it lists every hook (pre-commit, pre-push, commit-msg…), detects the runtime in use (Husky, for example) and shows the content of each script, editable on the spot. No more hunting for the right file or managing the runtime by hand.
Can an AI generate a Git hook in Singularity?
Yes. You describe in plain language what the hook should do — for example "run the tests before every commit and reject it if a test fails" — and an AI agent generates the script for you. You get a readable, versioned hook that you remain free to edit. It's handy if shell scripting makes you nervous.
Do you need tests for a pre-commit hook to be worth it?
Yes. A hook that runs the tests is only useful if the project actually has tests to run. Without tests, the hook can still run lint and typecheck, but most of the protection comes from the test suite. Having tests remains the prerequisite.