patch 단위로 커밋 쪼개게 하기

에이전트가 한 세션에서 기능·리팩터·테스트·포맷을 한 커밋에 몰아넣으면 git bisect·리뷰·revert가 한꺼번에 어려워집니다. 사람에게 “원자적 커밋”을 기대하듯, 에이전트에게도 한 커밋 = 한 논리 패치 규칙을 Rule·Done 정의에 고정하는 편이 안전합니다.

이 글은 **한 커밋 기준은? · 메시지 형식은? · 섞인 변경은 어떻게?**만 다룹니다. agent-pr-body는 PR 본문 칸이고, agent-diff-review는 리뷰용 diff 읽기입니다. 여기서는 스테이징·커밋 쪼개기 축입니다. 요금·플랜·제휴 링크는 없습니다.

근거는 git commit, git add —patch, Conventional Commits와 팀이 쓰는 원자적 커밋·히스토리 관행입니다.

한 커밋 기준은?

한 줄 답: 한 커밋은 한 가지 의도(리뷰·revert·bisect 단위) 로 끝나게 하십시오. “같은 파일에 손댔다”가 아니라 같은 논리 패치인지로 자릅니다.

실무에서 에이전트에 줄 합격 기준:

기준통과실패(쪼개기)
의도버그 하나 / 기능 하나 / 리팩터 하나기능 + 무관 리팩터 + 포맷
빌드·테스트그 커밋만으로 초록(또는 팀이 허용한 WIP 표기)중간 커밋이 깨진 채 방치
리뷰“왜”를 메시지·diff만으로 설명 가능파일 목록만 보고 의도를 추측
revert그 커밋만 되돌려도 다른 작업이 안 무너짐한 커밋에 두 기능이 얽힘
범위관련 테스트·타입·문서가 같은 의도에 속함“顺便”으로 다른 모듈 청소

에이전트 지시 한 줄:

One commit = one logical patch (review/revert/bisect unit).
Do not mix feature, unrelated refactor, and formatting in one commit.
If the working tree has multiple intents, split commits before finishing.

피해야 할 패턴:

  • “세션 끝날 때 git add -A && git commit -m 'wip' 한 방” — 히스토리가 복구 단위를 잃습니다.
  • 테스트 없이 구현만, 다음 커밋에서 테스트 — 팀이 허용한 WIP/fixup! 규칙이 없으면 같은 의도 안에 테스트까지 넣는 편이 bisect에 유리합니다(정책은 팀 문서에 맞추십시오).
  • 자동 포맷터 전체 트리 돌린 결과를 기능 커밋에 섞기 — 포맷은 별도 커밋 또는 pre-commit으로 분리합니다.

커밋 단위를 “파일 하나”로 강제할 필요는 없습니다. 여러 파일이 한 의도에 필요하면 한 커밋이 맞고, 한 파일에 두 의도가 있으면 git add -p로 쪼갭니다.

메시지 형식은?

한 줄 답: 제목(50–72자 권장) + 본문(왜·범위) 을 쓰게 하고, 팀이 Conventional Commits를 쓰면 type(scope): summary를 고정하십시오. 제목만 “update”·“fix”·파일명 나열은 금지합니다.

git은 커밋 메시지를 편집기로 쓰게 하며, 관행상 첫 줄은 요약, 빈 줄 뒤 본문입니다. Conventional Commits는 feat/fix/docs/refactor/test/chore 등 type과 선택적 scope·본문의 BREAKING CHANGE를 정의합니다.

에이전트용 최소 형식:

<type>(<optional-scope>): <imperative summary ≤72 chars>

Why: <one or two sentences>
Scope: <what changed / what did not>
Test: <commands you actually ran, or "n/a: docs-only">

예시(개념):

fix(auth): reject expired refresh tokens at gateway

Why: clients with stale refresh kept getting 500 from upstream.
Scope: gateway middleware + unit tests; no public API change.
Test: go test ./internal/gateway/...

규칙:

  1. 동사 원형·결과 중심 — “fixed bug”보다 “reject expired refresh tokens”.
  2. 실제로 돌린 명령만 Test에 — 돌리지 않았으면 쓰지 말고, Done에서 막으십시오(agent-test-gate와 맞춤).
  3. 이슈 ID — 팀이 쓰면 본문 Refs: ENG-1234 또는 제목 prefix. 없는 ID를 지어내지 마십시오.
  4. Co-authored-by / Generated-by — 팀 정책이 있을 때만 trailer를 붙입니다. 비밀·토큰은 메시지에 넣지 마십시오.
  5. amend·force — 이미 push된 커밋은 사람 지시 없이 --amend/push --force 금지(에이전트 Rule에 명시).

팀이 쓰는 템플릿이 있으면 .gitmessage 또는 에이전트 brief에 그 템플릿 경로만 가리키십시오. 채팅마다 형식을 새로 설명하지 않습니다.

섞인 변경은 어떻게?

한 줄 답: 워킹 트리에 의도가 둘 이상이면 한 번에 커밋하지 말고, git add -p(또는 경로·hunk 단위 스테이징)로 나눈 뒤 의도 순서대로 커밋하십시오.

분리 절차(에이전트 Done에 넣을 체크리스트):

[ ] git status / git diff — list distinct intents
[ ] For each intent: stage only related hunks (git add -p PATH or pathspecs)
[ ] git diff --cached — confirm staged set matches ONE intent
[ ] Commit with message template for that intent
[ ] Repeat until working tree is clean (or only unrelated leftover, reported)
[ ] Never git add -A when multiple intents are present

도구 메모:

상황명령·방법주의
hunk 단위git add -p / git add -p -- path대화형; 비대화형이면 경로·부분 스테이징 도구 사용
파일 단위로 충분git add path1 path2한 파일에 두 의도면 부족
스테이징 취소git restore --staged -- path커밋 전 실수 복구
이미 한 방에 커밋함사람 정책에 따라 soft reset 후 재분할push된 히스토리는 함부로 재작성 금지
포맷만 섞임포맷 커밋 분리 또는 포맷을 pre-commit으로기능 diff 가독성 확보

비대화형 에이전트는 git add -p 프롬프트를 못 받을 수 있습니다. 그때는 (1) 파일을 의도별로 나눠 수정 순서를 지키게 하거나, (2) git apply/git restore -p 대안·에디터 스테이지 API를 쓰게 하거나, (3) “섞였으면 커밋하지 말고 사람에게 분할 요청”을 Rule에 넣으십시오.

섞임을 줄이는 상류 규칙:

  • 한 턴·한 브랜치에 의도 목록을 먼저 쓰게 하고, 커밋 전에 그 목록과 git diff를 대조합니다.
  • 자동 포맷·import 정리는 기능 편집과 같은 커밋에 넣지 않기.
  • 생성 코드·락파일은 팀이 허용한 범위만; 무관 업데이트는 별도 커밋 또는 out of scope.

인접: PR에 올릴 때 본문 Summary는 agent-pr-body, 리뷰 전에 diff를 읽히는 법은 agent-diff-review입니다.

한 줄 정리: 한 의도 = 한 커밋 → type(scope): 요약 + 왜/테스트 → 섞이면 add -p(또는 동일 효과)로 분할, git add -A 금지.

FAQ

“원자적”이면 커밋이 너무 잘게 쪼개지지 않나?

리뷰·bisect에 의미가 있는 단위면 됩니다. “줄 하나 = 커밋 하나”가 목표가 아닙니다. 되돌아갈 가치가 있는 경계에서 자르십시오.

Conventional Commits를 안 쓰는 팀은?

제목 한 줄 + 본문에 Why/Test만 강제해도 충분합니다. type 접두는 팀 문서에 맞추고, “update”·파일 나열만 있는 제목은 공통으로 금지하십시오.

에이전트가 이미 git add -A로 스테이징했다면?

git restore --staged로 내린 뒤 의도별로 다시 올리십시오. 이미 커밋·push까지 갔다면 사람 승인 없이 rebase/amend하지 마십시오.

fixup·squash는?

로컬에서만 정리하고 메인에 올리기 전 squash하는 팀은 fixup!/squash!를 허용할 수 있습니다. 에이전트 Rule에 최종 히스토리 형태(남길 커밋 수·메시지)를 명시하십시오.

출처 (Sources)