발행일

Git 커밋 메시지 잘 쓰는 법 — 그리고 내 저장소 2년치로 검증해 본 결과

Git 커밋 메시지 잘 쓰는 법

커밋 메시지는 코드 변경의 의미와 이유를 기록하는 짧은 설명입니다. 잘 작성된 메시지는 코드 리뷰, 히스토리 파악, 장애 대응 시 원인 추적을 쉽게 만들어줍니다. 규칙 정리를 앞에 두고, 제 저장소 2년치로 이 규칙들을 검증해 본 결과를 뒤에 붙였습니다.

기본 형식 (Conventional Commits)

<type>(<scope>): <subject>

<body>

<footer>
구성필수설명
type필수커밋 종류
scope선택변경 범위 (모듈·화면 등)
subject필수변경 요약 (50자 이내)
body선택변경 이유·상세 (행당 72자)
footer선택이슈 번호, 참고
타입사용 상황
feat / fix기능 추가 / 버그 수정
docs / style문서 / 포맷(로직 무변경)
refactor / test리팩터링(동작 무변경) / 테스트
chore빌드·설정·의존성 등

작성 규칙

  • 제목과 본문은 빈 줄로 구분
  • 제목 50자, 본문 행당 72자
  • 명령형·현재형 (Change O, Changed X) — 끝에 마침표 없음
  • 무엇을 바꿨는지보다 왜 바꿨는지가 본문의 몫
refactor(api): 중복된 인증 미들웨어 통합

인증 로직이 각 뷰마다 흩어져 있어
공통 데코레이터로 분리하여 중복 제거
나쁜 예좋은 예
수정함fix: 로그인 토큰 만료 오류 수정
작업 중feat(auth): 카카오 소셜 로그인 연동
여러 가지 변경커밋을 기능 단위로 분리

내 저장소 2년치로 검증해 본 결과

여기까지는 어느 컨벤션 문서에나 있는 이야기입니다. 이 글을 개고하게 된 계기는 따로 있어요 — 사이드 프로젝트(TripTune) 커밋 500여 개를 이력서·회고 재료로 전수 조사하면서, 위 "나쁜 예" 표를 제가 전부 실제로 저질렀다는 걸 확인했습니다. 그리고 나쁜 커밋의 비용이 언제 청구되는지도요.

실제로 저지른 것들

초기 커밋에는 이런 것들이 있습니다(전부 실제 메시지입니다):

  • 문서 준비 — 무슨 문서를, 왜?
  • 여러번 렌더링 되는 문제, 로그인 풀리는 문제, 로그아웃 안되는 이슈 수정 완료서로 다른 버그 세 개가 한 커밋. 이 중 하나만 롤백할 방법이 없습니다.
  • [24-09-06] 여행지 탐색 개선 (검색 post, 위도 경도 추가), 라이트 하우스 개선, seo 추가 — 제목에 날짜(git이 이미 아는 메타데이터의 중복)에, 관련 없는 작업 세 갈래가 또 한 커밋.

후기로 갈수록 fix: API 응답이 JSON이 아닐 때 에러 처리 추가, chore: 도메인 URL을 일괄 변경처럼 이 글의 형식에 수렴했는데, 규칙을 외워서가 아니라 초기 커밋 때문에 고생한 뒤였습니다.

비용이 청구되는 시점은 "나중"이다

나쁜 커밋의 문제는 쓸 때는 아무 비용이 없다는 겁니다. 청구서는 한참 뒤에 옵니다.

  1. 회고·이력서를 쓸 때. "이 버그를 언제 어떻게 고쳤지?"의 유일한 원천 데이터가 커밋 로그인데, 수정 완료 류의 커밋은 아무것도 증언해주지 않습니다. 2년 뒤의 저는 세 버그가 묶인 커밋 앞에서 diff를 다시 읽어야 했어요.
  2. 원인 추적(bisect)할 때. 세 가지 변경이 묶인 커밋은 bisect가 범인을 지목해도 "이 중 뭔데?"가 남습니다. 커밋 분리는 미래의 이등분 탐색을 위한 인덱싱이었습니다.
  3. 되돌릴 때. revert 단위 = 커밋 단위. 여러 가지 변경은 되돌리기의 최소 단위도 "여러 가지"로 만듭니다.

한국어 커밋에 규칙을 맞추며 정한 것

원문 규칙 중 "제목 첫 글자 대문자"는 영어 전제라 한국어 제목에는 적용할 게 없고, 명령형 규칙도 한국어에서는 명사형 종결("~수정", "~추가")로 자연스럽게 대응됩니다. 정착한 조합은 type·scope는 영어, subject는 한국어입니다 — 도구(체인지로그 생성, 커밋 lint)는 type을 파싱하고, 사람은 한국어 제목을 읽는 분업이에요.


한 줄 요약

커밋 메시지의 독자는 리뷰어가 아니라 2년 뒤의 나였습니다. 그 독자는 diff를 다시 읽고 싶어 하지 않습니다 — 를 50자 안에, 변경은 한 단위로.