Bird
Raised Fist0
Gitdevops~15 mins

pre-push hook in Git - Deep Dive

Choose your learning style10 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.

Practice

(1/5)
1. What is the main purpose of a pre-push hook in Git?
easy
A. To delete local branches after pushing
B. To merge branches automatically before pushing
C. To run checks or tests before code is pushed to a remote repository
D. To create a backup of the repository before pushing

Solution

  1. Step 1: Understand the role of pre-push hooks

    Pre-push hooks run scripts before pushing code to a remote repository to catch errors early.
  2. Step 2: Identify the correct purpose

    They help ensure code quality by running tests or checks before the push happens.
  3. Final Answer:

    To run checks or tests before code is pushed to a remote repository -> Option C
  4. Quick Check:

    Pre-push hook = run checks before push [OK]
Hint: Pre-push hooks run before push to catch problems early [OK]
Common Mistakes:
  • Confusing pre-push with post-push hooks
  • Thinking it merges branches automatically
  • Assuming it deletes branches
2. Which of the following is the correct way to make a pre-push hook script executable on Linux or macOS?
easy
A. chmod +x .git/hooks/pre-push
B. git enable pre-push
C. chmod 777 .git/hooks/pre-push
D. git hook activate pre-push

Solution

  1. Step 1: Identify how to make scripts executable

    On Linux/macOS, chmod +x sets execute permission on a file.
  2. Step 2: Apply to pre-push hook

    Running chmod +x .git/hooks/pre-push makes the hook script runnable by Git.
  3. Final Answer:

    chmod +x .git/hooks/pre-push -> Option A
  4. Quick Check:

    Make hook executable = chmod +x [OK]
Hint: Use chmod +x to make hook scripts executable [OK]
Common Mistakes:
  • Using git commands that don't exist for hooks
  • Setting overly permissive permissions like 777
  • Forgetting to make the script executable
3. Given this pre-push hook script snippet, what will happen if the tests fail?
#!/bin/sh
npm test || exit 1
medium
A. The push will continue regardless of test results
B. The script will delete the remote branch
C. The tests will be skipped
D. The push will be blocked and stopped

Solution

  1. Step 1: Understand the script logic

    The script runs npm test. If tests fail, npm test returns non-zero, triggering exit 1.
  2. Step 2: Effect of exit 1 in pre-push hook

    Exiting with a non-zero code stops the push process, blocking the push.
  3. Final Answer:

    The push will be blocked and stopped -> Option D
  4. Quick Check:

    Exit 1 in pre-push = block push [OK]
Hint: Exit non-zero in pre-push stops the push [OK]
Common Mistakes:
  • Assuming push continues even if tests fail
  • Thinking tests are skipped automatically
  • Confusing exit codes with success
4. You wrote a pre-push hook script but it does not run when you push. What is the most likely cause?
medium
A. The remote repository is down
B. The script is missing execute permissions
C. You forgot to commit your changes
D. The branch name is incorrect

Solution

  1. Step 1: Check script execution requirements

    Git requires hook scripts to have execute permission to run them.
  2. Step 2: Identify common cause of hook not running

    If the script lacks execute permission, Git silently skips running it.
  3. Final Answer:

    The script is missing execute permissions -> Option B
  4. Quick Check:

    Missing execute permission = hook won't run [OK]
Hint: Check execute permission if hook doesn't run [OK]
Common Mistakes:
  • Blaming remote repository for local hook issues
  • Thinking commit status affects hook execution
  • Assuming branch name affects hook running
5. You want your pre-push hook to run tests only on files changed in the last commit before pushing. Which approach is best?
hard
A. Use git diff --name-only HEAD~1 HEAD inside the hook to get changed files and run tests accordingly
B. Run tests on all files every time without checking changes
C. Manually list files in the hook script each time
D. Push first, then run tests on the remote repository

Solution

  1. Step 1: Identify how to detect changed files

    The command git diff --name-only HEAD~1 HEAD lists files changed in the last commit.
  2. Step 2: Use this command in pre-push hook

    Using this inside the hook lets you run tests only on changed files, saving time and resources.
  3. Final Answer:

    Use git diff --name-only HEAD~1 HEAD inside the hook to get changed files and run tests accordingly -> Option A
  4. Quick Check:

    Detect changed files with git diff for selective tests [OK]
Hint: Use git diff to find changed files for selective tests [OK]
Common Mistakes:
  • Running tests on all files unnecessarily
  • Manually updating file lists each time
  • Running tests after push instead of before
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard