Git Hook 으로 commit message 강제하기
728x90
Git hook 을 사용하여 협업시 commit template 의 통일성을 가져가려고 합니다.
.git 폴더 밑에 .gitmessage 를 만들어 줍니다.
# <type>: <subject>
##### Subject 50 characters ################# -> |
# Body Message
######## Body 72 characters ####################################### -> |
# Issue Tracker Number or URL
# --- COMMIT END ---
# Type can be
# feat : new feature
# fix : bug fix
# refactor: refactoring production code
# style : formatting, missing semi colons, etc; no code change
# docs : changes to documentation
# test : adding or refactoring tests
# no productin code change
# chore : updating grunt tasks etc
# no production code change
# ------------------
# Commit rules:
# Capitalize the subject line
# Use the imperative mood in the subject line
# Do not end the subject line with a period
# Separate subject from body with a blank line
# Use the body to explain what and why vs. how
# Can use multiple lines with "-" for bullet points in body
# ------------------
commit template 은 google 에서 가장 유명한 template 를 사용했습니다.
commit 시 commit message 를 lint check 하기 위한 python script 입니다
#!/usr/bin/python3
import re
import sys
type_list = [
"feat",
"fix",
"refactor",
"style",
"docs",
"test",
"chore",
"ci",
"perf",
]
type_regex = r"^(feat|fix|refactor|style|docs|test|chore|ci|perf)(\(.+\))?\:\s(.{3,})"
class bcolors:
FAIL = "\033[91m"
ENDC = "\033[0m"
def verify_commit_message():
with open(sys.argv[1]) as commit:
lines = commit.readlines()
# Remove comments
lines = [line for line in lines if not line.startswith("#")]
# If the last line is whitespace, remove it
while lines[-1] == "\n":
lines = lines[:-1]
if len(lines) == 0:
break
# Empty commit message
if len(lines) == 0:
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}Empty commit message.\n"
)
sys.exit(1)
# Subject line should be less than 50 characters.
if len(lines[0]) > 50:
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}Subject line should be less than 50 characters.\n"
)
sys.exit(1)
# Subject line should follow the rule.
if re.match(f"({type_regex})", lines[0]) is None:
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}The commit message subject line does not follow the rule."
)
sys.stderr.write("\n<type>: <subject> is required.\n")
sys.exit(1)
# The subject should be a title-case.
if not lines[0].split(":")[1].strip()[0].istitle():
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}The subject should be title-cased.\n"
)
sys.exit(1)
# If commit message has single line, description might be missing.
if len(lines) == 1:
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}Descriptions are missing.\n"
)
sys.exit(1)
# After subject line, line space is required.
if lines[1] != "\n":
sys.stderr.write("\nThe line space after the subject line is required.\n")
sys.exit(1)
for line in lines[2:]:
# Every single description should be less than 72 characters.
if len(line) > 72:
sys.stderr.write(
"\nEvery single description should be less than 72 characters.\n"
)
sys.exit(1)
# Description starts with "-".
if not line.startswith("-"):
sys.stderr.write(line)
sys.stderr.write(
f"\n{bcolors.FAIL} Commit failed: {bcolors.ENDC}Description should start with a dash '-'.\n"
)
sys.exit(1)
sys.exit(0)
if __name__ == "__main__":
verify_commit_message()
.git/hooks/verify_commit_msg.py 로 저장합니다.
chmod ug+x ./verify_commit_msg.py
로 파일실행 권한을 줍니다.
.git/hooks/commit-msg
#!/bin/sh
exec < /dev/tty
./.git/hooks/verify_commit_msg.py $1
commit 발생시 이벤트를 받아 파이썬 스크립트를 실행할 shell script 입니다.
chmod ug+x ./commit-msg.py
마찬가지로 파일권한을 줍니다.
template 규칙을 맞추지 않아서 commit 이 되지 않았습니다.
728x90