프로젝트를 깃에 연동하면 자동으로 디렉토리 루트에 .git이라는 폴더가 생긴다. 아래에 들어가면 여러 관련 파일들이 있는데, 오늘 우리가 확인할 것은 [hooks], 그 중에서도 [commit-msg]이다! 공식문서에 따르면 git hook은 어떤 이벤트가 생겼을 때 자동으로 특정 스크립트를 실행해주는 동작을 의미한다. hooks 디렉토리에 들어가보면 여러 스크립트 예제가 존재한다. 각각의 파일들은 '.sample'이라는 확장자로 저장되어 있는데, 내가 원하는 형태로 수정하고 '.sample' 을 떼면 깃이 동작하면서 읽고 스크립트를 실행하게 된다.
commit-msg 훅은 커밋 메시지가 들어 있는 임시 파일의 경로를 아규먼트로 받는다.
그리고 이 스크립트가 0이 아닌 값을 반환하면 커밋되지 않는다.
이 훅에서 최종적으로 커밋이 완료되기 전에 프로젝트 상태나 커밋 메시지를 검증한다.
앞선 문장에 적혀있든 commit-msg는 내가 작성한 커밋 메시지가 git message template에 맞는 형태인지를 체크해주는역할을 하게된다. 다음은 GPT의 도움으로 작성한 commit-msg 파일의 내용이다. 내가 참고한 git template은 이전 게시물에서 확인할 수 있다.
1. commit-msg 파일 작성
#!/bin/sh
commit_msg_file=$1
# 커밋 메시지에서 주석(#)을 제외한 모든 줄을 배열로 추출
commit_lines=$(grep -v "^#" "$commit_msg_file")
# 첫 번째 줄은 type과 subject
type_subject=$(echo "$commit_lines" | sed -n '1p')
# 두 번째 줄은 빈 줄이어야 함
empty_line=$(echo "$commit_lines" | sed -n '2p')
# 세 번째 줄부터 본문과 꼬릿말 구분
body_and_footer=$(echo "$commit_lines" | sed -n '3,$p')
# 본문과 꼬릿말을 나누는 빈 줄의 위치 찾기
footer_start=$(echo "$body_and_footer" | grep -n -m 1 '^$' | cut -d: -f1)
# 본문과 꼬릿말 구분
if [ -n "$footer_start" ]; then
body=$(echo "$body_and_footer" | sed -n "1,$((footer_start-1))p")
footer=$(echo "$body_and_footer" | sed -n "$((footer_start+1)),$ p")
else
body=$body_and_footer
footer=""
fi
# 커밋 메시지 확인을 위한 출력
echo "Type and subject: '$type_subject'"
echo "Empty line: '$empty_line'"
echo "Body: '$body'"
echo "Footer: '$footer'"
# type 확인 (feat, fix, docs, style, refactor, test, chore 등)
valid_types="feat|fix|docs|style|refactor|test|chore|design|comment|init|rename|remove"
if ! echo "$type_subject" | grep -Eq "^($valid_types): .+"; then
echo "Error: Commit message 'type' must be one of $valid_types and follow the format 'type: subject'"
exit 1
fi
# 두 번째 줄은 반드시 빈 줄이어야 함
if [ -n "$empty_line" ]; then
echo "Error: Second line must be empty."
exit 1
fi
# 본문이 여러 줄일 경우 각 줄은 '-'로 시작해야 함
line_count=$(echo "$body" | wc -l)
if [ "$line_count" -gt 1 ]; then
echo "$body" | while read -r line; do
if [ -n "$line" ] && ! echo "$line" | grep -q "^-\s"; then
echo "Error: Body lines must start with '-'."
exit 1
fi
done
fi
# 푸터에 대한 규칙 검증 (필수 아님)
if [ -n "$footer" ]; then
if ! echo "$footer" | grep -Eq "^(Fixes|Resolves|Ref|Related to): .+"; then
echo "Error: Footer must follow the format 'Fixes: #issue' or similar."
exit 1
fi
fi
echo "Commit message format is valid."
exit 0
commit-msg를 작성하고 날 가장 혼란스럽게 했던 에러는 git template의 '#(주석)'을 읽어오는 것이었다. 그냥 git bash에서 커밋 메시지를 작성하면 #은 자동으로 주석처리가 되는데, 템플릿으로 만들고 hook에서 읽을 때는 인식을 못하는 것 같다. 그래서 첫번째 줄에 주석을 제외하고 커밋메시지로 던질 수 있게 코드를 추가해주었다!
2. 권한 부여
commit-msg 파일을 제대로 작성하고 나서, git이 파일에 접근할 수 있게 권한을 부여해야 한다.
chmod +x prepare-commit-msg
3. 평소와 같이 커밋날리기!
이렇게 파일을 잘 작성하고 권한도 잘 부여해 주면! 커밋 메시지를 남길 때 Template에서 어긋나는 커밋 메시지를 적은 경우 어떤 부분에서 에러가 났는지를 내뱉어주고, commit에 실패하게 된다.
'GIT' 카테고리의 다른 글
[Git] 깃 원격 레포에 용량 큰 파일 업로드하는 법(ft. GIT LFS) (0) | 2024.12.19 |
---|---|
[GIT] commit msg template 적용 (0) | 2024.09.11 |
Git이란 무엇인가? (0) | 2023.12.05 |