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-commitandgit-mergeand 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 pullis done on a local repository) - post-checkout (invoked when a
git-checkoutis 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-verifyflag
Top comments (0)