개발 도구/Git

[Git] 커밋 (commit) 메세지 잘 쓰는 법 - 2. 7가지 커밋 컨벤션 (commit convention)

중중모리 2021. 6. 29. 23:22

참조 : https://chris.beams.io/posts/git-commit/

 

How to Write a Git Commit Message

Commit messages matter. Here's how to write them well.

chris.beams.io

 

Git 커밋 메세지를 작성하는 7가지 규칙은 다음과 같다.

 

1. 내용의 제목과 본문을 한 줄 띄워 구분한다.

2. 제목은 50 characters 이하로 제한한다.

3. 제목의 첫 번째 문자는 대문자로 작성한다.

4. 제목의 마지막에는 마침표를 사용하지 않는다.

5. 제목은 명령문으로 작성한다.

6. 본문은 72 character마다 줄을 바꾼다.

7. 본문의 내용은 "어떻게" 보다 "무엇을" "왜" 인지에 대해 설명한다.

 

위 7가지 방법을 적용한 커밋 메세지 예는 다음과 같다.

Summarize changes in around 50 characters or less

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like `log`, `shortlog`
and `rebase` can get confused if you run the two together.

Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.

Further paragraphs come after blank lines.

 - Bullet points are okay, too

 - Typically a hyphen or asterisk is used for the bullet, preceded
   by a single space, with blank lines in between, but conventions
   vary here

If you use an issue tracker, put references to them at the bottom,
like this:

Resolves: #123
See also: #456, #789

 

1. 내용의 제목과 본문을 한 줄 띄워 구분한다.

 git commit의 manpage를 보면 다음과 같은 내용이 있다.


Though not required, it’s a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git. For example, Git-format-patch(1) turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body.


 위 내용에 따르면, 필수는 아니지만 커밋 메세지를 작성할 때는, 변경사항에 대해 50자 이내로 요약된 내용을 작성하고 한줄 띄워 자세한 설명을 작성하는 것이 좋다고 나와있다.

 

 기본적으로 모든 커밋 메세지가 항상 제목과 본문의 형식으로 작성되어야 하는 것은 아니다. 변경사항에 대해 한줄로 표현 가능한 경우 아래와 같이 표현해도 무방하다.

Fix typo in introduction to user guide

 위 내용을 보면 어디에 있는 무엇을 바꾸었는지에 대해 나와 있으며, 이 경우 한 줄의 내용만 보고도 무슨 내용의 커밋인지 인지할 수 있다. 

 

하지만 변경사항에 대해 어느정도의 설명이 필요할 때는 아래와 같이 본문을 작성할 필요가 있다.

Derezz the master control program

MCP turned out to be evil and had become intent on world domination.
This commit throws Tron's disc into MCP (causing its deresolution)
and turns it back into a chess game.

만약 제목과 본문을 분리하였다면 git log 를 통해 아래와 같이 전체 로그 내용을 확인할 수 있다.

$ git log
commit 42e769bdf4894310333942ffc5a15151222a87be
Author: Kevin Flynn <kevin@flynnsarcade.com>
Date:   Fri Jan 01 00:00:00 1982 -0200

 Derezz the master control program

 MCP turned out to be evil and had become intent on world domination.
 This commit throws Tron's disc into MCP (causing its deresolution)
 and turns it back into a chess game.

 

그리고 git log --oneline 을 통해 작성한 제목만을 출력할 수 있다.

$ git log --oneline
42e769 Derezz the master control program

 커밋 메세지를 작성하는 사람이 여러명이고 다수의 커밋 메세지가 있을 때, git shortlog 를 통해 모든 커밋 메세지의 제목만을 요약하여 확인할 수도 있다.

$ git shortlog
Kevin Flynn (1):
      Derezz the master control program

Alan Bradley (1):
      Introduce security program "Tron"

Ed Dillinger (3):
      Rename chess program to "MCP"
      Modify chess program
      Upgrade chess program

Walter Gibbs (1):
      Introduce protoype chess program

 이러한 기능은 제목과 본문 사이에 빈 줄이 없을 경우 정상적으로 동작하지 않기 때문에 커밋 메세지를 상세하게 적고 이를 효율적으로 관리하기 위해서는 제목과 본문을 구분하는 것이 필요하다.

 

2. 제목은 50 characters 이하로 제한한다.

 제목을 50자 이내로 작성하는 것은 누군가가 만들어낸 규칙이 아니라 수많은 경험에 의해 생겨난 규칙이다. 제목의 나타낼때 50자로 표현하는 것이 가독성도 좋고, 어떤 변경사항이 발생했는지 작성자가 간결하게 작성하기 위해 생각할 수 있는 기회를 제공함으로서 보다 효과적인 커밋 메세지를 작성할 수 있다.

 

 추가적으로 GitHub의 UI를 보면 이 규칙을 그대로 반영하는 것을 볼 수 있는데, 50자 이상 작성할 경우 경고 메세지가 뜨는것을 확인할 수 있다.

 또한 72자를 넘어갈 경우 커밋 메세지가 ...으로 잘려서 표시되기 때문에 커밋 메세지의 제목을 작성할 때에는 50자 이내로 작성하는 것을 권장하고 최대 72자는 초과하지 않도록 작성해야한다.

 

3. 제목의 첫 번째 문자는 대문자로 작성한다.

 내용 그대로이다. 제목의 첫 번째 문자는(영문일 경우) 대문자로 작성해야 한다.

  • Accelerate to 88 miles per hour (O)
  • accelerate to 88 miles per hour (X)

 

4. 제목의 마지막에는 마침표를 사용하지 않는다.

 제목을 작성할 때는 형식상 마침표가 필요하지 않으며 2번 규칙인 50자 이내 작성을 준수하기 위해서는 마침표를 쓰지 않는것이 바람직하다.

  • Open the pod bay doors (O)
  • Open the pod bay doors. (X)

 

5. 제목은 명령문으로 작성한다.

 이 내용은 커밋 메세지 컨벤션 내용 중 가장 이해가 안되는 부분이면서, 자연스럽게 받아들이기 어려운 부분이다. 일반적으로, 제목을 명령문으로 작성한다는 것은 다소 무례해보일 수 있기 때문에 평소에 사용하지 않는 문법이지만, git의 제목을 작성할 때는 가장 적합한 문법이다. 이는, git에서 기본적으로 제공하는 커밋 메세지의 형태가 명령문을 사용하기 때문이다.

 

예를 들어, git merge 를 수행했을 경우 자동으로 생성되는 메세지는 다음과 같다.

Merge branch 'myfeature'

또한, git revert 를 수행했을 때에는 다음과 같이 생성된다.

Revert "Add the thing with the stuff"

This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.

자동으로 생성된 두 메세지의 공통점은 명령문으로 작성된다는 것이다. 따라서 커밋 메세지의 제목을 명령문으로 작성한다는 것은, git에서 제공하는 빌트-인 컨벤션(Built-in Convention)을 그대로 사용하는 것이고, 이는 git shortlog 와 같은 기본으로 제공하는 명령어에도 자연스럽게 모든 커밋 메세지가 조화를 이룬다는 것을 의미한다. 

 

이는, 영문으로 커밋 메세지를 작성할 때 적용되는 컨벤션이며, 만약 한글로 작성하는 경우에 이 규칙을 따르기 위해서는 명령문으로 작성하는 문장 보다는 구문으로 작성하는 것이 자연스럽다. 예를 들면,

  • A 버그를 수정해라 (X)
  • A 버그를 수정했다. (X)
  • A 버그 수정 (O)

이 규칙은 메세지의 다른 규칙과 마찬가지로 제목에만 해당되는 규칙이며, 본문을 작성할 때는 명령문으로 작성하지 않아도 된다.

 

6. 본문은 72 character마다 줄을 바꾼다.

 Git은 메세지를 작성할 때 자동으로 줄바꿈을 해주지 않기 때문에 작성자가 직접 줄바꿈을 적절할 때 사용해야 한다. 이를 사용할 때 커밋 메세지 컨벤션에서 권장하는 한 줄의 길이는 72자 이내이다. 

 

 하지만 본문을 작성할 때마다 72자를 세어가며 엔터를 입력하는 것은 작성자 입장에서 매우 힘든 작업이 되기 때문에 텍스트 에디터에서 제공하는 기능을 활용하는 것이 효과적이다. Vim의 경우 72자를 넘어갈 때마다 자동으로 줄바꿈을 해주는 기능이 있다. 하지만 IDE의 경우 전통적으로 이러한 기능을 제공하지 않았으나 최근 버전에서는 IntelliJ IDEA가 이러한 부분이 개선되었다.

 

7. 본문의 내용은 "어떻게" 보다 "무엇을" "왜" 인지에 대해 설명한다.

 커밋 메세지를 보는 사람이 어떤 목적을 갖고 보는지에 대해 바라보면 이해하기 쉽다. 커밋 메세지를 남기는 용도는 변경사항에 대해 무엇을 왜 바꾸었는지 설명하는 것이고, 어떻게 바꾼지에 대해서는 직접 변경사항을 보면 되기 때문이다.  

 좋은 예시를 보면 다음과 같다.

commit eb0b56b19017ab5c16c745e6da39c53126924ed6
Author: Pieter Wuille <pieter.wuille@gmail.com>
Date:   Fri Aug 1 22:57:55 2014 +0200

   Simplify serialize.h's exception handling

   Remove the 'state' and 'exceptmask' from serialize.h's stream
   implementations, as well as related methods.

   As exceptmask always included 'failbit', and setstate was always
   called with bits = failbit, all it did was immediately raise an
   exception. Get rid of those variables, and replace the setstate
   with direct exception throwing (which also removes some dead
   code).

   As a result, good() is never reached after a failure (there are
   only 2 calls, one of which is in tests), and can just be replaced
   by !eof().

   fail(), clear(n) and exceptions() are just never called. Delete
   them.

 여기까지 좋은 커밋 메세지를 작성하는 7가지 방법을 정리해보았다. 당장 커밋 메세지를 작성할 때는 필요성도 크게 못 느낄 것이고, 귀찮다고 느낄수도 있지만, 커밋 메세지를 남긴다는 것은 지금 뿐만이 아니라 몇 개월, 몇 년후에 다시 봤을 때 큰 도움이 되기 위함이고, 원활한 협업을 위해 필수적이다. 따라서 좋은 프로젝트를 만들기 위해서는 코드 뿐만이 아니라 커밋 메세지도 많은 영향을 미친다는 사실을 깨닫고 프로젝트에 임하는 것이 바람직하다.