개발 Dev/깃 Git

좋은 커밋, 좋은 커밋 메시지Git commit message는 어떤 것일까?

Tap to restart 2021. 3. 11. 17:00
반응형

깃Git을 쓰고 커밋commit을 할 때 메시지를 적는다.

메시지를 어떻게 적어야 할까?

 

커밋 메시지는 훌륭한 협업자를 판단하는 기준

"a commit message shows whether a developer is a good collaborator." - Peter Hutterer.

(출처: On commit messages)

"커밋 메시지는 개발자가 훌륭한 협업자인지 여부를 보여준다."

 

말로 훌륭한 협업자라고 주장해봤자 의미는 없다. 언제나 말보다 실제가 중요하니까.

결국 커밋 메시지를 잘 적어야 다른 사람들에게 훌륭한 협업자로 인정받을 수 있게 된다.

 

Peter Hutterer의 주장을 좀 더 살펴보자.

(출처: On commit messages)

A good commit message should answer three questions about a patch:

Why is it necessary? It may fix a bug, it may add a feature, it may improve performance, reliabilty, stability, or just be a change for the sake of correctness.
How does it address the issue? For short obvious patches this part can be omitted, but it should be a high level description of what the approach was.
What effects does the patch have? (In addition to the obvious ones, this may include benchmarks, side effects, etc.)

좋은 커밋 메시지는 패치(오류 수정)에 대해 다음 3가지 질문에 답을 해야 한다.

 

1. 왜 그것이 필요한가? 버그를 수정하거나, 기능을 추가하거나, 성능, 신뢰성, 안정성을 개선하거나 단지 정확성을 개선하기 위한 변화일 수도 있다.

2. 어떻게 그 이슈(문제)를 해결하는가? 짧은 뻔한 오류 수정이라면 이 부분은 생략할 수도 있지만, 접근 방식이 무엇이었는지에 대한 높은 수준의 설명이어야 한다.

3. 그 패치는 무슨 효과들을 갖고 있는가? (명백한 효과 이외에도, 기준들(benchmark), 부작용들을 포함할 수 있다.)

 

How to do it better

There's no strict definition of the ideal commit message, but some general rules have emerged.
A commit should contain exactly one logical change. A logical change includes adding a new feature, fixing a specific bug, etc. If it's not possible to describe the high level change in a few words, it is most likely too complex for a single commit. The diff itself should be as concise as reasonably possibly and it's almost always better to err on the side of too many patches than too few. As a rule of thumb, given only the commit message, another developer should be able to implement the same patch in a reasonable amount of time.

어떻게 해야 더 잘할 수 있을까

 

이상적인 커밋 메시지에 대한 엄격한 정의는 없지만 몇가지 일반적인 규칙이 등장했다.

커밋에는 정확히 하나의 논리적 변화가 포함되어야 한다. 논리적 변경에는 새 기능 추가, 특정 버그 수정 등이 포함된다. 높은 수준의 변화를 몇 마디로 설명할 수 없다면, 하나의 커밋으로는 너무 복잡할 가능성이 높다. 차이 자체는 비교적 가능한 한 간결해야 하며, 거의 언제나 지나치다 싶을 정도로 너무 많은 패치들이 너무 적은 것보다 낫다(패치는 오류수정을 뜻하므로, 너무 많은 패치란 결국 오류의 가능성을 최대한 줄일 수 있는 방향의 코드를 의미한다고 볼 수 있다). 원칙적으로 커밋 메시지만 주어진다면, 다른 개발자가 합당한 시간 내에 동일한 패치를 구현할 수 있어야 한다.

 

How not to do it

There's a bunch of common sins that are committed (yay, a pun!) regularly.

SCM is not a backup system! My personal pet hate. Developers who use it as such tend to do end-of-day commits, checking in everything at the end of the day. The result is useless, a random diff across the code with changes that are impossible to understand by anyone including the original author once a few months have passed. (On this note: universities, please stop teaching this crap).

Per-file commit. More often than not a logical change affects more than one file and it should not be split up into two commits.

Lazy commit messages, any commit labelled as "misc fixes and cleanups" or similar. I've seen my fair share of those on non-FOSS projects and they always come back to bite you. Impossible to find when a bug was introduced, hard to bisect and makes it harder for anyone else to keep track of what's happening in the project.

Two changes in one patch. Something like "Fixed bug 2345 and renamed all foo to bar". Unless bug 2345 required the renaming, fixes whould be split it up into multiple patches. Others may have to take one of those bug fixes and apply it to a stable branch but not the other one. Picking bad patches apart into useful chunks is one of the most time-consuming and frustrating things I've done since it doesn't actually add any value to the project.

Whitespace changes together with code changes. Needle in a haystack is a fun game, but not when you're looking at patches. It's a great way to introduce bugs, though because almost no-one will spot the bug hidden in hundreds of lines that got reindented for fun and profit.

The ever-so-lovely code drops. Patches with hundreds of lines of code to dump a new feature into the code while at the same time rewriting half the existing infrastructure to support this feature. As a result, those hundreds of lines of code need to be reviewed every time a bug is discovered that is somehow related to that area of code.
It's easier and less time consuming to first rework the infrastructure one piece at a time, then plug the new feature on top. As a side-effect, if a project relies on code dumps too often it's discouraging outside developers. Would you like to contribute to a project where the time spent filtering the signal from the noise outweighs the actual contribution to the code?

Unrelated whitespace changes in patches. A reviewer needs to get the big picture of a patch into their brains. Whitespace-only hunks just confuse, a reviewer has to look extra hard to check if there's a real change or whether it can be ignored. That's not so bad for empty lines added or removed,it's really bad for indentation changes.

어떻게 하면 안 될까

 

여기 흔히 정기적으로 범하는 많은 실수 다발이 있다.

 

소스코드 관리SCM(Source Code Management)는 백업 시스템이 아니다. 개인적으로 짜증나는 것이다. 하루가 끝날 때 모든 것을 확인하면서, 커밋을 하는 경향이 있는 개발자들을. 그 결과는 쓸모 없는 몇달만 지나도 처음 작성한 사람을 포함한 누구도 이해할 수 없는 무작위한 코드 차이다. (이 노트에 대해서: 대학들은, 이 그지 같은 것 좀 가르치지 마라.)

- 백업용으로 커밋을 하지 말라는 뜻이다. 일과가 끝날 때.

 

파일별 커밋. 논리적 변경이 하나 이상의 파일에 영향을 미치는 경우가 많으므로 두 개의 커밋으로 분할해서는 안 된다.

 

게으른 커밋 메시지, "오류 수정 및 정리"와 비슷한 커밋들. FOSS(Free and open-source software자유오픈소스소프트웨어)가 아닌 프로젝트에 대해서 이런 커밋 메시지 중 공평한 분배를 봐왔고, 이것들이 나중에는 언제나 당신을 괴롭힌다. 오류가 언제 생겼는지 찾을 수 없고, 나누기도 어렵고, 다른 사람들은 프로젝트에서 무슨 일이 일어나고 있는지 추적하기가 더 어려워진다.

 

한 패치에 두 변경 사항이 있는 경우. "오류 2345 수정하고 모든 foo를 bar로 변경' 같은 경우다. 오류 2345가 이름 변경을 필요로 하는 경우가 아니라면, 여러 패치로 분할해야 한다. 다른 버그 수정 중 하나를 가져와서 안정적인 브랜치에 적용해야 하지만 다른 하나는 적용하지 말아야 할 수도 있다. 나쁜 패치를 유용한 덩어리와 구분하는 것은 프로젝트에 실제로 어떤 가치도 더하지 못하기 때문에 내가 한 일 중 가장 시간이 많이 걸리고 좌절감을 주는 일 중 하나다.

 

공백은 코드 변경과 함께 변경된다. 건초더미 속의 바늘은 재미있는 게임이지만, 패치를 볼 때는 그렇지 않다. 이것은 오류를 소개하는 좋은 방법이지만, 재미와 이익을 위해 처음부터 다시 만들어진 수백줄 속에서는 그 누구도 오류를 찾을 수 없기 때문이다.

 

너무나 사랑스러운 코드는 떨어뜨린다. 새로운 기능을 추가하기 위한 코드와, 동시에 그 기능을 지원하기 위해 다시 작성된 코드 수백줄로 이루어진 패치들. 그 결과 수백줄의 코드는 매번 다시 검토되어야 한다. 코드 영역과 관련된 오류(버그)가 발견될 때마다.

 

이것이 훨씬 쉽고 시간이 적게 소요된다. 한번에 하나씩 소프트웨어 기반(인프라스트럭쳐)을 재작업하고 나서 맨 위에 새로운 기능을 연결하는 것이. 부작용으로, 프로젝트가 코드 더미에 너무 자주 의존하면, 외부 개발자들을 남닥시키게 된다. 당신은 실제로 코드에 기여하는 것보다 소음으로부터 신호를 불리하는데 시간을 더 많이 쓰는 프로젝트에 기여하고 싶은가?

 

패치에서 관련없는 공백 변경들. 코드를 다시 보는 사람은 그들의 머리속에 패치에 대한 큰 그림을 그려 넣어야 한다. 공백은 단지 혼란스럽게하고, 코드 검토자는 실제 변경 사항이 무엇인지 무시할 수 있는지 확인하기 위해서 더 열심히 봐야한다. 빈줄이 추가되거나 제거되는 것은 그리 나쁘지 않다. 들여쓰기 변경은 정말 나쁘다.

 


요약해보면 대략 이런 내용인 거 같다.

 

커밋의 단위: 하나의 논리적 변화

- 절대 너무 많은 것들을 한꺼번에 바꾸면 안 된다. 그러면 다른 사람들이 이해할 수 없게 되고, 이해하기 위해서 많은 시간이 필요하기 때문이다.

 

커밋 메시지에 담겨야 할 내용: 왜 필요하고, 어떻게 해결했고, 어떤 부작용이 있을 수 있는가.

 

 

 

반응형