[Git] Commit Message Conventions

Hood·2025년 10월 15일

Github

목록 보기
5/5
post-thumbnail

들어가기 전

Git에서 커밋은 보통 하나의 의미 있는 변경 단위로 나누어 작성합니다.
그리고 커밋 메시지는 그 변경 사항이 무엇인지 빠르게 이해할 수 있도록 명확하고 일관성 있게 작성하는 것이 중요합니다.

이러한 이유로 많은 팀에서는 커밋 컨벤션(commit convention) 을 사용합니다.
커밋 컨벤션은 변경 사항을 쉽게 파악할 수 있게 도와주고,
프로젝트 히스토리를 일관되게 관리하거나 자동화 도구와 연동할 때도 도움이 됩니다.

이번 글에서는
AngularJS Git Commit Message Conventions
문서를 참고해 커밋 메시지 형식을 정리해보겠습니다.


커밋 메시지 구조

위 컨벤션에서는 커밋 메시지를 보통
유형(Type), 범위(Scope), 제목(Subject) 으로 구조화합니다.

커밋 메시지 형식

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

즉, 한 줄 제목만 간단히 쓰는 경우도 있지만,
필요하다면 본문(body)과 바닥글(footer)까지 함께 작성해
변경 이유와 추가 정보를 더 자세히 남길 수 있습니다.


유형(Type)

가장 앞에 오는 type
이번 커밋이 어떤 종류의 변경인지를 나타냅니다.

대표적으로 많이 사용하는 유형은 다음과 같습니다.

  • feat: 새로운 기능 추가
  • fix: 버그 수정
  • docs: 문서 수정
  • style: 코드 포맷팅, 세미콜론, 공백 등 기능 변화가 없는 스타일 수정
  • refactor: 기능 변화 없이 코드 구조를 개선하는 리팩터링
  • test: 테스트 코드 추가 또는 수정
  • chore: 빌드 설정, 패키지 매니저 설정, 기타 자잘한 작업

패키지 매니저란?

특정 플랫폼에서 소프트웨어 패키지를 설치하고 관리하는 도구를 말합니다.

프로덕션 코드란?

실제로 사용자에게 배포되어 서비스에서 동작하는 코드를 말합니다.


범위(Scope)

scopetype 뒤의 괄호 () 안에 작성하며,
어느 부분이 변경되었는지를 나타냅니다.

예를 들어 특정 모듈, 도메인, 컴포넌트 이름 등을 넣을 수 있습니다.

feat(auth): 로그인 기능 추가
fix(user): 프로필 이미지 조회 오류 수정

다만 scope필수는 아니며 선택사항입니다.
변경 범위를 함께 적으면 커밋을 더 빠르게 이해하는 데 도움이 됩니다.


제목(Subject)

subject는 변경 사항을 한 줄로 간단하게 설명하는 부분입니다.
보통 아래 규칙을 많이 따릅니다.

  • 명령형 또는 현재형에 가깝게 작성합니다.
  • 첫 글자를 대문자로 시작하지 않습니다.
  • 끝에 마침표(.)를 붙이지 않습니다.
  • 짧지만 무엇을 변경했는지 알 수 있게 작성합니다.

예를 들면 아래와 같습니다.

feat: 게시글 좋아요 기능 추가
fix: 로그인 시 null 예외 수정
refactor: 회원 조회 로직 분리

본문(Body)

본문은 왜 이 변경이 필요했는지,
그리고 이전과 무엇이 달라졌는지를 설명할 때 사용합니다.

모든 커밋에 꼭 본문이 필요한 것은 아니지만,
변경 이유를 함께 남겨야 나중에 히스토리를 이해하기 훨씬 쉬워집니다.

예를 들어 아래처럼 작성할 수 있습니다.

fix: 로그인 시 null 예외 수정

사용자 정보가 없는 경우에도 인증 로직이 실행되면서
NullPointerException이 발생하던 문제를 수정한다.
존재 여부를 먼저 확인한 뒤 인증 로직을 수행하도록 변경한다.

추가로 커밋 메시지 작성 방식에 대해 더 자세히 보고 싶다면
Git 커밋 메시지 작성
자료도 함께 참고해보면 좋습니다.


바닥글(Footer)

footer에는 이 커밋과 관련된 이슈 번호나
중요한 참고 사항을 작성합니다.

예를 들어 특정 이슈를 닫는 커밋이라면 아래처럼 쓸 수 있습니다.

Closes #234

여러 이슈를 함께 닫는 경우에는 다음과 같이 작성할 수 있습니다.

Closes #123, #245, #992

프로젝트에 따라 footer에는
마이그레이션 정보나 주요 변경 사항을 함께 남기기도 합니다.


기능(Feature)이란 무엇일까요?

커밋 메시지를 작성하기 전에 먼저
기능의 경계를 어떻게 볼 것인지 생각해보는 것이 중요합니다.

여기서 기능은 단순히 메서드 하나를 추가하는 수준이 아니라,
사용자 또는 시스템 관점에서 의미 있는 가치를 제공하는 작업 단위로 보는 것이 더 적절합니다.

즉, 사용자가 직접 체감할 수 있는 변화이거나
시스템의 동작에 분명한 영향을 주는 변경이라면
하나의 기능으로 볼 수 있습니다.


예를 들어 보면

1. 사용자 스토리를 구현한 경우

예를 들어
“사용자는 게시글에 좋아요를 누를 수 있다”
라는 요구사항을 구현했다면,
이것은 사용자 입장에서 의미 있는 기능 추가입니다.

이 경우 커밋 메시지는 아래처럼 작성할 수 있습니다.

feat: 게시글 좋아요 기능 추가

2. 새로운 API 엔드포인트를 개발한 경우

예를 들어 특정 사용자의 게시글 목록을 조회하는
/users/{userId}/posts API를 개발했다면,
이 역시 하나의 기능 단위로 볼 수 있습니다.

이 경우에는 다음처럼 작성할 수 있습니다.

feat(users): 특정 사용자 게시글 목록 조회 API 추가

기능으로 보기 어려운 경우

반대로 아래와 같은 작업은 보통 feat보다는
다른 타입이 더 어울리는 경우가 많습니다.

1. 단순 헬퍼 메서드 추가

예를 들어 문자열 앞뒤 공백을 제거하는 유틸리티 메서드를 추가한 경우,
그 자체만으로는 사용자 관점의 기능이라고 보기 어렵습니다.

이럴 때는 상황에 따라
더 큰 기능 구현의 일부로 묶거나,
refactor 또는 chore로 표현하는 편이 더 자연스러울 수 있습니다.

2. 변수명 변경이나 코드 구조 개선

예를 들어 user_iduserId로 바꾸거나,
동작은 그대로 두고 코드 구조만 정리한 경우에는
보통 refactor 또는 style이 더 적절합니다.


🤔 커밋을 잘게 나누고 싶다면?

커밋을 작성하다 보면 이런 고민이 생길 때가 있습니다.

기능 구현이 완전히 끝나지 않았는데,
이 상태도 커밋으로 남겨도 괜찮을까?

저 역시 예전에는 하나의 기능이나 하나의 API 구현이 끝났을 때
커밋을 남기는 편이었습니다.
그런데 이렇게 하다 보면 변경 폭이 커져서,
문제가 생겼을 때 원인을 추적하는 데 시간이 오래 걸리는 경우가 있었습니다.

그래서 최근에는 커밋을 조금 더 작게 나누는 방식에 관심을 가지게 되었습니다.
다만 너무 잘게 나누면 하나의 기능 아래 커밋이 지나치게 많아져
히스토리가 오히려 복잡해질 수도 있습니다.

결국 여기에 절대적인 정답이 있는 것은 아니고,
팀의 스타일과 본인의 작업 방식에 맞는 기준을 잡는 것이 중요하다고 생각합니다.

예를 들어 저는 아래와 같은 기준을 고민해보고 있습니다.

  • 이전 커밋과 비교했을 때 유의미한 변화가 있다면 따로 커밋하기
  • 테스트를 통해 정상 동작을 확인했다면 커밋하기
  • 별도 기능 작업 중 오류가 생겼다면, 수정한 뒤 의미 있는 단위로 다시 커밋하기

결국 많이 작성해보면서
본인만의 기준을 만들어가는 것이 가장 현실적인 방법이라고 생각합니다.

또 너무 컨벤션이나 원칙 자체에만 집착하기보다는,
먼저 기능 구현과 요구사항 충족에 집중한 뒤,
그다음 커밋 메시지를 일관되게 정리해가는 것이 더 중요하다고 생각합니다.


마무리하며

커밋 메시지를 작성하기 전에는
스스로에게 한 번 질문을 던져보는 것이 도움이 됩니다.

무엇이 달라졌는가?

예를 들면 이렇게 생각해볼 수 있습니다.

  • 사용자에게 새로운 가치가 생겼는가? → feat
  • 기존 문제가 해결되었는가? → fix
  • 코드가 더 깔끔하고 효율적으로 바뀌었는가? → refactor

커밋 메시지는 단순히 형식을 맞추기 위한 것이 아니라,
변경의 의미를 팀원과 미래의 나에게 전달하는 기록이라고 생각합니다.

그래서 너무 어렵게 접근하기보다는,
“이 커밋이 어떤 변화를 담고 있는지 한눈에 이해할 수 있는가?”
를 기준으로 작성해보면 훨씬 도움이 됩니다.

profile
달을 향해 쏴라, 빗나가도 별이 될 테니 👊

0개의 댓글