iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Git hooks are executable scripts that run at specific points in Git workflows, such as before a commit or push. They are useful for quick local feedback—formatting staged changes, checking a commit message, or running a focused test—but they are not reliable policy enforcement: clones do not include client-side hooks, and some hooks can be bypassed. Use them to help contributors catch problems early, and run mandatory checks in CI or on a trusted Git server.
What Git hooks do
A Git hook is an executable program associated with a repository event. Git runs the corresponding hook when that event occurs; a hook can inspect repository state, run a check, or perform a follow-up action. As Git’s official hooks manual puts it, “Hooks are programs you can place in a hooks directory to trigger actions at certain points in git’s execution.”
Git normally looks for hooks in $GIT_DIR/hooks. The hook file must be executable; a file with the right name but without executable permissions is ignored. The core.hooksPath setting can redirect Git to a different directory.
Which hook should run a check?
Choose the hook based on when the check needs to happen and whether it must be able to stop the action. Hook inputs and behavior vary by event, so consult the manual for the specific hook before relying on its arguments or repository state.
#1 Best Overall
| Hook | When it runs | What it is suited for | Can it stop the action? |
|---|---|---|---|
pre-commit |
Before Git obtains the proposed commit message and creates the commit. | Quick checks such as formatting, linting staged changes, or a focused test. | Yes. A nonzero exit aborts the commit. It can be bypassed with --no-verify. |
prepare-commit-msg |
After Git prepares the default commit message and before the editor opens. | Editing or preparing the message file. | It runs despite --no-verify; do not confuse it with pre-commit. |
commit-msg |
After the message is prepared, with the message-file path passed to the hook. | Checking or editing commit-message format. | Yes. A nonzero exit aborts the commit. It can be bypassed with --no-verify. |
post-commit |
After the commit has been made. | Notifications or other follow-up work. | No. The commit has already succeeded. |
pre-push |
Before Git sends proposed refs to a remote. | Checks that are too expensive to run on every commit, if appropriate for the project. | Yes. It can prevent the push. |
pre-receive and update |
On the receiving repository during an update. | Server-side checks and rules that must apply to incoming changes. | Yes. These hooks can reject updates. |
The full event sequence and each hook’s inputs are documented in the Git hooks manual. In particular, a post-event hook cannot prevent an action that has already completed.
How to create a basic pre-commit hook
For a personal check or a simple experiment, create a file named pre-commit in the repository’s active hooks directory. With Git’s default location, that is .git/hooks/pre-commit in an ordinary repository. The example below blocks a commit if whitespace errors are found in the staged diff:
Rank #2
#!/bin/sh
git diff --cached --check
- Save the script as
.git/hooks/pre-commit. - Make it executable, for example with
chmod +x .git/hooks/pre-commit. - Stage a change and run
git commit. If the check exits with a nonzero status, Git aborts the commit; fix the reported issue and try again.
This example uses Git’s default hooks directory. If core.hooksPath is configured, put the hook in that configured directory instead. Git’s configuration documentation describes the setting. For more complex scripts, check whether commands inspect staged content or the working tree: those can differ when a developer has both staged and unstaged changes.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How to share hooks with a team
A normal clone does not copy client-side hooks into the new repository. A hook committed to a project’s files therefore does not automatically become an active hook for every contributor. A team needs an installation step, a checked-in hook manager and configuration, or another setup mechanism.
Git offers a native route: configure core.hooksPath to point to a shared hooks directory. Git also documents the git hook command for listing configured hooks and running them, as well as named hook commands associated with events. See the command manual and core.hooksPath documentation. Git notes that hooks accessing shared state may be restricted to sequential execution, so do not assume they can safely run in parallel.
Hook managers can make installation and configuration more repeatable. Their workflows differ; choose based on your project’s languages, onboarding needs, file targeting, platforms, and maintenance preferences—not a universal performance claim.
| Approach | Useful when | Tradeoffs |
|---|---|---|
Raw scripts in .git/hooks |
You need a personal check or a minimal setup. | Smallest setup, but installation and distribution are local concerns, and the executable bit is required. Git’s manual describes hook files and locations. |
core.hooksPath or Git named-hook configuration |
You want to use Git’s own configuration to locate or register hooks. | Native to Git, but the team must understand configuration scope and how each developer gets the setup. See the configuration docs and git hook manual. |
| pre-commit | You want declarative hooks and support for a range of hook languages. | Its configuration supports file and type selection, fail-fast behavior, and serial execution; the runtime environment depends on the selected hook language. |
| Husky | You have a JavaScript or Node project and want hooks integrated with project setup. | Its documentation covers core.hooksPath, cross-platform support, commit-message checks, and code checks. Follow the installation instructions for your project. |
| Lefthook | You want YAML-configured jobs and commands matched to files. | Its examples include parallel jobs and staged-file targeting; installation may use a project or system package manager. |
Before adopting a manager, confirm that a fresh-clone setup works on the platforms your team uses, that checks target the intended files, and that the required checks also run in CI.
Can Git hooks enforce code quality?
Client-side hooks are best treated as convenience and early feedback, not as a guarantee. Git does not install them through a normal clone, and pre-commit and commit-msg can be skipped with --no-verify. The prepare-commit-msg hook is an exception to that particular bypass flag, but relying on it does not solve the broader distribution and enforcement problem.
Best Value
When a rule must apply regardless of a contributor’s local setup, run the check in CI or enforce it with server-side hooks such as pre-receive or update. Pro Git’s hooks chapter recommends server-side enforcement when the goal is to enforce a policy.
Quick Recap
Keep hooks useful and safe
- Keep commit-time checks focused. Run fast, actionable checks before a commit; consider
pre-pushfor suitable checks that take longer. Git’s documentation establishes when these events run, not a universal runtime target. - Make failures clear. Say which command failed and what the contributor can do to fix it.
- Inspect installers and scripts. A project-provided hook installer runs code on a contributor’s machine; understand what it executes before enabling it.
- Do not rely on post-event hooks for rejection. Once a post-commit hook starts, the commit already exists.
- Read the event-specific contract. Git hooks can receive different arguments, standard input, and working-directory behavior. Use the relevant section of the manual rather than assuming all hooks behave alike.
- Repeat mandatory checks in a trusted place. Local hooks improve feedback; CI or server-side controls provide enforcement.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

