[번역] Git 커밋 메시지를 작성하는 방법

 

"An Ukiyo-e style painting of Spider-Man on a Rollercoaster." from DALL-E 2

Git 커밋 메시지를 작성하는 방법 - 크리스 빔스

 

How to Write a Git Commit Message

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

cbea.ms

diff는 소스코드에서 무엇이 변경되었는지 알려주지만, 커밋 메시지만이 그 이유를 제대로 알려줄 수 있다.

커밋 메시지는 개발자가 좋은 협력자인지 여부를 보여준다.
Peter Hutterer

커밋 기록이 구조화되지 않고 일관성이 없기 때문에 사용하거나 관리하는데 많은 시간을 할애하지 않는다. 사용되거나 관리되지 않기 때문에 구조화되지 않고 일관성이 없다.

잘 관리된 로그는 유용하다. git blame, revert, rebase, log, shortlog 그리고 다른 하위 명령어들도 존재한다. 다른 사람의 커밋과 풀 요청을 검토하는 것은 가치 있는 일이 되고, 독립적으로 수행할 수 있도록 만들어준다. 몇 달 또는 몇 년 전에 일이 발생한 이유를 이해하는 것이 가능해질 뿐만 아니라 효율적으로 변한다.

프로젝트의 장기적인 성공은 유지 관리 가능성에 달려 있으며 유지 관리자는 프로젝트 로그보다 강력한 도구가 거의 없다. 제대로 로그를 작성하는 법을 배우는데 시간을 할애할 가치가 있다. 처음에는 번거로울 수 있지만 곧 습관이 되고 결국에는 관련된 모든 사람에게 자부심과 생산성의 원천이 된다.

대부분의 프로그래밍 언어에는 관용적 스타일, 즉 이름 지정, 서식 지정 등을 구성하는 것과 관련하여 잘 정립된 규칙이 있다. 물론 이러한 규칙에는 변형이 있지만, 하나를 선택하여 고수는 것이 훨씬 낫다.

커밋 로그에 대한 팀의 접근 방식도 다르지 않아야 한다. 유용한 개정 (revision) 기록을 생성하려면 팀은 먼저 다음 세 가지 이상을 정의하는 커밋 메시지 규칙에 동의해야 한다.

① 스타일

마크업 구문, 줄 바꿈 여백, 문법, 대문자, 구두점. 이러한 내용을 추측과 철자를 맞추고 추측을 제거하고 가능한 간단하게 만들어야 한다. 최종 결과는 읽는 즐거움 뿐만 아니라 실제로 정기적으로 읽히는 매우 일관된 로그가 될 것이다.

② 내용

커밋 메시지 본문에는 어떤 종류의 정보가 포함되어야 하는가? 무엇이 들어 있지 않아야 하는가?

③ 메타데이터

이슈 추적 ID, 풀 리퀘스트 번호 등을 어떻게 참조해야 하는가?

다행히도 관용적인 Git 메시지를 남기기 위한 잘 확립된 관습들이 있다.

 

Git 커밋 메시지를 위한 위대한 일곱 가지 규칙

1) 제목과 본문을 구분하여 빈 라인으로 표시

2) 제목줄을 50자로 제한

3) 제목 줄 대문자화

4) 마침표로 제목 줄을 끝내지 말기

5) 제목 줄에서 명령조로 작성하기

6) 72자로 본문 감싸기

7) 본문을 사용하여 what, why 그리고 how를 설명하기

예를 들면 다음과 같다.

 

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 메뉴얼 페이지에 다음과 같이 쓰여 있다.

필수는 아니지만, 변경을 요약한 짧은 (50자 미만) 줄 하나로 커밋 메시지를 시작한 후 빈 줄에 이어 보다 철저한 설명을 하는 것이 좋다. 커밋 메시지의 첫 번째 빈 줄까지의 텍스트는 커밋 제목으로 처리되며, 해당 제목은 Git 전체에서 사용된다. 예를 들어, Git-format-patch(1)은 커밋을 이메일로 변환하고, 제목 줄의 제목과 본문의 나머지 커밋을 사용한다.

우선, 모든 커밋이 제목과 본문을 모두 필요로 하는 것은 아니다. 때로는 한 줄도 괜찮고, 특히 변화가 너무 간단해서 더 이상의 맥락이 필요하지 않을 때는 더욱 그렇다. 예를 들면 다음과 같다.

 

Fix typo in introduction to user guide

 

더 이상 언급할 필요가 없다. 만약 독자가 오타가 무엇인지 궁금하다면, 단순히 diff 값을 볼 수 있다. git show 또는 git diff 또는 git log -p 명령어를 사용하면 된다.

 

하지만, 어떤 커밋에 약간의 설명과 맥락의 파악이 필요할 때, 본문을 작성할 필요가 있다. 예를 들면 다음과 같다.

 

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

2. 제목 줄을 50자로 제한하기

50자는 엄격한 제한이 아니라 경험적인 값이다. 제목 줄을 이 길이로 유지하면 읽을 수 있다는 것을 보장하며, 저자는 현재 진행 중인 내용을 가장 간결하게 설명하는 방법에 대해 잠시 고민하게 된다.

 

팁: 요약하는데 어려움을 겪고 있다면, 한 번에 너무 많은 변경을 하고 있는 것일 수 있다. 커밋을 원자화하기 위해 노력하라.

 

GitHub의 UI는 이러한 규약을 충분히 알고 있는데, 50자 제한을 초과하면 다음과 같이 경고가 표출된다.

그리고 72자보다 긴 제목 줄인 경우 줄임표로 잘라진다.

그러므로, 50자를 적되, 72자를 강한 한계로 간주하는 것이 좋다.

3. 제목 줄을 대문자로 시작하기

제목 그대로 모든 제목 줄을 대문자로 시작하는 것이다.

예를 들면 다음과 같다.

*Accelerate to 88 miles per hour

아래와 같이 작성하면 안 된다.

*accelerate to 88 miles per hour

4. 마침표로 제목 줄을 끝내지 말기

제목 줄에서는 후행 구두점이 필요하지 않다. 게다가 제목 줄의 길이를 50자 이하로 유지하기 위해 공간을 소중히 사용해야 한다.

*Open the pod bay doors

아래와 같이 사용하지 말아야 한다.

*Open the pod bay doors.

5. 제목 줄에서 명령 식으로 작성하기

명령 무드는 "명령이나 지시를 내리는 것처럼 말하거나 쓰는 것"을 의미한다. 몇 가지 예는 아래와 같다.

*방청소 하세요.

*문 닫아

*쓰레기를 내다 버려라

지금 읽고 있는 7가지 규칙 또한 명령조 (본문을 72자 이하로 작성하라) 로 쓰여 있다.

그 명령조는 약간 무례하게 들릴 수 있다. 그래서 자주 사용하지 않는다. 하지만 이 어조는 Git이 제목들을 커밋하기에 완벽하다. 명령조를 사용하는 한 가지 이유는 Git 자체가 당신을 대신하여 커밋을 만들 때 마다 명령조를 사용하기 때문이다.

 

예를 들어, git merge를 사용할 때 생성되는 기본 메시지는 다음과 같다.

 

Merge branch 'myfeature'

 

그래서 의무적으로 커밋 메시지를 작성할 때, 당신은 Git의 내재된 규칙을 따르고 있습니다. 예를 들면 다음과 같습니다.

* 가독성을 위한 서브시스템 X 재작성

* Getting Started 설명서 업데이트

* 사용되지 않는 메서드 제거

* 릴리스 버전 1.0.0

이렇게 작성하는 것이 처음에는 어색할 수 있다. 우리는 사실을 보고하는 것에만 급급해 말하는 식에 익숙하다. 그렇게 때문에 커밋 메시지가 종종 다음과 같이 작성된다.

* Y에 대한 버그가 수정됨

* X의 행위를 수정하는 중

그리고 때때로 커밋 메시지는 내용에 대한 설명으로 기록된다.

* 고장난 것들에 대한 더 많은 수정

* 깔끔한 새로운 API 메서드들

혼란을 없애기 위해 이를 바로잡는 간단한 규칙이 있다.

 

적절하게 형성된 Git 커밋 제목 줄은 항상 다음의 문장을 완성할 수 있어야 한다.

 

* 적용되는 경우, 이 커밋은 [여기에서 커밋 제목 줄을 작성]

예를 들면 다음과 같다.

* 적용되는 경우, 이 커밋은 getting started 문서를 업데이트할 것이다.

* 적용되는 경우, 이 커밋은 사용되지 않는 메서드들을 제거할 것이다.

* 적용되는 경우, 이 커밋은 버전 1.0.0을 릴리스할 것이다.

* 적용되는 경우, 이 커밋은 user/branch 로부터 풀 리퀘스트 #123을 머지할 것이다.

다른 비 명령조 형식에서는 적절하지 않을 수 있다.

* 적용 시, 이 커밋은 Y로 버그를 수정할 것이다.

* 적용 시, 이 커밋은 X의 동작을 변경할 것이다.

* 적용 시, 이 커밋은 고장난 기능들을 더 많이 수정할 것이다.

* 적용 시, 이 커밋은 새로운 API 메서드들은 스위트할 것이다 (?).

단, 명령조의 사용은 제목 줄에서만 사용해야 한다. 본문에서는 조금 더 유연하게 사용할 수 있다.

6. 본문을 72자로 감싸기

Git은 자동으로 텍스트를 감싸지 않는다. 커밋 메시지의 본문을 작성할 때, 당신은 메시지의 오른쪽 여백을 신경써야 하며, 수동으로 텍스트를 줄바꿈해야 한다.

 

권고사항은 본문을 72자로 제한하는 것으로 Git은 모든 것을 전체적으로 80자 미만으로 유지하면서 텍스트를 들여쓸 수 있는 충분한 공간을 확보한다.

 

좋은 텍스트 편집기는 이 부분을 도울 수 있다. 예를 들어, Git 커밋을 작성할 때 72자로 텍스트를 감쌀 때 Vim에서는 쉽게 구성할 수 있다. 그러나 전통적으로 IDE는 커밋 메시지에서 텍스트를 감싸기 위한 스마트판 지원을 제공하는데 서툴렀다 (최근 버전에서는 인텔리제이 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.

 

전체 diff를 살펴보고, 이 문맥을 제공함으로써 저자가 동료들과 다른 커미터들의 시간을 얼마나 절약했는지 유심히 생각해볼 필요가 있다. 만약 그가 이렇게 행동하지 않았다면 영원히 잃어버렸을 것이다.

 

대부분의 경우, 어떤 변화가 발생했는지 생략할 수 있다. 코드가 그 자체로 설명이 될 수 있다 (그리고 코드가 너무 복잡해서 설명이 필요하다면 소스 주석을 달면 되는 것이다). 커밋 메시지는 애초에 왜 변화를 만들었는지, 즉 변화하기 전의 상황 (그리고 그것이 무엇이 잘못되었는지), 지금 상황들이 어떻게 작용하는지, 그리고 왜 당신이 했던 방식으로 그것을 해결하기로 결심했는지 명확히 하는 데 초점을 맞추면 된다.

당신이 고마워할 미래의 메인테이너가 당신 자신이 될 것이다.

커맨드라인을 사랑하는 법을 배워라

Git의 하위 명령어들이 많은 만큼 커맨드라인을 수용하는 것이 현명하다. Git은 미친듯이 강력하다; IDE도 그렇지만 다른 방식으로 동작한다. 나는 매일 IDE (IntelliJ IDEA)를 사용하고 다른 것을 광범위하게 사용 (Eclipse)해 왔지만, 명령 라인의 용이성과 위력에 부합하는 Git을 위한 DIE는 본적이 없다.

Git의 모든 기능을 휘두르기 위해서는 어디까지나 커맨드라인 밖에 없다. Bash, Zsh 또는 PowerShell을 사용하든 탭을 누르면 자동으로 완성해주는 기능이 있다는 것을 명심해야 한다.

Pro Git 책은 온라인에서 무료로 구할 수 있으니 참고하라!