Git Hooked

 A Tour of the .git/hooks Directory

Key Hooks by Category

  • Category 1: Client-Side: Local Workflow

    • pre-commit: Runs before a commit is created. Use for linting, formatting, security scans.

    • prepare-commit-msg: Runs before the commit message editor opens. Use for templating messages.

    • commit-msg: Runs after the message is written. Use for validating the message format.

    • post-commit: Runs after a commit is successfully created. Use for notifications.

  • Category 2: Client-Side: Pushing Code

    • pre-push: Runs before git push. Use for running tests, ensuring you're not pushing broken code.

  • Category 3: Client-Side: Workflow Events

    • post-merge: Runs after a successful merge. Use for installing dependencies, rebuilding caches.

Lab 1 - Hello, Hook!

  • Objective: Create a basic pre-commit hook that blocks a commit based on a simple condition.

The Hook Lifecycle

git add files -> [HOOK: pre-commit] [HOOK: prepare-commit-msg] -> Commit Editor Opens -> [HOOK: commit-msg] -> Commit is created -> Developer Action: git push -> [HOOK: pre-push] -> Code sent to Remote -> Developer Action: git merge other-branch -> [HOOK: post-merge]

The Commit Part

  • pre-commit: "Is this code good enough to commit?"

  • prepare-commit-msg: "Can I help you write a better message?"

  • commit-msg: "Does this message meet our team's standards?"

The Networking Part

  • Focus on the push portion of the diagram.

  • pre-push: "Are we absolutely sure this is ready to be shared with the team?" This is your last chance to stop a mistake on your local machine.

  • Use Case: Since it runs less frequently than pre-commit, it's the perfect place for slightly slower checks, like running a critical subset of unit tests.

The Workflow Lifecycle

  • Focus on the merge portion of the diagram.

  • post-merge: "Now that we've brought in new code, does our environment need any cleanup or setup?" It runs after a successful merge.

  • Use Case: Automatically run npm install if package.json changed, or pip install -r requirements.txt if requirements.txt changed. A huge quality-of-life improvement.

Lab 2 - The Guardian

  • Objective: Write a pre-commit hook that runs a linter on staged files and blocks the commit if errors are found.

  • Link: github.com/your-repo/LAB-2.md

  • A timer pre-set to 30:00.

Lab 3 - The Automator

  • Objective: Build a two-part hook system to enforce policy and automate chores.

  • Part 1 (commit-msg): Enforce that commit messages contain a JIRA-style ID based on the current branch name.

  • Part 2 (post-merge): Automatically run a dependency installer if a package file has changed after a merge.

  • A timer pre-set to 35:00.

Hooks out in the wild

Module 3: The Case for Frameworks

The Honeymoon is Over...

  • A simple, text-only slide.

  • "So, manual hooks are great, right? They're powerful, flexible, and have no dependencies."

  • "...what happens when you try to share them with your team?"

The "Common Hook Problems" Bingo Card

  • A visual 3x2 bingo card grid.

  • Each square contains one of the common problems:

    • "It works on my machine!" (macOS sed vs. Linux sed)

    • "I forgot to run chmod +x"

    • "New dev joined, forgot to install the hooks"

    • "Our hooks aren't even in version control!"

    • "I just used --no-verify to bypass it..."

    • "Managing Python, Node, and Ruby hooks is a nightmare"

Introducing: pre-commit

How pre-commit Works

  • A simple three-step diagram:

    1. You write a .pre-commit-config.yaml file. (Shows a snippet of the YAML).

    1. You run pre-commit install. This installs a tiny, smart script into .git/hooks/pre-commit.

    1. On commit, the script reads the YAML. It then downloads the specified tools into isolated, cached environments and runs them against your staged files.

Anatomy of the.pre-commit-config.yaml

A code block with a well-annotated example YAML file.

What About JavaScript? Introducing Husky

  • The Husky logo.

  • A code block showing a sample package.json configuration for Husky.

  • Text: "Husky is the go-to hook manager for the Node.js ecosystem. It leverages package.json and npm scripts for configuration."

Hooks and CI: Better Together

A diagram with two columns.

  • Column 1: Git Hooks (Your Laptop)

    • Icon: Laptop

    • Fast, Individual Feedback

    • Runs on every commit

    • Jobs: Linting, Formatting, Secret Scanning, Syntax Checks

  • Column 2: CI/CD Pipeline (The Server)

    • Icon: Server/Cloud

    • Slower, Authoritative Team Feedback

    • Runs on every pull request

    • Jobs: Full Unit/Integration Test Suites, Building Artifacts, Deploying

  • An arrow connects them, labeled "Partners in Quality".

 Hooks Aren't Just for Saying 'No'

Productivity Hacks

  • The Automatic Ticket Inserter (prepare-commit-msg)

    • Reads branch name feature/PROJ-451-login

    • Automatically prepends PROJ-451:  to the commit message.

    • "Turns a manual chore into an invisible, automated process."

  • The Automatic Dependency Installer (post-merge)

    • Detects changes to package.json after a merge.

    • Automatically runs npm install.

    • "Handles a common follow-up task without any user intervention."

Workflow Enhancements

  • The "Did you run migrations?" Reminder (post-merge)

    • Detects changes in the db/migrate/ directory.

    • Prints a big, bold, colorful message to the console: "ATTENTION: New migrations were pulled. Remember to run rails db:migrate!"

    • "A low-effort, high-impact nudge at the perfect moment."

A 4-Step Strategy for Your Team

  • A numbered list of actionable steps.

  • 1. Start Small & Provide Value: Don't boil the ocean. Introduce a single, undeniably useful hook first. An auto-formatter like Black or Prettier is a perfect start because its value is immediately obvious.

  • 2. Get Buy-In, Don't Mandate: Share a success story (like the secret-scanning one). Show, don't just tell. Frame it as a tool that helps everyone, not a process that is forced upon them.

  • 3. Use a Framework for Consistency: Once you have more than one hook or more than one developer, adopt a framework like pre-commit or Husky. This is non-negotiable for team success.

  • 4. Document the Setup: Add the two-line installation guide to your CONTRIBUTING.md or team wiki. Make it the path of least resistance.

Thank You

github.com/exitflynn

Git Hooked - IndiaFOSS '25

By Akshit Tyagi

Git Hooked - IndiaFOSS '25

  • 14