Git 클라이언트 측 훅을 활용하여 워크플로우 자동화하기: 실용 가이드
Git 훅은 Git 생태계 내에서 강력하지만 종종 제대로 활용되지 않는 도구입니다. 커밋, 푸시 또는 병합과 같은 특정 시점 이전에 또는 이후에 사용자 지정 스크립트를 자동으로 실행할 수 있게 해줍니다. 로컬 리포지토리에서 작업하는 개별 개발자의 경우, 클라이언트 측 훅은 중앙 서버 측 강제 적용에 의존하지 않고 코드 품질을 적용하고, 로컬 테스트를 실행하며, 제출 전 확인 작업을 표준화하는 데 필수적입니다.
이 가이드에서는 Git 클라이언트 측 훅의 작동 방식을 살펴보고, 가장 일반적이고 유용한 유형인 pre-commit과 post-merge에 중점을 둡니다. 이러한 훅을 숙달하면 반복적인 작업을 자동화하고, 오류를 조기에 발견하며, 일일 개발 프로세스의 일관성과 신뢰성을 크게 향상시킬 수 있습니다.
Git 훅 이해하기
Git 훅은 Git이 특정 핵심 작업 전후에 자동으로 실행하는 실행 가능한 스크립트입니다. 이들은 모든 Git 리포지토리의 .git/hooks 디렉터리에 상주합니다. Git은 샘플 훅(일반적으로 .sample로 끝남)을 함께 제공하지만, .sample 확장자를 제거하도록 이름을 변경해야만 활성화됩니다.
클라이언트 측 훅 대 서버 측 훅
두 가지 주요 유형을 구별하는 것이 중요합니다.
- 클라이언트 측 훅: 로컬 개발자의 컴퓨터에서 실행됩니다(예:
pre-commit,commit-msg). 이는 로컬 유효성 검사 및 사용자 경험 개선에 탁월합니다. - 서버 측 훅: 푸시가 수신될 때 중앙 서버에서 실행됩니다(예:
pre-receive,post-receive). 이는 일반적으로 프로젝트 전체의 강제 적용 정책에 사용됩니다.
중요 참고 사항: 클라이언트 측 훅은 로컬에 있으므로 리포지토리를 복제해도 자동으로 복제되거나 공유되지 않습니다. 모든 설정은 각 개발자가 수동으로 수행하거나 초기화 스크립트를 통해 관리해야 합니다.
클라이언트 측 훅 찾기 및 활성화하기
모든 클라이언트 측 훅은 리포지토리 내의 .git/hooks 디렉터리에 있습니다.
새 리포지토리를 초기화할 때 Git은 템플릿을 제공합니다.
git init
# pre-commit.sample과 같은 샘플 파일이 채워진 .git/hooks 디렉터리를 생성합니다.
훅을 활성화하려면 샘플 파일의 이름을 바꾸기만 하면 됩니다. 예를 들어, pre-commit 훅을 활성화하려면 다음을 수행합니다.
cd .git/hooks
cp pre-commit.sample pre-commit
chmod +x pre-commit
여기에 배치된 스크립트는 실행 가능해야 합니다(따라서 chmod +x가 필요합니다). 일반적으로 셸 스크립트로 실행되지만, 셔뱅(shebang) 줄(#!/bin/bash, #!/usr/bin/env python 등)이 존재하고 인터프리터가 사용 가능하다면 어떤 언어로든 작성할 수 있습니다.
실용적인 예제 1: pre-commit 훅
pre-commit 훅은 Git이 커밋 메시지를 요청하기 직전에 실행됩니다. 이는 커밋하려는 코드에 대한 검사를 실행하기에 이상적인 위치입니다.
pre-commit의 일반적인 사용 사례:
- 린팅/스타일 검사: 코드가 설정된 스타일 가이드(예: ESLint, Black)를 준수하는지 확인합니다.
- 단위 테스트 실행: 빠르고 중요한 테스트를 실행합니다.
- 구문 검사: 기본적인 구문 정확성을 확인합니다.
- 의도치 않은 커밋 방지: 비밀 키나 디버그 문장이 남아 있지 않은지 확인합니다.
간단한 pre-commit 훅 생성 (셸 예제)
이 예제 스크립트는 커밋을 위해 스테이징된 파일에 TODO:라는 단어가 포함되어 있는지 확인하고, 발견되면 커밋을 실패시켜 개발자가 해당 자리 표시자를 처리하도록 강제합니다.
.git/hooks/pre-commit 파일을 만들고 다음 내용을 추가합니다.
#!/bin/bash
# 1. 스테이징된 파일에서 'TODO:' 확인
STAGED_FILES=$(git diff --cached --name-only)
if grep -q "TODO:" <<< "$STAGED_FILES"; then
echo "\n[훅 실패] 스테이징된 파일에서 'TODO:' 마커가 발견되었습니다. 커밋하기 전에 이를 해결해 주세요."
# 마커를 포함하는 특정 파일 출력 (선택 사항)
git diff --cached | grep "TODO:"
exit 1 # 커밋을 중단하려면 0이 아닌 값으로 종료
fi
# 2. Python 파일에 대한 기본 구문 검사 실행 (requires 'python -m py_compile')
for FILE in $(git diff --cached --name-only --diff-filter=ACM | grep '\.py$'); do
echo "$FILE 에 대한 구문 검사 중..."
python -m py_compile "$FILE" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "[훅 실패] $FILE 에서 구문 오류가 발견되었습니다."
exit 1
fi
done
# 모든 검사를 통과한 경우
echo "Pre-commit 검사를 성공적으로 통과했습니다."
exit 0 # 커밋을 허용하려면 0으로 종료
스크립트가 0이 아닌 상태 코드(예: exit 1)로 종료되면 Git은 즉시 커밋 프로세스를 중단하고 오류 메시지를 출력합니다.
모범 사례: 복잡한 린팅 및 서식 지정의 경우, 후크 설치, 공유 및 종속성 관리를 자동으로 처리하는 Husky(JavaScript 생태계용) 또는 Pre-commit(프레임워크에 구애받지 않는 도구)과 같은 외부 훅 관리 도구를 고려하십시오.
실용적인 예제 2: post-merge 훅
post-merge 훅은 성공적인 git merge 작업이 완료된 직후에 실행됩니다. 이 훅은 정리 작업을 수행하거나 새로 병합된 코드를 기반으로 로컬 종속성을 업데이트하는 데 유용합니다.
post-merge의 일반적인 사용 사례:
- 서브모듈 업데이트: 종속 리포지토리를 자동으로 새로 고침합니다.
- 종속성 재빌드: 종속성 파일(
package.json,requirements.txt)이 변경된 경우npm install또는 이에 상응하는 명령을 실행합니다. - 사용자 알림: 관련 브랜치 정보를 표시합니다.
간단한 post-merge 훅 생성 (종속성 새로 고침)
프로젝트가 Node.js를 사용하는 경우, package.json 또는 package-lock.json을 병합하여 수정한 후 node_modules가 최신 상태인지 확인하고 싶을 수 있습니다.
.git/hooks/post-merge 파일을 생성합니다.
#!/bin/bash
echo "Post-merge 훅이 트리거되었습니다."
# 병합에서 package.json 또는 package-lock.json이 수정되었는지 확인
if git diff --name-only HEAD@{1} HEAD | grep -Eq "(package\.json|package-lock\.json)"; then
echo "종속성 파일이 수정되었습니다. npm install을 실행합니다..."
npm install
if [ $? -eq 0 ]; then
echo "종속성이 성공적으로 업데이트되었습니다."
else
echo "경고: 병합 후 npm install에 실패했습니다. 수동으로 'npm install'을 실행하십시오."
fi
else
echo "종속성 파일이 변경되지 않았습니다. npm install을 건너뜁니다."
fi
exit 0
이 훅은 Git의 참조 로그 기능(HEAD@{1}은 병합 이전 상태를 참조)을 활용하여 파일을 비교하므로 동작을 조건부로 만들고 불필요한 실행을 방지합니다.
기타 유용한 클라이언트 측 훅
pre-commit과 post-merge가 널리 사용되지만, 몇 가지 다른 클라이언트 측 훅도 워크플로우를 간소화할 수 있습니다.
commit-msg: 사용자가 커밋 메시지를 입력한 후 커밋이 확정되기 전에 실행됩니다. 커밋 메시지 표준(예: Conventional Commits 형식)을 적용하는 데 유용합니다.pre-rebase: 리베이스 시작 전에 실행됩니다. 특정 브랜치가 리베이스되는 것을 보호해야 하는지 확인할 수 있습니다.post-checkout:git checkout이 성공한 후에 실행됩니다. 체크아웃된 브랜치에 따라 환경 변수 또는 도구 구성을 전환하는 데 유용합니다.
| 훅 이름 | 트리거 지점 | 주요 사용 사례 |
|---|---|---|
pre-commit |
커밋 생성 전 | 코드 린팅, 로컬 테스트, 서식 지정 |
commit-msg |
메시지 입력 후 | 메시지 형식 적용 (예: JIRA 티켓) |
post-merge |
병합 성공 후 | 서브모듈 업데이트, 종속성 새로 고침 |
post-checkout |
체크아웃 성공 후 | 환경 구성 전환 |
요약 및 다음 단계
클라이언트 측 Git 훅은 반복적인 작업을 자동화하고 로컬 품질 표준을 개발 환경에서 직접 적용할 수 있는 제로 오버헤드 방법을 제공합니다. 이는 부주의한 커밋 및 통합 문제에 대한 중요한 첫 번째 방어선 역할을 합니다.
효과적으로 사용하려면 다음을 수행하십시오.
- 반복 작업 식별: 커밋하거나 병합하기 전에 수동으로 수행하는 검사를 결정합니다.
.git/hooks찾기: 프로젝트에서 이 디렉터리로 이동합니다.- 활성화 및 스크립팅:
.sample파일을 복사하고, 이름을 바꾸고, 실행 가능하도록 보장(chmod +x)한 다음 자동화 논리를 작성합니다. - 관리 도구 고려: 팀의 경우,
pre-commit과 같은 도구를 조사하여 개발자 간의 훅 설치를 동기화하십시오.