World map

 

BM: Baca dalam Bahasa Melayu

World 10: Deep Git

Hooks

You will learn: how Git can run your own checks before a commit, and how to share them.

The problem

You keep committing with console.log left in. Your teammates sigh. Can Git stop you before the commit?

Pick one answer.

Watch

A hook: A script Git runs by itself at a set moment, like just before a commit. is a script that Git runs at a set moment. Hooks live in .git/hooks. Tap each moment.

Tap each point on the timeline.

Watch

bash
cat .git/hooks/pre-commit
#!/bin/sh
# Stop the commit if a staged line adds console.log
if git diff --cached | grep -q "^+.*console.log"; then
echo "Please remove console.log first."
exit 1
fi
chmod +x .git/hooks/pre-commit
git commit -m "Add menu"
Please remove console.log first.
A pre-commit hook: if a staged line adds console.log, it prints Please remove console.log first and exits with 1. After chmod +x, git commit stops with that message.

A hook must be executable: chmod +x. If it ends with exit 1, Git stops the commit. exit 0 lets it through.

Try it

Put the life of a pre-commit hook in order.

First step at the top. Put these in order. Use the arrows, or drag.

  • The hook exits with 0, so the commit is made
  • Make it executable with chmod +x
  • Write the script in .git/hooks/pre-commit
  • Run git commit
  • Git runs the hook first

Watch

bash
cat .git/hooks/commit-msg
#!/bin/sh
# $1 is the file that holds the message
if ! grep -qE "^(feat|fix|docs): " "$1"; then
echo "Start the message with feat:, fix: or docs:"
exit 1
fi
git commit -m "stuff"
Start the message with feat:, fix: or docs:
A commit-msg hook: if the message file does not start with feat, fix or docs, it prints a tip and exits with 1. git commit -m stuff stops with that tip.

A commit-msg hook checks the message. Git hands it the message file as $1. Here, “stuff” does not get in.

Predict

You add a hook in .git/hooks. Mei clones the repo. Does the hook run on her computer?

Pick one answer.

Try it

To share hooks, commit them in a folder like .githooks. Each person then sets core.hooksPath. Read the hook, then set it.

Check

Good habit, or needs work? Swipe each one.

Swipe right for good, left for needs work. Or use the buttons.

1 / 4

Keep hooks fast

Keep hooks fast

You did it!

You can now make Git check your work before every commit.

Go deeper (optional)

New repos get sample hooks in .git/hooks, ending in .sample. Remove the ending to try one. A hook can be any language: the first line names it. git commit --no-verify skips pre-commit and commit-msg. git hook run pre-commit runs a hook by hand.