The "Oops, I Forgot to Lint" Problem
It’s a classic scenario: you finish a piece of code, you’re proud of it, you push it, and immediately the CI build fails. Why? You forgot to run the linter, and there’s a simple formatting error. It’s an embarrassing and completely avoidable waste of time. What if you could make it impossible to commit code that doesn't meet your quality standards? You can, with Git Hooks.
What Are Git Hooks?
Git Hooks are scripts that Git automatically executes before or after certain events, such as `commit`, `push`, and `rebase`. They are your personal, automated gatekeepers. If a hook script exits with a non-zero status (an error), it will abort the Git action. This allows you to enforce quality standards and automate tedious checks right on your local machine.
The Most Useful Hook: `pre-commit`
The `pre-commit` hook runs after you type `git commit` but before the commit message editor appears. It's the perfect place to run fast, automated checks on the code you’re about to commit.
Popular uses for `pre-commit` hooks include:
- Running a code linter (like ESLint for JavaScript or Black for Python).
- Running a code formatter (like Prettier).
- Checking for leftover debugging statements (like `console.log`).
- Ensuring code compiles successfully.
If any of these scripts fail, the commit is aborted, forcing you to fix the issue before you can proceed. This prevents broken code from ever entering your repository’s history.
How to Set Up Git Hooks (The Easy Way)
While Git has a built-in hooks system (look in your project’s `.git/hooks` folder), managing these shell scripts manually can be tedious. A much better approach is to use a tool that manages them for you. For front-end projects, the most popular tool is Husky.
Here’s how you would set up a `pre-commit` hook with Husky and `lint-staged` to automatically lint only your staged files:
# 1. Install the tools
npm install husky lint-staged --save-dev
# 2. Enable Husky
npx husky install
# 3. Create a pre-commit hook that runs lint-staged
npx husky add .husky/pre-commit "npx lint-staged"
4. Configure `lint-staged` in your `package.json` to specify which commands to run on which files:
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
And that’s it! Now, every time you run `git commit`, Husky will trigger `lint-staged`, which will run ESLint and Prettier on only the JavaScript/TypeScript files you’ve changed. If they find any issues, the commit will be aborted. It’s automation and quality control, baked right into your workflow.
Other Useful Hooks
- `pre-push`: Runs before you `git push`. This is a great place to run your full test suite. It’s slower, so you don’t want it on every commit, but it provides a final safety net to ensure you aren’t pushing broken code.
- `commit-msg`: Can be used to lint your commit message itself, ensuring it follows your team’s conventions (e.g., starting with "Feat:", "Fix:", etc.).
Using Git Hooks is like having a diligent teammate who double-checks your work before it goes public. It takes a few minutes to set up but saves countless hours and headaches in the long run.