Husky 사용법: Git Hook으로 커밋 메시지 규칙 자동화하기

댓글 4
댓글을 작성하려면 로그인이 필요합니다.

오오.... git hook 설정!

댓글을 작성하려면 로그인이 필요합니다.

오오.... git hook 설정!
우리 팀의 커밋 메시지는 얼마나 통일되어 있을까?
Git Log를 열어보면 생각보다 다양한 메시지를 만날 때가 있다.
feat: 로그인 기능 추가
fix: 로그인 오류 수정
로그인 수정
버그 수정
작업중
팀에서 feat, fix, refactor 같은 규칙을 정해두더라도 결국 커밋하는 사람이 매번 기억해야 한다.
사람이 기억해야만 지켜지는 규칙이라면 언젠가는 빠질 수밖에 없다.
커밋 규칙을 잘 지켜달라고 말하는 대신, 커밋하는 순간 자동으로 검사하게 만들 수는 없을까?
이 문제를 해결할 때 사용할 수 있는 것이 Git Hook과 Husky다.
Git Hook은 Git에서 특정 동작이 발생했을 때 원하는 스크립트를 실행할 수 있는 기능이다.
| Hook | 실행 시점 | 활용 예시 |
|---|---|---|
pre-commit | 커밋이 생성되기 전 | ESLint, Prettier |
commit-msg | 커밋 메시지가 작성된 후 | 커밋 메시지 검사 |
pre-push | Push 직전 | 테스트, 타입 검사 |
Husky는 이런 Git Hook을 프로젝트 안에서 관리할 수 있도록 도와주는 도구다.
즉 Husky가 직접 코드를 검사하거나 커밋 메시지를 검사하는 것은 아니다.
Husky의 역할은 Git의 특정 시점에 원하는 명령어를 실행하는 것이다.
먼저 Husky를 설치한다.
npm install --save-dev husky
Husky 공식 문서에서 권장하는 초기화 방식은 husky init이다.
npx husky init
초기화하면 .husky/pre-commit 파일이 생성되고 package.json에는 Husky 설정을 위한 prepare 스크립트가 추가된다.
대략 이런 구조가 된다.
project/
├── .husky/
│ └── pre-commit
├── package.json
└── ...
예를 들어 .husky/pre-commit에 다음 명령을 넣을 수 있다.
npm run lint
이제 git commit을 실행하면 바로 커밋되는 것이 아니라 먼저 lint가 실행된다.
git commit
↓
pre-commit
↓
npm run lint
↓
Commit
여기까지가 Husky의 기본 역할이다.
처음 이야기했던 문제는 커밋 메시지의 통일성이었다.
Husky는 Hook을 실행할 뿐, 메시지가 올바른지는 판단하지 않는다. 이 역할은 commitlint에게 맡길 수 있다.
npm install --save-dev @commitlint/cli @commitlint/config-conventional
프로젝트 루트에 설정 파일을 만든다.
// commitlint.config.mjs
export default {
extends: ['@commitlint/config-conventional'],
}
그리고 .husky/commit-msg에서 commitlint를 실행한다.
npx --no -- commitlint --edit "$1"
이제 다음과 같은 메시지는 규칙을 통과한다.
feat: 로그인 기능 추가
fix: 로그인 오류 수정
refactor: 인증 로직 분리
반대로 이런 메시지는 커밋 단계에서 막을 수 있다.
로그인 수정
작업중
fix
결국 팀원이 컨벤션 문서를 매번 기억하는 대신, 잘못된 커밋 메시지가 만들어지는 순간 바로 피드백을 받게 된다.
커밋 메시지를 검사했다면 코드도 커밋 전에 검사할 수 있다.
가장 단순한 방법은 pre-commit에서 프로젝트 전체 lint를 실행하는 것이다.
하지만 파일 하나만 수정했는데 전체 프로젝트를 검사할 필요는 없다.
이때 lint-staged를 사용할 수 있다.
npm install --save-dev lint-staged
package.json에 검사 대상을 지정한다.
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": "eslint --fix",
"*.{json,md,css}": "prettier --write"
}
}
그리고 .husky/pre-commit에서는 lint-staged를 실행한다.
npx lint-staged
그러면 이번 커밋에 포함되는 staged 파일만 검사한다.
git add
↓
git commit
↓
pre-commit
↓
lint-staged
↓
ESLint / Prettier
프로젝트 전체를 검사하는 것보다 커밋 흐름을 가볍게 유지할 수 있다.
Husky를 처음 사용하면 commitlint, lint-staged, ESLint의 역할이 섞여 보일 수 있다.
| 도구 | 역할 |
|---|---|
| Husky | Git Hook에서 명령 실행 |
| commitlint | 커밋 메시지 규칙 검사 |
| lint-staged | staged 파일에 명령 실행 |
| ESLint | 코드 규칙 검사 |
| Prettier | 코드 포맷 정리 |
전체 흐름은 다음과 같다.
git commit
|
+-- pre-commit
| +-- lint-staged
| +-- ESLint
| +-- Prettier
|
+-- commit-msg
+-- commitlint
Husky가 모든 것을 검사하는 것이 아니다.
Git과 각각의 검사 도구를 연결하는 역할이라고 이해하면 훨씬 쉽다.
Husky를 사용한다고 해서 테스트, 빌드, 타입 검사까지 모두 pre-commit에 넣는 것이 좋은 것은 아니다.
커밋할 때마다 오래 기다려야 한다면 오히려 개발 흐름을 방해한다.
나는 다음 정도로 역할을 나누는 편이 좋다고 생각한다.
pre-commit
→ 변경 파일 Lint / Format
commit-msg
→ Commit Convention
CI
→ 전체 Lint / Type Check / Test / Build
로컬 Hook의 목적은 모든 것을 보장하는 것이 아니라 실수를 최대한 빠르게 발견하는 것에 가깝다.
팀에서 규칙을 만드는 것은 어렵지 않다.
어려운 것은 그 규칙을 모든 사람이 계속 기억하고 지키는 것이다.
Husky를 사용하면 “커밋 메시지를 규칙에 맞게 작성해주세요”라고 반복해서 말하는 대신, 커밋이 만들어지는 순간 규칙을 확인할 수 있다.
여기에 commitlint와 lint-staged를 연결하면 커밋 메시지뿐 아니라 실제 커밋될 코드도 같은 흐름에서 검사할 수 있다.
반복해서 지켜야 하는 규칙이라면, 사람에게 기억시키기 전에 자동화할 수 있는지 먼저 확인해보자.
지금 작업 중인 프로젝트의 git log를 한번 열어보자. 팀에서 정한 규칙과 실제 커밋 메시지가 얼마나 닮아 있는지 확인하는 것부터 시작하면 된다.

우리들의 게임 발매 이야기

안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다


안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다

놀라운 생명체 발견...!
좋은 것 가져왔습니다! ㅎㅎ
잘 왔어요~ 반가워요 ㅎ