codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
📦

Git & GitHub

19 / 63 topics
13Working with Remote Repositories14Using git fetch15Using git pull16Using git push17Using git clone18Using Submodules19Git Hooks
Tutorials/Git & GitHub/Git Hooks
📦Git & GitHub

Git Hooks

Updated 2026-04-20
3 min read

Git Hooks

Git hooks are scripts that run automatically every time a specific event occurs in your Git repository. They provide a powerful way to enforce coding standards, automate tasks, and integrate with other tools. In this tutorial, we'll explore the different types of Git hooks, how they work, and best practices for using them effectively.

Understanding Git Hooks

Git hooks are scripts that reside in the .git/hooks directory of your repository. They are written in any scripting language you prefer (e.g., Bash, Python, Ruby) and can be executed at various stages of the Git workflow. There are two main types of hooks:

  1. Client-Side Hooks: These run on the local machine where changes are being made.
  2. Server-Side Hooks: These run on the remote server after receiving a push.

Client-Side Hooks

Client-side hooks are triggered by actions performed locally, such as committing or pushing code. They can be used to validate changes before they are committed or pushed.

Common Client-Side Hooks

  • pre-commit: Runs before a commit is finalized.
  • prepare-commit-msg: Allows you to edit the default commit message.
  • commit-msg: Validates the commit message.
  • post-commit: Runs after a commit is made.
  • pre-rebase: Runs before a rebase operation starts.
  • post-checkout: Runs after switching branches or checking out files.
  • post-merge: Runs after a merge operation.

Example: pre-commit Hook

Let's create a pre-commit hook to ensure that all code changes are formatted according to Prettier standards before committing.

  1. Navigate to your repository's .git/hooks directory.
  2. Create a new file named pre-commit.
  3. Add the following content:
#!/bin/bash

# Run Prettier on staged files
npx prettier --write $(git diff --cached --name-only)

# Check if there are any changes after formatting
if ! git diff-index --quiet HEAD --; then
  echo "Prettier has reformatted your code. Please review and commit again."
  exit 1
fi

echo "Commit is clean. Proceeding..."
exit 0
  1. Make the script executable:
chmod +x .git/hooks/pre-commit

Now, every time you attempt to commit changes, Prettier will automatically format your code. If there are any changes after formatting, Git will prevent the commit and prompt you to review them.

Server-Side Hooks

Server-side hooks run on the remote server after receiving a push. They can be used to enforce rules about what gets accepted into the repository.

Common Server-Side Hooks

  • pre-receive: Runs before any refs are updated.
  • update: Runs once for each ref that is being updated.
  • post-receive: Runs after all refs have been updated.

Example: pre-receive Hook

Let's create a pre-receive hook to prevent the merging of feature branches directly into the main branch.

  1. On your remote server, navigate to the .git/hooks directory of your repository.
  2. Create a new file named pre-receive.
  3. Add the following content:
#!/bin/bash

# Read from standard input
while read oldrev newrev refname; do
  # Check if the push is to the main branch
  if [[ "$refname" == "refs/heads/main" ]]; then
    # Get the list of branches being pushed
    branches=$(git for-each-ref --format='%(refname:short)' refs/heads/)
    
    # Check if any feature branch is being merged directly into main
    for branch in $branches; do
      if [[ "$branch" == "feature/*" ]]; then
        echo "Error: Direct merging of feature branches into main is not allowed."
        exit 1
      fi
    done
  fi
done

echo "Push accepted."
exit 0
  1. Make the script executable:
chmod +x .git/hooks/pre-receive

Now, any attempt to merge a feature branch directly into the main branch will be rejected.

Best Practices for Using Git Hooks

  1. Keep Hooks Simple: Avoid complex logic in hooks to prevent unintended side effects.
  2. Document Hooks Clearly: Document what each hook does and how it should be used.
  3. Test Hooks Thoroughly: Test hooks in a development environment before deploying them to production.
  4. Use Shared Hooks: Store common hooks in a shared location and symlink them into individual repositories.
  5. Handle Errors Gracefully: Ensure that hooks exit with appropriate error codes and provide meaningful feedback.

Conclusion

Git hooks are a powerful feature of Git that can significantly enhance your workflow by automating tasks, enforcing standards, and integrating with other tools. By understanding the different types of hooks and best practices for using them, you can create a more efficient and reliable development process. Remember to always test and document your hooks to ensure they work as expected.

In the next section of our Git & GitHub course, we'll explore advanced Git workflows and strategies for managing large repositories. Stay tuned!


PreviousUsing SubmodulesNext Introduction to GitHub

Recommended Gear

Using SubmodulesIntroduction to GitHub