Conventional Commits에 반대하는 논거: 왜 Scope가 Type보다 중요한가
Conventional Commits는 잘못된 메타데이터를 우선시한다
Conventional Commits는 변경의 type(예: fix, feat, chore)보다 scope(영향을 받는 코드베이스의 특정 영역)를 우선시하지 않기 때문에 적극적으로 나쁜 표준입니다. 실제로, scope는 커밋 로그에 의존하는 이해관계자들에게 가장 중요한 정보입니다.
Scope가 Type보다 중요한 이유
커밋 히스토리의 주요 사용자들에게는 무엇이 변경되었는지(what)를 아는 것이 어떻게 분류되었는지(how)를 아는 것보다 훨씬 더 가치 있습니다.
- Contributors: 프로젝트의 관성을 파악하거나 rebasing 중에 발생할 수 있는 잠재적 충돌을 식별하기 위해 코드의 특정 영역에서의 변경 사항을 파악해야 합니다.
- Debuggers: 버그가 발생한 컴포넌트와 관련된 변경 사항을 검색해야 합니다. 버그는 어떤 변경 유형(bugfixes 포함)에 의해서도 발생할 수 있으므로,
type레이블은 격리(isolation)에 도움이 되지 않습니다. - Incident Responders: 운영 중 장애가 발생했을 때 로그를 스캔하여 에러 급증과 상관관계가 있는 특정 서브시스템(예:
authscope)에 가해진 변경 사항을 찾습니다.
Conventional Commits는 scope를 선택 사항으로 만들어, 변경의 주제를 카테고리보다 부차적인 것으로 취급합니다. 게다가, type은 종종 중복적입니다. "prevent namespaced SVG style elements from being stripped"와 같이 잘 작성된 설명은 fix: 접두사 없이도 그것이 수정 사항임을 본질적으로 전달합니다.
자동화 약속의 실패
Conventional Commits는 실제 소프트웨어 엔지니어링 시나리오에서 종종 실현되지 못하는 몇 가지 자동화 이점을 약속합니다.
자동화된 Changelog
커밋 메시지에서 직접 changelog를 생성하는 것은 두 가지 서로 다른 대상(audience)을 혼동하는 것입니다. commit log는 개발자 대상이며 코드베이스가 어떻게 진화했는지에 대한 이야기를 추적합니다. changelog는 사용자 대상이며 비즈니스 관점에서 기능적 차이를 설명해야 합니다 합니다.
단일 기능(feature)을 구현하기 위해 여러 개의 커밋이 필요한 경우가 많기 때문에, 자동화된 도구는 최종 사용자에게 무용지물인 노이즈가 많고 세밀한 로그를 생성합니다. 또한, revert는 문제가 됩니다. revert는 개발자의 히스토리에는 필수적이지만, 사용자가 보기에는 변경 사항이 전혀 이루어지지 않은 것과 같으므로 보이지 않아야 합니다.
Semantic Versioning (SemVer) 자동화
커밋 유형을 사용하여 major, minor, 또는 patch 버전 업을 트리거하는 것은 개발의 복잡성 때문에 신뢰할 수 없습니다.
- Reverts: 즉시 revert된 breaking change는 자동화 도구에서 여전히 major 버전 업을 트리거할 수 있습니다.
- Accidental Breakages: 미묘한 breaking change가 patch로 잘못 분류되어 잘못된 버전 관리가 이루어질 수 있습니다.
- Retroactive Fixes: 후속 커밋이 이전의 breaking change를 무효화할 수 있지만, 도구는 이미 버전 업을 표시했을 것입니다.
빌드 및 배포 트리거
커밋 유형을 기반으로 보안 체크나 빌드를 트리거하는 것(예: docs:를 위해 체크를 건너뛰는 것)은 보안 위험입니다. 악의적인 공격자가 취약점을 유발하는 커밋을 docs: fix typos라고 레이블링하여 자동화된 도구를 우회할 수 있습니다.
대안: Scope-Prefixed Commits
경직적인 스키마를 따르는 대신, Linux, FreeBSD, Git, Go, and NixOS를 포함한 성공적인 대규모 프로젝트들은 scope-prefixed 메시지를 활용합니다. 이러한 프로젝트에서 scope는 프로젝트의 자연스러운 아키텍처(예: 서브시스템, 패키지 경로, 또는 마이크로서비스 이름)에 의해 정의됩니다.
| Project | Format | Example |
| :--- | :--- | :--- | |
| Linux | subsystem: description | i2c: virtio: mark device ready before registering the adapter |
| Go | package: description | net/http/cookiejar: add godoc links |
| Git | area: description | gitlab-ci: update macOS image |
| FreeBSD | prefix: Description | linuxulator: Return EINVAL for invalid inotify flags |
| nixpkgs | pkg-name: description | xwayland: 24.1.11 -> 24.1.12 |
커뮤니티 관점 및 반론
Conventional Commits에 대한 비판은 날카롭지만, 커뮤니티의 개발자들은 그 유효성에 대해 다양한 관점을 제시합니다.
Conventional Commits를 옹호하는 논거
- CI/CD Necessity: 99%의 프로젝트에서 SemVer를 자동으로 태깅하고 main으로의 모든 merge를 통해 배포할 수 있는 능력은 형식의 이론적 결함함보다 더 큰 가치를 가 가집니다.
- Enforcement for Junior Devs: 일부 유지보수자들은 pre-commit hooks를 통해 강제하기 쉽기 때문에 Conventional Commits를 사용합니다. 이는