0
0
Gitdevops~15 mins

pre-push hook in Git - Deep Dive

Choose your learning style9 modes available
Overview - pre-push hook
What is it?
A pre-push hook is a script that runs automatically before you push your code changes to a remote repository. It lets you check or test your code to catch problems early. If the hook finds an issue, it can stop the push to prevent bad code from going out. This helps keep the shared code safe and clean.
Why it matters
Without pre-push hooks, developers might push broken or untested code that causes bugs or breaks the project for everyone else. This can slow down work and cause frustration. Pre-push hooks act like a safety net, catching mistakes before they spread. They save time and keep the project healthy.
Where it fits
Before learning pre-push hooks, you should understand basic Git commands like commit and push. After mastering pre-push hooks, you can explore other Git hooks like pre-commit or post-merge, and learn how to automate testing and code quality checks in your workflow.
Mental Model
Core Idea
A pre-push hook is a checkpoint that automatically tests or verifies your code right before it leaves your computer to join the shared project.
Think of it like...
It's like a security guard checking your luggage before you board a plane, making sure nothing dangerous or forbidden gets on board.
Local Repo ──▶ [Pre-push Hook: Checks/tests code] ──▶ Remote Repo

If hook fails: push stops here
If hook passes: push continues
Build-Up - 6 Steps
1
FoundationWhat is a Git hook?
🤔
Concept: Git hooks are scripts that run automatically at certain points in Git operations.
Git hooks live inside the .git/hooks folder of a repository. They are small programs or scripts that Git runs when specific events happen, like committing or pushing. They help automate checks or tasks.
Result
You learn that Git can run custom scripts automatically during your workflow.
Understanding Git hooks opens the door to automating quality checks and custom behaviors in your development process.
2
FoundationWhere pre-push hook fits in Git flow
🤔
Concept: The pre-push hook runs right before Git sends your commits to the remote repository.
When you run 'git push', Git first runs the pre-push hook script if it exists. If the script exits with success, the push continues. If it exits with failure, the push stops.
Result
You see that pre-push hooks act as a gatekeeper before code leaves your local machine.
Knowing when the pre-push hook runs helps you place checks exactly where they can prevent bad code from spreading.
3
IntermediateCreating a simple pre-push hook script
🤔Before reading on: do you think a pre-push hook can stop a push if tests fail? Commit to your answer.
Concept: You can write a script that runs tests and stops the push if tests fail.
Inside .git/hooks, create a file named 'pre-push' with executable permissions. For example, a bash script: #!/bin/sh npm test || exit 1 This runs tests with 'npm test'. If tests fail, exit 1 stops the push.
Result
When you push, tests run first. If tests fail, push is blocked.
Using pre-push hooks to run tests prevents broken code from reaching the shared repository.
4
IntermediatePassing information to pre-push hooks
🤔Before reading on: do you think pre-push hooks receive details about what is being pushed? Commit your guess.
Concept: Pre-push hooks receive information about the refs and commits being pushed via standard input.
Git passes lines with local and remote refs to the pre-push hook on stdin. You can read these lines to know what branches or commits are involved. This lets you customize checks based on what is pushed.
Result
You can write smarter hooks that react differently depending on the pushed content.
Knowing the input format lets you build flexible hooks that adapt to different push scenarios.
5
AdvancedSharing pre-push hooks across teams
🤔Before reading on: do you think Git automatically shares hooks with collaborators? Commit your answer.
Concept: Git does not share hooks automatically; you must distribute them manually or via scripts.
Hooks live only in the local .git folder and are not pushed. To share hooks, teams use scripts or tools like Husky (for JavaScript) that install hooks on each developer's machine automatically.
Result
Teams can enforce consistent checks by distributing hooks properly.
Understanding hook distribution prevents confusion about why hooks don't run on others' machines.
6
ExpertPerformance and pitfalls of pre-push hooks
🤔Before reading on: do you think slow pre-push hooks affect developer productivity? Commit your opinion.
Concept: Pre-push hooks run synchronously and can delay pushes if slow or complex.
If hooks run long tests or heavy tasks, developers wait longer to push. This can cause frustration and lead to bypassing hooks. Experts balance thoroughness with speed, sometimes running full tests in CI instead.
Result
You learn to design hooks that are fast and effective, improving workflow without blocking developers unnecessarily.
Knowing the tradeoff between thorough checks and speed helps maintain developer happiness and code quality.
Under the Hood
When you run 'git push', Git looks for a 'pre-push' executable script in .git/hooks. If found, Git runs this script and waits for it to finish. The script can read information about what is being pushed from standard input. If the script exits with code 0, Git continues the push. If it exits with any other code, Git aborts the push. This mechanism allows the script to approve or reject the push based on custom logic.
Why designed this way?
Git hooks were designed as simple executable scripts to allow maximum flexibility across platforms and languages. Using exit codes to control flow is a standard Unix pattern. This design avoids complex APIs and lets users write hooks in any language. The hooks run locally to catch issues early before network operations.
┌───────────────┐
│ git push cmd  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ pre-push hook │
│ (script runs) │
└──────┬────────┘
       │ exit 0 (success) → push continues
       │ exit !=0 (fail) → push aborted
       ▼
┌───────────────┐
│ remote repo   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Git automatically share your pre-push hooks with your teammates? Commit yes or no before reading on.
Common Belief:Git hooks like pre-push are shared automatically when you push your code.
Tap to reveal reality
Reality:Git hooks live only in your local .git folder and are not pushed or shared with others.
Why it matters:If you assume hooks are shared, you might think your team is protected by your checks when they are not, leading to inconsistent code quality.
Quick: Can a pre-push hook run after the push has completed? Commit yes or no before reading on.
Common Belief:Pre-push hooks run after the code has been pushed to the remote repository.
Tap to reveal reality
Reality:Pre-push hooks run before any data is sent to the remote, blocking the push if needed.
Why it matters:Misunderstanding this can cause confusion about when checks happen and why a push might be blocked.
Quick: Do pre-push hooks run on the remote server? Commit yes or no before reading on.
Common Belief:Pre-push hooks run on the remote repository server to check incoming pushes.
Tap to reveal reality
Reality:Pre-push hooks run only on the local machine before pushing; server-side checks use different hooks like pre-receive.
Why it matters:Confusing local and server hooks can lead to misplaced trust in checks and security gaps.
Quick: Is it safe to run very long tests in a pre-push hook? Commit yes or no before reading on.
Common Belief:Running all tests in a pre-push hook is always good to catch every problem.
Tap to reveal reality
Reality:Long-running hooks slow down pushes and frustrate developers, sometimes causing them to skip hooks.
Why it matters:Balancing test coverage and speed is crucial to keep hooks effective and developers happy.
Expert Zone
1
Pre-push hooks can read the refs being pushed from stdin, allowing conditional checks based on branch or commit range.
2
Hooks run with the user's environment, so differences in local setup can cause inconsistent behavior across machines.
3
Using tools like Husky or custom scripts to install hooks ensures team-wide consistency and reduces manual errors.
When NOT to use
Avoid using pre-push hooks for very long or resource-heavy tests; instead, run those in continuous integration pipelines. Also, do not rely on pre-push hooks for security checks that must run on the server side; use server-side hooks or protected branches instead.
Production Patterns
Teams often use pre-push hooks to run quick linters or smoke tests locally, combined with CI pipelines for full test suites. Hooks are distributed via package managers or setup scripts to ensure all developers have the same checks. Some projects use pre-push hooks to prevent pushes to protected branches or to enforce commit message formats.
Connections
Continuous Integration (CI)
Builds-on
Pre-push hooks catch issues early on the developer's machine, while CI runs full tests on servers after code is pushed, creating a layered defense.
Unix exit codes
Same pattern
Pre-push hooks use exit codes to signal success or failure, a common Unix pattern that controls program flow and automation.
Airport security checks
Similar process
Just like airport security stops dangerous items before boarding, pre-push hooks stop bad code before it reaches the shared project.
Common Pitfalls
#1Assuming hooks are shared automatically with the team.
Wrong approach:Relying on .git/hooks/pre-push without distributing it; expecting teammates to have the same hook.
Correct approach:Use a tool like Husky or include hook installation scripts in the project to ensure all developers install the pre-push hook.
Root cause:Misunderstanding that Git does not push or share hooks with the repository.
#2Writing a pre-push hook that runs very slow tests.
Wrong approach:#!/bin/sh npm run full-test-suite exit $? # full-test-suite takes 30+ minutes
Correct approach:#!/bin/sh npm run quick-lint exit $? # quick-lint runs in seconds
Root cause:Not balancing thoroughness with developer productivity, causing frustration and bypassing.
#3Ignoring the exit code in the hook script.
Wrong approach:#!/bin/sh npm test # no exit code check, always exits 0
Correct approach:#!/bin/sh npm test || exit 1 # exit 1 stops push if tests fail
Root cause:Not understanding that Git uses the script's exit code to decide whether to continue or abort the push.
Key Takeaways
Pre-push hooks run automatically before code is pushed to a remote repository, acting as a gatekeeper.
They help catch errors or enforce rules early, preventing broken code from spreading to others.
Hooks are local scripts and are not shared automatically; teams must distribute them explicitly.
Balancing the thoroughness and speed of pre-push hooks is key to keeping developers productive and code quality high.
Pre-push hooks complement, but do not replace, server-side checks and continuous integration pipelines.