협업 프로젝트에서 커밋 메시지를 잘 쓰자는 말은 누구나 한 번쯤은 들어봤을 것이다. 하지만 “잘 쓰자”는 말은 너무 추상적이다. 어떻게 쓰는 게 ‘잘’ 쓰는 것이고, 왜 그렇게까지 구조를 맞춰야 하는 걸까?
이 글은 내가 Apple Academy에서 팀 프로젝트를 진행하며 커밋 메시지를 구조화하고, 이를 점진적으로 자동화하며 팀 전체에 강제하게 된 배경과 과정을 공유하려는 목적에서 썼다.
시작은 작은 불편함이었다
팀원들과 작업을 병행하다 보면, 과거의 변경사항을 다시 살펴야 하는 경우가 자주 생긴다. 예를 들어, 특정 UI가 언제 바뀌었는지, 어떤 이유로 메서드 명이 바뀌었는지 등을 추적하려 할 때 git log, git blame, git grep을 사용하게 된다.
그런데 커밋 메시지가 다음과 같다면?
qwer수정함readme 수정끝!!이 메시지들만 보고서는 도대체 왜, 무엇 때문에 고쳤는지 알 수 없다. 결국 코드를 다시 뜯어봐야 하고, 히스토리는 전혀 도움이 되지 않는다.
검색이 가능한 히스토리를 만들어야 했다.
내가 정한 커밋 메시지 구조
<TYPE>. 요약 설명또는 이모지를 붙인 버전도 허용한다:
📝 <TYPE>. 요약 설명- TYPE은 대문자로 시작 (예: Fix, Docs, Refactor 등)
- 마침표 뒤에는 반드시 공백
- Gitmoji 스타일을 좋아하기 때문에 많이 참고하기도 했다.
본문
Why:- 왜 이 변경을 했는가
How:- 무엇을 어떻게 바꿨는가선택적으로 아래 내용을 추가하기도 했다
Tags:- UI, Accessibility 등
See:- [Figma 링크]- [DE-1111 이슈 링크]
Co-authored-by: 이름 <email@domain.com>How:는 실제 diff나 코드 변경으로도 어느 정도 유추할 수 있기 때문에, 모든 경우에 반드시 작성해야 한다고 보지는 않는다. 팀이나 개인의 스타일에 따라 적절히 조절할 수 있을 것 같으나, 나는 이 템플릿의 영향을 많이 받았던 터라…
또한 로컬 저장소 수준이 아닌, 사용자 전체 Git 설정으로도 템플릿을 적용할 수 있다는 점도 유용하다.
예를 들어 아래와 같이 설정하면, 커밋 메시지 작성 시 자동으로 템플릿이 로드된다 (특정 GUI의 경우에는 미지원)
git config --global commit.template ~/.git-commit-template.txt귀여운 기능으로는 Co-authored-by:도 있다. 커밋에 여러 사람의 이름을 넣고 싶은 경우, 본문에 이 줄을 추가하면 GitHub에서 자동으로 함께한 사람으로 인식해준다. 도움을 받았는데, 혼자 작업한 것처럼 보이기 아쉬울 땐 살짝 써주는 것도 소소한 즐거움이다.
이 구조는 git log 또는 git grep Why: 처럼 검색할 때 매우 강력한 이점을 준다.
예시 커밋 메시지
🐛 Fix. 로그인 실패 시 예외처리 추가
Why:- 빈 토큰에서 앱이 크래시 발생
How:- if 조건문 보호 및 로그 출력 추가Tags: #auth #bugfix태그를 #과 함께 문단의 첫 글자로 붙이면 주석처리 되어 커밋에서는 보이지 않게 된다. 주의하자.
📝 Docs. 컴포넌트 구조 개선
Why:- View 네이밍 통일
How:- CycleView → CycleProgressView로 변경
Tags:- UISee:- [Figma](https://figma.com/___)
Tags: #ui #docs
See: https://figma.com/...
Co-authored-by: 이름 <email@example.com>안 되는 메시지 예시
readme 수정fix: 로그인 고침이런 커밋은 팀에서 아예 막히도록 설정했다.
어떻게 강제했는가
1단계: setup-githooks.sh로 훅 직접 설치 (C3 시기)
초기에는 Git의 commit-msg 훅을 직접 관리하는 스크립트를 작성해서, 형식에 맞지 않는 커밋 메시지는 아예 막아버렸다.
setup-githooks.sh스크립트를 만들어.git/hooks/commit-msg에 복사- 훅은 메시지의 제목 형식과
Why:,How:필드의 존재를 체크함
bash setup-githooks.sh❌ 제목 형식 오류:👉 제목은 'Type. 요약 설명' 또는 '📝 Type. 요약 설명' 형식이어야 합니다.
❌ 본문 누락:👉 Why:, How: 섹션이 모두 포함되어야 합니다.
⚠️ 제목 요약이 42자입니다 (30자 이내 권장)원래는
husky같은 Node.js 기반 도구도 고려했지만, Swift 프로젝트라는 특성상 팀원들에게 Node 환경 설치를 요구하고 싶지 않았다. 때문에 최대한 Bash 기반으로 가볍게 구성했다.
2단계: Makefile + Lefthook 으로 전환 (C4 시기)
다음 프로젝트(C4)에서는 팀원 중 비개발자나 Git CLI에 익숙하지 않은 iOS 개발자도 많았기 때문에, .sh 파일 실행 권한 부여조차 허들이 되었다.
Swift 프로젝트 특성상 애플 생태계(macOS)에서 작업하는 점을 고려해, make setup으로 모든 설정이 한 번에 되도록 Makefile 중심으로 전환했다.
make setup시lefthook설치 및 설정 자동화commit-msg와pre-commit훅을 함께 관리하도록 통합.lefthook.yml로 훅 스크립트 정의 및 버전 관리 가능
팀 적용 방식은 이렇게 했다
- Notion이나 Wiki 문서로 규칙을 공유하고 템플릿 예시를 배포했다
- 팀원들이 직접
.gitmessage.txt를 적용하지 않아도 되도록make setup한 줄로 커밋 템플릿과 린트가 적용되게 했다 - 브랜치명 린트, SwiftFormat 자동 실행 등 다른 훅들과 함께 통합해서 도입함으로써 “커밋 전 자동검사”가 자연스러운 흐름이 되도록 만들었다
어떤 변화가 생겼는가?
git log로 바뀐 이유를 빠르게 파악 가능- 검색 (
git grep,log --grep)이 쉬워짐 - 코드리뷰 시 커밋 메시지만 보고도 컨텍스트 파악 가능
- GPT나 자동 릴리즈 도구와도 더 쉽게 연동 가능해짐
무엇보다도, “왜 고쳤더라?”라는 질문에 답하는 시간이 줄어들었다.
참고: 테스트 커밋
git commit --allow-empty -m "Fix. 로그인 고침"# → ❌ 오류 출력
# ❌ 오류 메시지 예시:# 제목 형식 오류:# 👉 제목은 'Type. 요약 설명' 또는 '📝 Type. 요약 설명' 형식이어야 합니다.
# 본문 누락:# 👉 Why:, How: 섹션이 모두 포함되어야 합니다.
# 제목 요약이 42자입니다 (30자 이내 권장)git commit --allow-empty -m "Fix. 로그인 처리 개선\n\nWhy:\n- 사용자 피드백 반영\n\nHow:\n- 조건 분기 및 메시지 보강"# → ✅ 성공이 커밋 메시지 구조는 아직도 완성형은 아니지만 구조를 갖추기 시작하면서, 우리 팀의 기록은 분명 더 검색 가능하고, 읽기 쉬운 기록이 되었다.