- Conventional Commits는 <type>[optional scope]: <description> 형식으로 커밋 메시지에 의미를 부여하려 하지만, 변경 유형을 앞세우고 범위를 선택사항으로 둬 실제 탐색에 필요한 정보를 뒤로 미룸
- 기여자·디버거·장애 대응자는 커밋 로그에서 변경이 닿은 코드 영역을 찾으며, 버그는 어떤 유형의 변경에서도 생길 수 있어 범위(scope) 가 유형보다 중요함
- fix(compiler): prevent namespaced SVG <style> elements from being stripped처럼 설명만으로도 버그 수정 성격을 알 수 있고, refactor(core): Update webmcp support to use document.modelContext처럼 한 커밋이 수정·리팩터링·기능 추가에 걸칠 수 있어 type이 중복적이고 제한적임
- 자동 CHANGELOG 생성과 시맨틱 버전 증가 판단은 커밋 로그와 변경 로그의 독자가 다르고, 되돌리기·우발적 하위 호환성 깨짐·나중의 깨짐 해소 때문에 결과가 어긋날 수 있음
- 범위 접두사 커밋 메시지는 변경 주체를 먼저 보여 주며, 빌드·배포 조건도 제목 유형보다 git diff로 바뀐 파일을 기준으로 삼는 편이 낫음
잘못된 우선순위
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
- 제목 줄은 fix, feat, chore, docs, refactor 같은 <type>, 선택적 scope, description으로 구성됨
- 핵심 결함은 변경의 주체인 scope보다 변경 종류인 type을 우선하는 구조임
- scope가 선택사항인 구조는 커밋에서 가장 중요한 정보가 빠질 수 있게 만들고, type을 제목 맨 앞에 둬 우선순위를 뒤집음
scope가 type보다 중요한 이유
- 기여자는 마지막 기여 이후의 변화, 프로젝트의 전체 흐름, pull이나 rebase 때 진행 중인 작업과 충돌할 수 있는 커밋을 찾기 위해 커밋 로그를 읽음
- 디버거는 버그가 드러난 컴포넌트와 관련된 영역을 건드린 변경을 찾으며, 버그는 어떤 type의 변경에서도 생길 수 있어 type 정보가 도움이 되지 않음
- 장애 대응자는 장애 시점 주변의 커밋 로그를 훑어 문제를 일으킨 영역을 찾으며, 인바운드 API 오류 급증 지점에 auth scope 커밋이 있으면 유력한 원인 후보가 됨
- 커밋 로그를 읽는 사람에게 중요한 정보는 변경이 어떤 종류였는지가 아니라 어떤 영역을 건드렸는지임
type의 중복성과 제한
자동화 약속의 한계
- git-cliff나 conventional-changelog 같은 도구로 커밋에서 CHANGELOG를 자동 생성하는 발상은 커밋 로그와 변경 로그의 독자가 다르다는 문제를 가짐
- CHANGELOG는 사용자 대상이며 버전 간 기능적·비즈니스적 차이를 이해하는 데 초점이 있음
- 커밋 로그는 개발자 대상이며 코드베이스가 시간에 따라 어떻게 바뀌었는지와 scope 관점의 흐름을 읽는 데 초점이 있음
- 중간 이상의 복잡도를 가진 프로젝트에서는 의미 있는 기능 하나가 여러 커밋으로 들어가며, 개발자에게는 구현 과정이 유용하지만 최종 사용자에게는 새 기능 자체만 중요함
- 되돌리기(revert) 커밋은 개발자에게 커밋 로그의 흐름상 중요하지만, 최종 사용자에게는 되돌려진 변경이 만들어지지 않은 변경과 같음
- 커밋 type에 기반한 시맨틱 버전 증가는 하위 호환성을 깨는 변경이 되돌려졌는데도 major 버전을 올리거나, 나중에야 깨짐을 알아차려 minor/patch로 잘못 올리거나, 후속 커밋과 합쳐져 깨짐이 사라졌는데도 깨짐으로 판단하는 문제를 만들 수 있음
- 이런 상황에서 rebase로 히스토리를 고칠 수는 있지만, 워크플로가 이를 막거나 깨뜨릴 수 있고 커밋 로그가 전하는 흐름의 신뢰성을 낮춤
- 커밋 제목 type으로 빌드·배포 프로세스를 트리거하면 docs: fix typos라는 제목의 커밋이 인증 서브시스템에 취약점을 넣는 식으로 자동 도구를 우회할 수 있음
- 빌드·배포 조건은 커밋 제목보다 git diff로 변경 파일을 식별해 정하는 편이 낫음
적용 문제와 대안
- Conventional Commits는 프로젝트별 type 집합을 정의하게 하지만, 많은 프로젝트가 commitlint의 기본 type을 그대로 가져가며 개별 프로젝트 특성과 잘 맞지 않을 수 있음
- Conventional Commits 명세는 기술적으로 fix와 feat만 정의하고 추가 type은 프로젝트에 맡김
- 기업 환경에서는 변경 관리와 감사 요구로 모든 커밋 메시지에 티켓 번호를 넣어야 하는 경우가 있으며, <scope>가 티켓 번호 자리로 쓰이면 유용한 metadata가 사라짐
- Linux, FreeBSD, Git, Go, NixOS, Node.js는 프로젝트에 맞는 scope 접두사 커밋 메시지를 사용함
- Linux 커널에서는 subsystem, Go 프로젝트에서는 package path, 마이크로서비스 아키텍처에서는 microservice 이름이 자연스러운 scope가 됨
- scopedcommits.com은 커밋 메시지에서 scope 중심 형식으로 돌아가고, CHANGELOG 생성과 커밋 로그 관리를 분리하자는 방향을 다룸
- Conventional Commits의 장점은 실제 이점으로 이어지지 않았고, 오픈소스 프로젝트에서의 인기와 AI의 기본 선택 경향이 안티패턴이 섞인 커밋 메시지 확산을 낳음