Git-hooks = scripts with a "special" name, located in the .git/hooks directory inside the repository which are triggered every time a particular event occurs in the Git repository.
They allow you to customize Git's internal behavior and perform customizable actions at certain points in GIT's execution.
There are different types of commit hooks but we will cover some of the client-side workflow hooks:
- pre-commit (linting, spell-checks, code style stuff)
- prepare-commit-msg (alter the default commit message or create a complete a new one)
- commit-msg (invoked
git-commit
andgit-merge
and allow to perform a check of the commit message) - post-commit (invoked
git-commit
, it takes no parameters, and is invoked after a commit is made) - pre-rebase
- pre-push
- post-rewrite
- post-merge (invoked by
git-merge
, which happens when agit pull
is done on a local repository) - post-checkout (invoked when a
git-checkout
is run after having updated the worktree)
A complete list of git-hooks can be found here
We will demonstrate the power of git-hooks by "enforcing" a certain standard with respect to the commit messages. (e.g. the commit message should contain the task identifier e.g. TASK-5463
)
This is a two step process.
1) Create our script, e.g. in the root of our repo we can create commit-msg.py
file.
#!/usr/bin/python
import sys
import re
def line_valid(line_no, line):
"""
return True if line is ok according with the verification
"""
if line_no == 0:
# first line should have the task identifier e.g TASK-4351
return re.match("^TASK-\d{1,5}.*", line)
def show_rules():
"""
Rules for a great git commit message style
"""
print("Please follow the rules add task/feature TASK-xxxx in the name of the commit msg""")
def main():
print("Args are {}".format(sys.argv))
# read commit-msg
with open(sys.argv[1], "r") as fp:
lines = fp.readlines()
for line_no, line in enumerate(lines):
#print(line_no,line)
if not line_valid(line_no, line):
show_rules()
sys.exit(1)
sys.exit(0)
if __name__=="__main__":
main()
2) Create a symbolic link.
cd <REPO>/.git/hooks
ln -s <REPO>/commit-msg.py ./commit-msg
Using this simple hook, we managed to enforced (based on our regex) that a commit message should start with the task id
Important aspects:
- Git hooks are not checked into source control by default
- The user can bypass locally pre-commit and commit-msg hooks by passing
--no-verify
flag
Top comments (0)