[Git] Hooks 적용으로 커밋 메세지 형식 강제하기

2025. 10. 15. 23:22·Develop note

https://velog.io/@jihwankim128/%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-%EC%BB%A8%EB%B2%A4%EC%85%98-%ED%86%B5%EC%9D%BC

 

프리코스 컨벤션 통일

프리코스는 커밋 컨벤션, 코드 컨벤션 규약이 있습니다!4.2 블럭 들여쓰기: +4 스페이스새 블록 또는 블록과 유사한 구조(block-like construct)가 열릴 때마다 들여쓰기가 네 칸씩 증가합니다. 블록이

velog.io

우아한 테크코스 프리코스를 진행중이신 한 분의 글을 보다가 왜 깃허브 컨벤션이 막히는걸까 싶어서 공부를 좀 해보았습니다!


🤔 기본 동작 확인하기

https://git-scm.com/book/ko/v2/Git%EB%A7%9E%EC%B6%A4-Git-Hooks

 

Git - Git Hooks

여기서 한가지 알아둘 점은 저장소를 Clone 해도 클라이언트 훅은 복사되지 않는다는 점이다. 만든 정책이 반드시 적용되도록 하려면 서버 훅을 이용해야만 하며 작성은 정책 구현하기 부분을 참

git-scm.com

 

일단 글을 읽기 전에 공식 문서를 한번 훑어보고 오는 것을 추천합니다

 

☺️ 깃 훅이란...?

Git 훅은 Git 저장소의 특정 이벤트(커밋, 푸시 등)가 발생했을 때 자동으로 실행되도록 설계된 스크립트입니다

 

이는 로컬 컴퓨터에 있는 Git 저장소의 .git/hooks/ 디렉터리에 존재하고, Git 명령이 실행될 때 Git 자체에 의해 호출됩니다.

이를 활용하면 커밋 전에 코드 포맷팅 검사, 커밋 메시지 형식 검사 등에 사용할 수 있습니다.

 

그렇다면... 커밋하면 어떤 flow로 동작하는건데...?

 

우리가 일방적으로 git commit을 하면 총 네 가지 플로우로 훅이 실행된다.

  1. pre-commit (커밋 직전)
    - 시점 : 이는 커밋 메시지를 작성하기 전에 호출된다.
    - 역할 : 커밋할 스냅샷(변경된 파일)을 점검한다. 표준 검사, 불필요 공백 제거, 단위 테스트 등을 위주로 실행된다.
  2. prepare-commit-msg (메시지 준비 중)
    - 시점 : pre-commit이 성공적으로 완료되고, 커밋 메시지를 담은 임시 파일이 생성된 직후에 실행된다.
    - 역할 : 커밋 메시지 템플릿 같은 자동으로 생성된 초기 메시지 내용을 편집하는 데 사용된다. (ex. 브랜치 이름 기반 이슈 번호를 메시지에 자동 추가)
  3. commit-msg (메시지 최종 검증)
    - 시점 : 사용자가 커밋 메시지 편집을 완료, 저장하여 메시지가 확정된 직후에 실행된다.
    - 역할 : 커밋 메시지가 컨벤션(규칙)을 따르는지 확인한다. (스크립트가 0이 아닌 값을 반환하면 Git은 커밋을 중단시킵니다.)
  4. post-commit (커밋 완료 후, 알림)
    - 시점 : 커밋이 완료되어 저장소에 올라간 후에 실행된다.
    - 역할 : 알림이나 정리 작업을 수행한다. (ex. CI 트리거 등의 작업)

정리하자면 아래 플로우와 같습니다.

git commit -> pre-commit -> prepare-commit-msg -> commit-msg -> post-commit

 

그렇다면 메시지를 최종 검증하는 단계인 commit-msg의 hook 파일을 건들면, husky같은 서비스를 사용하지 않아도 강제로 서식이 맞지 않는 경우에 block 할 수 있지 않을까?

 


💡 검증 단계

일단, git hook 폴더에 접근해보았습니다.

위에서 다뤘던 파일들의 sample hook 파일들이 위치해있었습니다.

 

지금 우리가 건드려야 할 파일은 commit-msg이니 해당 파일을 새로 생성해주었습니다.

 

그 다음 파일을 동작하게 세팅해줘야 하는데, 찾아보니 commit-msg는 bash 혹은 쉘 스크립트로 작동한다는 것을 알게 되었습니다.

 

그래서 파일을 수정해 주었고,

 

#!/usr/bin/env bash
commit_msg_file=$1

# 1. 파일에서 첫 줄 (제목)만 읽어옵니다.
commit_subject=$(head -n 1 "$commit_msg_file")

# 2. 정규식 패턴을 sh에서 작동하는 ERE 형식으로 정의합니다.
# (feat|fix|docs|style|refactor|test|chore)로 시작하고 : 공백이 와야 합니다.
pattern='^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,}'

# 3. grep 대신 정규식 매칭을 시도하고 실패하면 에러 메시지를 출력합니다.
if ! echo "$commit_subject" | grep -E "$pattern" > /dev/null; then
    echo "❌  커밋 메시지 형식 오류"
    echo ""
    echo "✅ 필수 사항: type, subject"
    echo "❎️선택 사항: scope, body, subject"
    echo ""
    echo "===제목 라인==="
    echo "<type>(<scope>): <subject>"
    echo "예시) feat: 로그인 기능 추가, fix(auth): 버그 수정"
    echo "허용 타입) feat, fix, docs, style, refactor, test, chore"
    echo ""
    echo "===본문 라인==="
    echo "<BLANK LINE>"
    echo "<body>"
    echo "<BLANK LINE>"
    echo "<footer>"
    exit 1  # 스크립트 강제 종료
fi

# 4. 성공 시 0으로 종료 (커밋 진행)
exit 0

 

참고로 해당 탐색 코드는 글 맨 위에 있는 블로그 선생님의 글에서 따와서 조금 수정했습니다!

 

그 다음으로는 새 파일을 만들었으니, 실행 권한을 부여해줬습니다.

chmod +x .git/hooks/commit-msg

 

그 다음 commit을 진행해 보았습니다.

 

그러자...

 

너무 허무하게 성공...했습니다.

 

 

제대로 된 형식의 커밋 메세지도 잘.. 됩니다...


외부 library를 사용하지 않고 직접 구현해서 쓰는 방법을 찾다가 여기까지 온건데... 생각보다 너무 허무하게 성공해버렸습니다...

 

암튼...

지식이 늘었다! (+1)

'Develop note' 카테고리의 다른 글

[트러블슈팅] 공백 입력 테스트코드, NoSuchElementException  (1) 2025.10.28
[Java] Utility class란?  (1) 2025.10.25
[Pattern] 예외 팩토리(Exception Factory) 패턴: 깔끔하고 유연한 예외 처리  (1) 2025.10.23
[Git] Git alias 설정은 어떻게 돌아가는가?  (0) 2025.10.20
'Develop note' 카테고리의 다른 글
  • [트러블슈팅] 공백 입력 테스트코드, NoSuchElementException
  • [Java] Utility class란?
  • [Pattern] 예외 팩토리(Exception Factory) 패턴: 깔끔하고 유연한 예외 처리
  • [Git] Git alias 설정은 어떻게 돌아가는가?
youngi2
youngi2
영기의 개발기록입니다!
  • youngi2
    영기의 개발일지
    youngi2
  • 전체
    오늘
    어제
    • 분류 전체보기 (15)
      • Algorithm (10)
      • Develop note (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    예외 팩토리 패턴
    유틸리티 클래스
    2618 kotlin
    백준 2618 kotlin
    Exceptino Factory
    7578 코틀린
    GIT
    백준 7578 코틀린
    백준 2618 코틀린
    7578 kotlin
    Exception Factory Pattern
    예외팩토리패턴
    commit-msg
    유틸리티클래스
    2618 코틀린
    예외팩토리
    utility class
    백준
    백준 7578 kotlin
    백준 7578
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
youngi2
[Git] Hooks 적용으로 커밋 메세지 형식 강제하기
상단으로

티스토리툴바