사전 커밋 메시지
개념

커밋 메시지

gabury1고친 사람 github-actions[bot]

커밋 메시지는 이번 변경을 왜 했는지를 이력에 남겨 둡니다. 무엇이 바뀌었는지는 코드를 견줘 보면 드러나지만, 왜 바꿨는지는 고친 사람의 머릿속에만 있습니다. 커밋 메시지가 그 빈칸을 맡습니다.

쉽고 빠른 이해

커밋 메시지는 변경 한 묶음을 이력에 넣을 때 같이 적어 두는 설명입니다. 결제 금액의 올림을 버림으로 바꾼 변경이라면 「표시 금액보다 1원이 더 청구된다는 신고가 들어왔다」가 그 설명입니다.

이게 없으면 몇 달 뒤에 곤란해집니다. 코드는 지금 모습만 보여 줍니다. 왜 그 모습이 됐는지는 안 보여 줍니다. 고친 사람이 팀을 떠나면 이유를 물어볼 데도 없습니다.

어떻게 도는가:

  1. 바꾼 파일을 한 묶음으로 고릅니다
  2. 그 묶음을 이력에 넣으면서 설명을 같이 적습니다
  3. 나중에 이력을 뒤지는 사람이 그 설명을 읽습니다

대가가 있습니다. 적는 데 시간이 듭니다. 남들과 이미 나눈 이력은 메시지만 고치기도 어렵습니다. 게다가 메시지가 코드와 맞는지는 아무도 검사해 주지 않습니다.

상세

이삿짐 상자에 「주방 · 깨지는 것」이라고 적어 붙여 두면 열어 보지 않고도 무엇이 들었는지 압니다. 커밋 메시지는 한 걸음을 더 갑니다. 왜 그것을 담았는지까지 적습니다.

커밋은 바뀐 파일을 한 묶음으로 확정해 이력에 넣는 일입니다. 커밋 메시지는 그 묶음마다 하나씩 딸리는 설명 글입니다. 바뀐 코드를 견주면 「무엇이」는 드러나므로, 메시지가 맡는 몫은 「왜」입니다.

실물은 이렇습니다. 「결제 금액을 올림에서 버림으로 바꿈. 표시 금액보다 1원이 더 청구된다는 신고가 들어왔습니다」 같은 글입니다. 코드만 봐서는 올림이 왜 틀렸는지 알 길이 없습니다.

메시지는 커밋마다 하나씩 붙으므로 쓸지 말지를 고르는 일은 없습니다. 고르는 것은 무엇을 적느냐입니다.

제목 줄과 본문

메시지는 대개 두 토막으로 씁니다. 첫 줄은 이번 변경을 한 줄로 줄인 제목입니다.

그 아래 빈 줄을 하나 둡니다. 그다음부터가 본문입니다. 본문에는 제목에 안 들어간 사정을 적습니다.

빈 줄이 경계 노릇을 합니다. 이력을 목록으로 보여 주는 도구는 첫 줄만 뽑아 한 행씩 늘어놓습니다. 빈 줄이 없으면 어디까지가 제목인지 가를 수 없습니다.

결제 올림을 버림으로 바꿈  // 목록에 뜨는 줄
                           // 빈 줄이 경계다
표시 금액보다 1원이 더 청구된다는
신고가 들어왔습니다.       // 왜 바꿨나

위가 메시지 한 벌입니다. 제목 한 줄, 빈 줄, 그리고 본문입니다.

제목만 읽고도 무슨 변경인지 짐작이 가야 목록이 쓸모가 있습니다. 그래서 제목은 짧게 씁니다. 「수정」이나 「버그 픽스」처럼 아무 커밋에나 붙일 수 있는 말은 피합니다.

본문에 담는 세 가지

본문은 길이보다 무엇을 담느냐로 갈립니다. 대개 아래 셋이면 충분합니다.

담는 것 왜 담나
고치기 전에 무엇이 문제였나 증상이 안 남으면 같은 문제가 다시 나도 알아보지 못합니다
왜 이 방법을 골랐나 같은 코드를 다시 만진 사람이 처음부터 고민하지 않습니다
무엇을 안 골랐나 이미 막혀 본 길을 뒷사람이 또 파지 않습니다

반대로 코드를 읽으면 바로 보이는 것은 안 적습니다. 「반복문을 하나 늘림」은 바뀐 코드가 이미 말하고 있어서 한 번 더 적어도 얻는 것이 없습니다.

메시지를 고치기 어려운 까닭

버전관리 도구 가운데는 커밋에 번호를 붙여 부르는 대신 내용으로 식별하는 것들이 있습니다. 커밋을 이루는 내용에는 메시지도 들어갑니다. 그래서 메시지 한 줄만 고쳐도 그 커밋을 가리키던 식별값이 달라집니다.

이런 도구에서 커밋은 저마다 앞 커밋을 하나씩 가리킵니다. 그렇게 커밋이 줄줄이 이어집니다. 가리킨 앞 커밋을 부모라고 부릅니다.

식별값이 달라지면 그 커밋을 부모로 가리키던 다음 커밋도 가리키는 값이 달라집니다. 그러면 그 다음 커밋 자신도 새로 쓰입니다. 이렇게 뒤쪽 끝까지 번집니다. Git 에서 오래된 메시지를 고치는 일이 번거로운 이유가 이것입니다.

flowchart TD
    subgraph before["고치기 전"]
        A1["커밋 A"] -->|다음| B1["커밋 B"]
        B1 --> C1["커밋 C"]
    end
    subgraph after["B 의 메시지만 고친 뒤"]
        A2["커밋 A · 그대로"] --> B2["커밋 B · 새 식별값"] --> C2["커밋 C · 덩달아 새 식별값"]
    end

손댄 것은 B 의 메시지 한 줄인데 C 까지 새것이 됐습니다. 남들이 이미 받아 간 이력이라면 그 사람들 손에 있는 것과 어긋나 버립니다. 그래서 메시지는 남들과 나누기 전에 다듬습니다.

형식을 못 박는 규약

팀이 커지면 메시지의 모양을 미리 정해 두기도 합니다. 제목 앞에 변경의 종류를 정해진 낱말로 붙이는 Conventional Commits 규약이 흔합니다. 기능을 더했으면 feat, 버그를 고쳤으면 fix 를 맨 앞에 적습니다. 앞에서 본 예라면 fix: 결제 올림을 버림으로 바꿈 이 제목이 됩니다.

모양이 정해지면 기계가 읽을 수 있습니다. 쌓인 메시지를 종류별로 모으면 변경 로그가 저절로 만들어집니다. 기능이 더해졌는지 버그만 고쳤는지도 맨 앞 낱말로 드러나므로, 다음 버전 번호를 얼마나 올릴지 정하는 데도 씁니다.

대가도 같이 옵니다. 형식 검사를 통과하는 것이 목표가 되면 제목만 규칙대로인 메시지가 늘어납니다. 본문은 비어 있습니다.

검사는 모양만 봅니다. 이유가 적혔는지는 못 봅니다.

메시지가 흐려지는 두 경우

한 커밋에 여러 변경을 몰아 담으면 메시지도 따라서 뭉뚱그려집니다. 「여러 가지 수정」이라고 적힌 커밋은 되돌리기 를 할 때도 통째로 되돌아가므로, 그중 한 가지만 빼내기 어렵습니다.

메시지가 코드와 어긋나는 경우도 있습니다. 코드는 테스트가 검사하지만 메시지를 검사하는 것은 읽는 사람뿐입니다. 고치다 방향이 바뀌었는데 제목만 처음 것으로 남는 일이 여기서 생깁니다.

관련 항목

커밋 메시지가 붙는 이력의 단위

커밋 · 커밋 객체 · 리비전 · 스냅숏 · 부모 커밋 · 해시 · 태그

커밋 메시지를 적고 고치는 명령

git commit · git log · 리베이스 · 스쿼시 · 되돌리기 · 블레임

커밋 메시지의 모양을 정하는 규약

Conventional Commits · 커밋 템플릿 · 커밋 훅 · 변경 로그 · 시맨틱 버저닝

커밋 메시지를 읽어 굴러가는 협업 절차

코드 리뷰 · 풀 리퀘스트 · 브랜치 전략 · 커밋에서 배포까지 · 릴리스 노트

커밋 메시지를 담아 두는 도구와 서비스

Git · 버전관리 · GitHub · GitLab · 저장소

이력을 되짚을 때 커밋 메시지에 기대는 작업

회귀 · 이분 탐색 디버깅 · 장애 사후 분석 · 감사 로그 · 변경 리드 타임

다른 이름: commit message · 커밋메시지 · commit log message