- 깃 커밋 메세지를 잘 쓰는 법2023년 07월 30일 12시 54분 27초에 업로드 된 글입니다.작성자: sue24
여름 휴가를 맞이해서 깃 커밋 메세지 규칙을 세우기로 했다.
그냥 컨벤션을 따르는 게 좋을 것 같아서 여기저기 검색을 하다가
왜 깃 커밋 메세지를 잘 써야 하는지 설명해주는 글을 발견했다.
공감가는 말들이 많아서 번역을 해 본다.
2014년 8월에 작성된 글이니만큼 IDE 기능같은 부분은 달라져있을 수 있음을 명시한다.왜 좋은 커밋 메세지가 필요할까요?
아무 깃 저장소에나 들어가서 로그를 구경해 보면 대개 엉망일 겁니다.
다음은 제가 초창기에 썼던 커밋들입니다.

같은 저장소에서 최근에 올린 커밋은 다음과 같습니다.

둘 중 어떤 걸 읽고 싶은가요?
첫번째는 길이와 형식이 제각각이고, 두번째는 간결하고 일관적입니다.
첫번째는 아무 생각 없이 쓰면 생기는 일이고, 두번째는 절대 우연히 생길 수 없는 일이죠.
(The former is what happens by default; the latter never happens by accident.)
대부분의 깃 로그들이 첫번째처럼 쓰이지만,
Linux kernel, Git, Spring Boot, Tim Pope의 저장소 같은 예외도 있습니다.
이 저장소들의 컨트리뷰터는 잘 정돈된 깃 커밋 메세지가
동료 개발자들에게(그리고 미래의 본인에게)
코드 수정의 문맥을 알려줄 수 있는 최적의 방법이라는 것을 알고 있습니다.
diff를 보면 무엇이 바뀌었는지 알 수 있지만
커밋 메세지를 봐야만 왜 바꾼 것인지를 알 수 있습니다.
(A diff will tell you what changed,
but only the commit message can properly tell you why.)
Peter Hutterer가 이에 대해 다음과 같이 말했습니다.
On commit messages
In the last few weeks, I've had a surprising number of discussions about commit messages. Many of them were with developers new to a projec...
who-t.blogspot.com
"코드의 문맥을 매번 알려주는 것은 시간 낭비입니다. 하지만 하지 않을 수 없죠.
그래서 들어가는 노력을 최대한 줄여야 합니다. 커밋 메세지가 그 역할을 해 줄 수 있습니다.
커밋 메세지를 보면 개발자가 협업을 할 수 있는 사람인지 알수 있습니다.
(a commit message shows whether a developer is a good collaborator.)"
어떤 것이 좋은 깃 커밋 메세지인지 고민해 본 적이 없다면
아마 당신은 git log나 관련 도구를 사용하는 데 많은 시간을 기울이지 않았을 겁니다.
여기서 바로 악순환이 만들어집니다.
커밋 히스토리의 체계가 없고 일관적이지 않으면
사용하는 사람은 제대로 된 커밋을 쓰기 위해 많은 노력을 기울이지 않게 됩니다.
아무도 노력을 기울이지 않기 때문에
깃 저장소는 체계적이지 않고 일관적이지 않은 상태를 유지하게 됩니다.
로그를 잘 다듬는 일은 충분히 의미 있는 일입니다.
git blame, revert, rebase, log, shortlog같은 짧은 명령어들이 일상이 됩니다.다른 사람은 물론 스스로의 커밋이나 풀 리퀘스트를 보는 것도 중요합니다.
몇 년 전, 아니 몇 달 전에 왜 이런 일을 했는지 이해하는 것은
불가능할 뿐 아니라 비효율적인 일입니다.
한 프로젝트의 장기적인 성공은 유지보수에 달려 있습니다.
유지보수를 맡은 사람에게 프로젝트의 로그보다 더 중요한 것은 거의 없습니다.
그러니까 로그를 잘 쓰기 위해 시간을 들여야 합니다.
처음에는 귀찮지만 곧 습관이 되고, 결국에는 자신감과 생산성의 근원이 될 겁니다.
이 글에서는 건강한 커밋 히스토리를 유지하기 위한 기본적인 요소들을 말하겠습니다.
개별적인 커밋 메세지를 쓰는 방법이죠.
커밋 스쿼시같은 중요한 다른 요소들이 있지만 여기서는 설명하지 않습니다.
대부분의 프로그래밍 언어는 일관적인 스타일을 위해서
네이밍, 포맷 등과 관련한 컨벤션을 가지고 있습니다.
이런 컨벤션의 변형 역시 가능하지만, 개발자 각각의 개성을 드러내서 오는 카오스보다
하나를 골라서 정착하는 것이 훨씬 낫다는 것을 다들 아실 겁니다.
(picking one and sticking to it is far better than
the chaos that ensues when everybody does their own thing.)
한 팀이 유용한 코드 수정 히스토리를 갖기 위해서는
처음부터 커밋 메세지 컨벤션을 만들어야 합니다.
컨벤션에는 적어도 다음 세 가지가 포함되어야 합니다.
- 스타일
- 마크업 문법, 마진, 문법, 대문자 사용, 구두점 등
- 다들 알 거라고 짐작하지 말고 소리내어 말하세요
- 가능한 간결하게 만드세요
- 일관적인 스타일을 가진 로그는 읽기 편할 뿐 아니라 주기적으로 읽히게 됩니다.
- 내용
- 커밋 메세지에 바디를 포함시킬 거라면 어떤 정보가 포함되어야 하고
- 어떤 정보가 포함되지 않아야 하는지 합의합니다
- 메타데이터
- 이슈 ID, 풀 리퀘스트 번호 등을 어떻게 표시할 지 합의합니다
다행히 이미 잘 만들어진 깃 커밋 메세지 컨벤션이 있습니다. 새로 만들 필요는 없습니다.
아래의 7가지 규칙을 지키면 프로처럼 커밋을 할 수 있을 겁니다.
깃 커밋 메세지의 7가지 규칙
- 제목과 본문 사이에는 한 줄을 비워 주세요.
- 제목은 50자 이내로 작성해주세요.
- 제목의 첫 글자는 대문자로 작성해주세요.
- 제목에 마침표를 찍지 마세요.
- 제목은 명령형을 사용해주세요.
- 본문의 각 줄은 72자 이내로 작성해주세요.
- 본문에는 어떻게가 아니라 무엇을 왜 바꿨는지를 작성해주세요.
Summarize changes in around 50 characters or less 변경된 부분은 50자 이내로 요약해주세요 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. 필요하다면 구체적인 설명을 추가하세요. 각 줄은 72자 정도에서 개행해주세요. 첫번째 줄은 커밋의 제목, 나머지는 본문으로 취급됩니다. 본문을 작성할 거라면 제목과 본문 사이에 한 줄을 비워 두는 것이 중요합니다. `log`, `shortlog`, `rebase` 같은 도구들은 공백이 없으면 제목과 본문을 구분하지 못할 수 있기 때문입니다. 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 해결된 이슈: #123 관련 이슈: #456, #789제목과 내용 사이에는 한 줄을 비워 주세요.
git commit manpage에서 발췌
필수적인 것은 아니지만 커밋 메세지는 변경 사항을 요약한
50자 이내의 한 줄로 시작하는 것이 좋습니다.
다음 줄은 비워두고 그 다음 줄부터 상세한 설명을 하는 식입니다.
첫 번째 공백 한 줄 전까지가 커밋 메세지의 제목으로 여겨지고
해당 타이틀을 깃 전반에서 사용하기 때문입니다.
예를 들어, Git-format-patch(1)는 커밋을 이메일로 바꿔주는데
커밋 제목을 제목으로 나머지를 본문으로 취급합니다.물론 모든 커밋에 제목과 본문을 작성하지 않아도 됩니다.
한 줄(=제목)만으로도 충분할 때도 있습니다.Fix typo in introduction to user guide
이처럼 간단한 수정이 이루어질 때는 설명이 필요하지 않습니다.
독자가 어떤 오타였는지 궁금하다면 스스로 찾아볼 수 있습니다.(
git show,git diff,git log -p)git commit -m"Fix typo in introduction to user guide"만약 이런 커밋을 커맨드 라인에서 한다면 git commit의 -m 옵션을 사용하면 됩니다.코드 수정에 대한 설명이 필요하다면 내용을 작성해야 합니다.
커밋 메세지의 내용은 -m 옵션을 사용해서 작성하기가 쉽지 않습니다.
텍스트 에디터에서 작성하는 것이 좋은데,
만약 커맨드 라인에서 깃과 함께 사용할 에디터 세팅이 되지 않았다면 이 링크를 참고하세요.
제목과 내용 사이에 한 줄을 띄워 두는 것은 로그를 살펴볼 때 도움이 됩니다.
$ 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 42e769 Derezz the master control program$ 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이외에도 깃의 다른 기능들 중에 제목과 본문 사이의 공백이 없다면
의도한 대로 작동하지 않는 기능들이 있습니다.
제목은 50자 이내로 작성해주세요.
50자는 그렇게 적은 숫자가 아닙니다.
이 정도 길이를 유지하면 읽기도 편하고
커밋을 할 때 어떻게 설명할 지 한 번 더 생각하게 할 수도 있습니다.
만약 요약이 너무 어렵게 느껴진다면 커밋을 한 번 할 때 너무 많은 수정을 하는 거 아닐까요?
한 번의 커밋에는 하나의 변화만 주는 것이 좋습니다.
관련 링크를 첨부합니다.
깃허브의 UI는 이런 컨벤션을 알고 있기 때문에,
50자가 넘어가면 경고를 띄워주고,
72자가 넘어가면 말줄임표를 사용하여 전체를 보여주지 않습니다.
50자 이내로 하려고 노력하되 72자를 마지노선으로 생각해주세요.
제목의 첫 글자는 대문자로 작성해주세요.
제목에 마침표를 찍지 마세요.
제목에 마침표는 필요하지 않습니다.
50자 이내로 적으려면 한 자라도 줄이는 것이 좋기도 하구요.
제목은 명령형을 사용해주세요.
Clean your room처럼 명령문으로 작성해주세요.
무례하게 들릴 수도 있어서 일상생활에서 잘 쓰는 방식은 아니지만
깃 커밋 제목으로는 아주 좋습니다.
깃이 우리를 대신해서 커밋을 할 때도 명령형을 사용합니다.
'git merge'는
Merge branch 'myfeature','git revert'는
Revert "Add the thing with the stuff"라고 쓰는 것처럼요.- Refactor subsystem X for readability
- Update getting started documentation
- Remove deprecated methods
- Release version 1.0.0
위와 같은 방식으로 쓰는 것이 어색할 수도 있습니다.
일상생활의 직설적인 화법과 다르기 때문입니다.
그래서 다음과 같은 커밋 메세지를 쓰게 됩니다.
- Fixed bug with Y
- Changing behavior of X
- More fixes for broken stuff
- Sweet new API methods
간단한 규칙을 알려드리겠습니다.
제대로 작성된 깃 커밋 제목은 다음 문장을 완성시켜야 합니다.
If applied, this commit will *your subject line here*- If applied, this commit will refactor subsystem X for readability
- If applied, this commit will update getting started documentation
- If applied, this commit will remove deprecated methods
- If applied, this commit will release version 1.0.0
- If applied, this commit will merge pull request #123 from user/branch
잘못 작성된 메세지는 다음과 같이 문장이 이상해집니다.
- If applied, this commit will fixed bug with Y
- If applied, this commit will changing behavior of X
- If applied, this commit will more fixes for broken stuff
- If applied, this commit will sweet new API methods
제목에서만 명령형을 사용하면 됩니다.
본문에서는 명령형을 사용할 필요가 없습니다.
본문의 각 줄은 72자 이내로 작성해주세요.
깃은 텍스트를 자동으로 개행시켜주지 않습니다.
커밋 메세지의 본문을 작성할 때 적절한 마진을 염두에 두고 임의로 개행을 해야 합니다.
추천하는 길이는 72자입니다.
깃이 텍스트를 들여쓰기할 공간을 줘서 전체적으로 80자 아래로 유지할 수 있습니다.
텍스트 에디터를 사용해서 좀 더 쉽게 이 규칙을 지킬 수 있습니다.
Vim을 예로 들자면 깃 커밋을 작성할 때 72자에서 개행을 하기가 쉽습니다.
그러나 보통 IDE들은 커밋 메세지에서의 개행을 하는데 큰 도움을 주지 못합니다.
본문에는 어떻게가 아니라 무엇을 왜 바꿨는지를 작성해주세요.
Bitcoin Core에서 가져온 아래 커밋이 좋은 예시입니다.
commit eb0b56b19017ab5c16c745e6da39c53126924ed6 Author: Pieter Wuille <pieter.wuille@gmail.com> Date: Fri Aug 1 22:57:55 2014 +0200 Simplify serialize.h's exception handling serialize.h의 예외 처리 간소화 Remove the 'state' and 'exceptmask' from serialize.h's stream implementations, 'state'와 'exceptmask'를 serialize.h의 stream과 implementation, as well as related methods. 관련 메소드에서 삭제했습니다. As exceptmask always included 'failbit', and setstate was always called with exceptmask가 'failbit'을 포함하여 setstate가 항상 bits = failbit, all it did was immediately raise an exception. Get rid of bits = failbit임을 가정하며 호출되었는데, 이는 바로 에러를 일으킵니다. those variables, and replace the setstate with direct exception throwing 해당 변수들을 없애고, setstate를 대체하여 직접적으로 예외를 발생시키도록 했습니다. (which also removes some dead code). (쓰이지 않는 코드들도 제거했습니다.) As a result, good() is never reached after a failure (there are only 2 결과적으로 good()은 실패 이후에 실행되지 않고 있었기 때문에 calls, one of which is in tests), and can just be replaced by !eof(). (두 번 호출되는데, 모두 테스트에서 이루어집니다), !eof()로 대체될 수 있었습니다. fail(), clear(n) and exceptions() are just never called. Delete them. fail(), clear(n), exceptions()는 호출되지 않는 함수들이므로 삭제했습니다.diff 링크도 첨부합니다.
수정된 코드를 보고 동료 개발자들이 코드를 이해하기 위해 쓸 시간을 줄이기 위해
커밋을 한 사람이 얼마나 많은 시간을 들였을지 생각해봅시다.
그 사람이 이렇게 커밋을 써주지 않았다면 아무도 알아내지 못했을 수도 있습니다.
미래에 유지보수를 맡은 누군가가 당신에게 감사할 것이고, 그 누군가가 본인이 될 수도 있습니다.
대부분의 경우 어떤 변화가 이루어졌는지 상세하게 설명할 필요는 없습니다.
코드가 설명해주기 때문입니다.
(만약 코드가 너무 복잡하여 설명이 필요하다면 주석이 그 역할을 해줄 수 있겠죠.)
왜 이 변화가 필요하다고 생각했는지에 집중하세요.
이 커밋 이전에 어떻게 동작했고 (그것이 왜 잘못됐는지), 이 커밋 이후에 어떻게 동작하고,
이 문제를 해결하는데 사용된 방식을 어떻게 결정했는지 같은 것들이요.
Tips
IDE가 아니라 커맨드 라인을 사랑해보세요.
깃의 다양한 서브커맨드들을 생각해보면 커맨드 라인을 이용하는 것이 좋습니다.
깃은 굉장히 유용한 도구입니다. IDE 역시 유용한 도구지만 두 개는 각자 다른 방식으로 유용합니다.
저도 IDE를 매일 사용하지만(IntelliJ IDEA를 사용하고 Eclipse도 사용해왔습니다)
커맨드 라인을 사용하는 것만큼 간편하고 효과적인 깃 IDE integration을 본 적이 없습니다.
파일을 삭제하는
git rm처럼 깃과 관련된 매우 유용한 IDE 기능들도 있습니다.그러나 commit, merge, rebase나 히스토리 분석 같은 복잡한 일을 IDE를 통해서 하려고 하면 다 엉망이 되어버립니다.
깃을 사용하려면 커맨드 라인이 가장 좋습니다.
Bash를 쓰든 Zsh나 Powershell을 쓰든 중요하지 않습니다.
tab을 사용해서 자동완성해주는 기능이 있어야 다양한 명령어를 모두 암기하지 않아도 됩니다.
Pro Git
이 링크에서 무료로 읽을 수 있습니다.
다음글이 없습니다.이전글이 없습니다.댓글 - 스타일