Git commit 메세지 규약 — Conventional Commits

사람과 컴퓨터 모두 이해하기 쉬운 커밋 메세지

한지승
HASHBOX
6 min readJul 14, 2020

--

Photo by Yancy Min on Unsplash

git을 사용하면서 가장 많이 사용하는 명령어는 단연코 git commit -m "MESSAGE" 이지 않을까 싶습니다. 대부분 커밋 메세지는 해당 커밋이 어떠한 작업에 대한 커밋인지 메세지를 잘 적어야한다는 것은 알거라고 생각합니다. 하지만 이러한 기준은 주관적이다 보니 메세지의 내용은 오직 커밋을 한 사람만 알아볼 수 있는 메세지를 가진 커밋이 난무하는 걸 볼 수 있습니다.

이러한 문제는 협업을 하면서 더욱더 크게 느껴지게 됩니다. 필자는 이러한 주관적인 커밋 메세지들을 의미를 가질 수 있는 방법을 찾게 되었고 역시나 이러한 문제를 해결하기 위한 규칙인 Conventional Commits를 찾을 수 있었다. 이를 정리해보고자 합니다.

Conventional Commits

Conventional commits은 의미 그대로 ‘커밋 메세지 규약’이라 이해하면 됩니다. 홈페이지에서는 ‘커밋 메세지에 사용자와 기계 모두가 이해할 수 있는 의미를 부여하기 위한 스펙’이라는 부제로 설명되고 있습니다. 즉, 커밋 메세지를 작성하는 규약이며 이 규약은 사용자도 쉽게 이해할 수 있고, 컴퓨터적으로도 의미가 있도록 작성하는 규약을 의미합니다. 이를 통해서 커밋 메세지 규약에 따라 작성할 경우, 일반적으로 버전 관리로써 사용하는 Semantic Versioning 관리에도 쉽게 할 수 있습니다.

Semantic Versioning은 어플리케이션 릴리즈 버전을 명시하는 형태로 1.0.0과 같은 3개의 숫자로 이루어져 있습니다. 각각 Major, Minor, Patch에 대한 버전을 의미합니다. 뒤에서부터 Patch의 경우 버그, 이슈와 같은 기존 기능에 대한 수정을 의미하며, Minor 숫자는 새로운 기능 추가에 대한 버전을 관리합니다. 마지막으로 Major 숫자는 이전 버전과 호환이 되지 않을 정도로 새로운 변화에 대한 버전을 관리합니다. 자세한 사항은 위 링크를 통해 참고하시기 바랍니다.

Conventional commits에서 규약하고 있는 메세지 유형은 다음과 같습니다.

{타입}({적용 범위})!: {메세지}{본문}{꼬리말}

굵은 글씨는 필수 사항을 나타내며 이탤릭 글씨는 선택 사항을 나타냅니다. 정리하면 {타입}: {메세지} 는 필수 적인 사항이고, 그외 {적용 범위} 와 뒤에 따라오는! ,{본문}, {꼬리말} 은 선택 사항으로 필요에 따라 선택하면 됩니다.

타입

타입의 경우 해당 커밋의 성격이 무엇인지 나타내는 역할을 합니다. 대표적으로 사용하는 타입으로는 크게 featfix 가 있습니다. 순서대로 feat 는 feature를 축약형으로 쓴 의미이며 일반적으로 사용하는 새로운 기능에 대한 의미를 가지고 있습니다. 이는 Semantic Versioning에서 Minor 버전에 해당한다고 보시면 됩니다. 예상대로 fix 는 Patch 버전을 의미하는 형태로 이해하시면 됩니다. 이 외에 일반적으로 세분화하는 스타일로 build , chore, ci, docs, style, refactor, test 와 같은 타입을 사용합니다. 이러한 규약은 Angular Conveion을 기반하고 있으니 참고바랍니다.

  • feat : 새로운 기능에 대한 커밋
  • fix : 버그 수정에 대한 커밋
  • build : 빌드 관련 파일 수정에 대한 커밋
  • chore : 그 외 자잘한 수정에 대한 커밋
  • ci: CI 관련 설정 수정에 대한 커밋
  • docs : 도큐먼트에 수정에 대한 커밋
  • style : 코드 문법 또는 포맷에 대한 수정에 대한 커밋
  • refactor : 코드 리팩토링에 대한 커밋
  • test : 테스트 코드 수정에 대한 커밋

Major 버전에 대한 의미를 가진 표현은 이후 본문 절에서 설명하도록 하겠습니다.

적용 범위

적용 범위는 해당 커밋에 대한 부가적인 정보로 선택 사항입니다. 하지만 이러한 적용 범위를 명시하게 되면 해당하는 커밋이 어떤 범위에 대한 수정사항인지 이해하는데 도움이 되는 정보입니다. 개인적인 생각으로는 적용범위를 보고 어떤 부분에 대한 커밋인지 알 수 있도록 명기하는 것이 협업을 하는데 있어 도움이 될 것으로 보입니다.

메세지

메세지는 해당하는 커밋에대한 설명을 의미하며 일반적으로 Add review function 과 같이 현재형 동사로 표현하는 메세지로 적는 것이 일반적입니다. 최대한 메세지를 통해서 해당 커밋에 대한 요약할 수 있도록 적는 것이 좋습니다.

본문

본문은 {타입}(적용범위): 메세지 로 표현할 수 없는 상세한 내용을 적는 부분입니다. 그렇기 때문에 충분히 {타입}(적용범위): 메세지 로 표현이 가능하다면 생략이 가능합니다. 하지만 반드시 본문에 표현해야하는 경우가 있습니다. 앞서 미뤄 두었던 Major 버전에 대한 명시입니다.

본문에서 BREAKING CHANGE: 설명 을 작성하면 해당 커밋은 Major 적인 변화가 있음을 표현할 수 있습니다. 즉, 어떠한 부분이 큰 변화가 있기 때문에 어떠한 부분과 호환이 될 수 없음을 표현할 수 있습니다. 추가적으로 Major 변화에 대한 메세지가 본문에 있기 때문에 커밋 메세지에서 확인을 하지 못하고 넘어갈 가능성이 있기 때문에 {타입}(적용 범위): 를 명기할 때 (적용범위): 사이에 ! 를 명기함으로써 본문에 BREAKING CHANGE: 설명 이 있음을 표시할 수 있습니다.

예: feat(pipeline)!: Add pipeline function

꼬리말

꼬릿말은 해당 커밋이 어떤 이슈에서 왔는지와 같은 참조 정보들을 추가하는 용도로 사용합니다. 예를들어, 깃허브의 경우 해당 커밋으로 특정 이슈와의 연관을 표현하기 위해 close #123 과 같이 커밋 메세지의 추가하게 되는데 이러한 정보들을 마지막으로 넣으시면 됩니다. 또한 지라를 사용할 경우 refs FIB-123과 같이 달으시면 됩니다.

Conventional commits을 지키면 어떤 장점이 있을까?

지금까지 설명한 규약을 지키면서 커밋 메세지를 작성할 경우 어떠한 장점이 있을까요?

첫 번째로 커밋 메세지가 하나의 의미를 담고 있기 때문에 단일 커밋 단위로 의미있는 수정들이 일어나도록 장려할 수 있습니다. 이는 같은 목적을 가지는 수정사항이 여러 커밋으로 나누어 있지 않도록 장려하기 때문에 단일 커밋이 하나의 목표에 대한 수정사항 단위로 관리할 수 있도록 합니다.

두 번째로 커밋 메세지만을 가지고 어떠한 것에 대한 커밋인지 확인하기 쉽다는 장점이 있습니다. 이는 소스 코드에서 특정 커밋을 찾기가 쉬우며 다른 개발자와의 소통을 원활하게 해줍니다.

세 번째로 규약을 통해 CHANGELOG에 대한 생성을 자동화할 수 있습니다. 이를 통해 릴리즈 노트를 일관적이고 명확하게 작성할 수 있습니다.

네 번째로 커밋을 통해 Semantic version 관리를 명확하게 할 수 있고 자동화 할 수 있습니다. 각각의 타입에 따라 버전 증가 기준을 잡을 수 있으며 나아가 자동화할 수 있습니다.

마치며

최근 필자는 Conventional commits을 따르고자 노력을 하고 있습니다. 해당 규약을 따르게 되면서 커밋의 단위가 명확해지고 Git 이력이 깔끔해지는 효과를 받고 있습니다. 규약을 따르는 것은 협업하는 사람들과의 의사소통을 명료하게 할 수 있게 도와주고 일의 능률을 올려 줄 수 있는 방법이라 생각합니다. 이 글을 읽고 처음 Conventional commits에 대해 알게 되신 분들께 도움을 드릴 수 있는 글이길 바랍니다.

--

--

한지승
HASHBOX
Editor for

딥러닝 분야에 모험가 — Machine Learning Engineer @ Clova, Naver Corp. — CV (https://hashbox.github.io)