(세션) 좀 더 편리한 협업을 도와주는 Git Hooks / 박서정

  • by

기고자:박서정


‘A Commit Message 잘못 입력했습니다.

그러나 누구인지, 누구나 종종 전략과 다른 커밋 메시지를 잘못 입력하는 등의 실수를 할 수도 있다.

Git에는 이러한 문제를 사전에 방지하고 보다 편리한 협업을 지원하는 기능이 있다.

이번 세션을 통해 그 기능인 Git Hooks를 조사하려고 한다.

1. Git Hooks 배우기

1-1. Git Hooks 개념


Git Hooks는 Git에서 이벤트 발생때, 원하는 작업을 특정 스크립트에서 실행할 수 있도록 하는 기능이다.


Git Hooks 공식 문서

1-2. Git 후크의 종류

Git Hooks는 주로 클라이언트 후크, 서버 후크로 나뉩니다.

클라이언트 후크는 commit, merge 이벤트와 관련하여 발생하기 전에 클라이언트에서 실행되는 후크이며, 서버 후크는 git의 repository에서 push가 발생했을 때 서버에서 실행하는 후크입니다.

Client Git Hooks

분류 후크 발생 시점
커밋 워크플로 후크 사전 커밋 commit 실행 전
prepare-commit-msg 커밋 메시지를 만든 후 편집기를 실행하기 전에
commit-msg commit message 완료 후 commit 최종 완료 전
post-commit 커밋 완료 후
이메일 워크플로 후크 applypatch-msg git am 명령을 실행 한 후 첫 번째
pre-applypatch 패치 적용 후 실행 (중단 가능)
post-applypatch git am 명령 실행 후 끝 (중단 불가)
기타 클라이언트 후크 pre-rebase rebase 전에
post-rewrite git commit -amend, git rebase 등의 커밋 변경 명령을 실행 한 후
post-merge merge 완료 후
pre-push git push 실행 후 원격으로 데이터 전송 전 (중단 가능)

Server Git Hooks

분류 후크 발생 시점
서버 후크 pre-receive 푸시 실행 후 첫 번째
update 푸시 실행 후 각 브랜치에 대해 한 번 실행
post-receive 푸시 완료 후 실행

2. Git Hooks 사용

2-1. Git Hooks 사용법

원하는 Git Hooks를 사용하려면 프로젝트 .git/hooks 디렉토리 내에 설정하고 싶은 후크명으로 스크립트를 보존하면 된다.

만약 커밋을 하기 전에 특정 메시지를 띄우고 싶다면 다음과 같이 진행한다.

// 경로로 이동
$ cd .git/hooks/
 
// 훅이름 file 생성
$ touch pre-commit
 
// 훅 실행 시점에서 실행시킬 코드 작성
$ vi pre-commit
# pre-commit 파일

# 'Commit message: (MJU-이슈번호) 메시지' 를 출력시키기
echo 'Commit message: (MJU-이슈번호) 메시지'

# Exit 코드가 0이 아니면 커밋 취소
exit 0

2-2. Git Hooks를 공유하는 방법

위와 같이 만든 Git Hooks를 팀 구성원과 공유하려는 경우 스크립트는 모두 .git 파일에 있으므로 git에 파일이 나타나지 않습니다.

그 문제를 해결하고 Git Hooks의 제어를 단순화하기 위해 Husky를 사용하면 된다.

Husky 공식 문서

# Husky ver 6 기준

# husky 설치
npx husky-init && npm install

# package.json 설정
{
  "scripts": {
    ...
    "prepare": "husky install"
  },
}

# 훅 추가
npx husky add .husky/(hook) '(code)'

3. Git Hooks 활용

3-1. 커밋 메시지 형식 검증


커밋 워크플로 후크

커밋 메시지 규칙을 “(MJU-Issue Number) message” 형식으로 지정하면 입력한 커밋 메시지가 필요합니다.

정규식과 일치하는지 확인에서 푸시가 이루어지는 것을 관리하면 좋을 것이다.

그러므로 이러한 경우 commit-msg 후크를 이용하면 된다.

$ cd .git/hooks/
$ touch commit-msg
$ vi commit-msg
# commit-msg 파일

# 원하는 정규식
$regex =  /^\(MJU-(0-9)+\)(\d\D)*refs(\s)?-(\s)?.*/
 
def check_message_format

  # ARGV는 commit message가 들어 있는 임시 파일 경로
  message_file = ARGV(0)
  # 위의 경로에서 commit message를 받아온다
  message = File.read(message_file)
  
  if !
$regex.match(message) puts "(POLICY) 잘못된 커밋 메시지 형식입니다.

" puts "(RULE) (MJU-{issueTicketNumber}) \n\n /* message */ \n\n refs - {issueLink}" exit 1 end end check_message_format

3-2. Branch에서 Issue 번호를 얻어 커밋 메시지 생성

Jira를 사용하는 경우 주로 branch 및 commit message 이슈 번호 관리를 통해 오류가 발생한 경우 신속하게 해결할 수 있도록 다음 규칙을 사용합니다.

Branch: feature/특정 이름 – 문제 번호 – 어떻게
예: feature/MJU-231-post
커밋 메시지: 특정 이름 – 문제 번호 커밋 내용
예: MJU-231 게시물 업로드 API 추가

이와 같이 commit 할 때마다 작성해야 하는 message 는 실수를 유발하기 쉽고, 무엇보다도 귀찮은 것의 하나이다.


따라서 이것을 Git Hooks prepare-commit-msg 후크을 사용하여 분기에서 문제 번호를 검색하고 커밋 메시지에 자동으로 적용할 수 있습니다.

$ cd .git/hooks/
$ touch prepare-commit-msg
$ vi prepare-commit-msg
#!
/bin/bash # 만약, branch가 master, develop, release, hotfix인 경우 스킵 if ( -z "$BRANCHES_TO_SKIP" ); then BRANCHES_TO_SKIP=(master develop release hotfix) fi # 브랜치 이름에서 이슈 번호 가져오기 BRANCH_NAME=$(git symbolic-ref --short HEAD) BRANCH_NAME="${BRANCH_NAME##*/}" JIRA_ID=`echo $BRANCH_NAME | egrep -o 'HD.-(0-9)+'` BRANCH_EXCLUDED=$(printf "%s\n" "${BRANCHES_TO_SKIP(@)}" | grep -c "^$BRANCH_NAME$") BRANCH_IN_COMMIT=$(grep -c "$JIRA_ID" $1) # 커밋 메시지에 이슈 번호가 적혀있는지 확인 후, 있다면 skip, 없다면 맨 앞에 이슈번호 추가 if ( -n $JIRA_ID ) && !
(( $BRANCH_EXCLUDED -eq 1 )) && !
(( $BRANCH_IN_COMMIT -ge 1 )); then sed -i.bak -e "1s/^/$JIRA_ID /" $1 fi​


여러 사람이 함께 하는 프로젝트일수록 체계적인 개발 룰은 서로의 코드를 보다 간단하게 파악하고 에러 발생시 신속하게 대처할 수 있도록 중요한 부분 중 하나라고 생각한다.

그러나 솔직히, 이것은 꽤 귀찮은 작업이며, 실수도 발생하기 쉽다는 문제가있다.

그러나 이것을 앞의 예처럼
프로젝트 내에서 Git Hooks를 활용하면 보다 체계적인 개발에 도움이 될 것 같다.

(References)

Git hooks란?

Git Hook commit-msg 적용

Husky에서 Git Hook을하자.

GitHub 커밋 메시지에 JIRA 문제 번호를 자동으로 입력