본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 07. 16:15

Claude Code에 Git 운영을 맡기기 — 거대 커밋을 방지하는 커밋 전략의 패턴

요약

Claude Code를 사용할 때 발생하는 거대 커밋 문제를 해결하기 위한 Git 운영 전략을 소개합니다. 하나의 커밋에는 하나의 의도만 담도록 지시하여 리뷰 용이성과 히스토리 관리 품질을 높이는 방법을 다룹니다.

핵심 포인트

  • 거대 커밋은 revert, bisect, 리뷰의 효율성을 저해함
  • 커밋 분할의 핵심 원칙은 '1커밋 1의도'를 유지하는 것
  • CLAUDE.md에 커밋 규약을 명시하여 AI의 행동을 제어 가능
  • 리팩토링과 기능 추가를 분리하도록 명시하는 것이 효과적

Claude Code에게 기능을 한꺼번에 구현하게 한 뒤, 커밋을 맡기면 대개 다음과 같은 상황이 발생합니다.

git add -A && git commit -m "fix"

로 전부 묶어서 1개의 커밋으로 처리

  • 1개의 커밋 안에 리팩토링(Refactor), 신규 기능, 버그 수정, 포맷 변경이 모두 들어 있음
  • 나중에 "그 변경사항 어디서 들어갔지?"라고 찾아봐도, 거대한 차이점(Diff)에 파묻혀 찾을 수 없음
  • 리뷰를 하려고 해도, +800 −300 행의 차이점 앞에서 손이 멈춤
  • 막상 revert(되돌리기)를 하고 싶은데, 되돌리고 싶은 변경사항과 되돌리고 싶지 않은 변경사항이 같은 커밋에 공존함

코드 내용은 나쁘지 않은데, 커밋을 나누는 방식이 허술한 탓에 히스토리가 쓰레기가 된다. 이는 Claude Code뿐만 아니라, AI에게 구현을 맡길 때 반드시 부딪히는 문제입니다.

원인은 모델의 능력이 아닙니다. "어떤 단위로 커밋해주길 원하는지"를 전달하지 않았기 때문입니다. Claude는 기본적으로 "일단 전부 커밋해두자"를 선택합니다. 지시하지 않으면, 인간이 가장 편하고자 할 때와 똑같은 선택을 합니다.

이 기사에서는 Claude Code에게 Git 운영을 맡기면서도, 의미 있는 단위로 · 리뷰하기 쉽게 · 나중에 되돌릴 수 있는 커밋을 만들게 하기 위한 패턴을 소개합니다. 모두 복사해서 오늘부터 바로 시도할 수 있습니다.

"돌아가기만 하면 되는 거 아닌가"라고 생각할지도 모릅니다. 하지만 거대 커밋은 미래의 자신과 팀에게 확실하게 빚을 떠넘깁니다.

거대 커밋으로 잃는 것구체적으로 어떤 일이 일어나는가
revert의 안전성버그가 발생한 변경사항만 되돌리고 싶은데, 같은 커밋의 정상적인 변경사항까지 함께 되돌아감
bisect의 정밀도git bisect로 원인 커밋을 특정해도, 그 안에 10개의 변경사항이 들어 있어 결국 무엇이 범인인지 알 수 없음
리뷰의 용이성+800행의 차이점은 아무도 진지하게 읽지 않음. "LGTM"이라며 대충 넘어감
히스토리의 설명력git log를 봐도 무엇을 했는지 알 수 없음. "fix", "update", "wip"가 나열됨
cherry-pick의 자유도"이 수정사항만 다른 브랜치로 가져가고 싶다"가 불가능해짐

반대로 말하면, 커밋을 의미 있는 단위로 나누는 것만으로도 위의 모든 것을 얻을 수 있습니다. Git의 강력한 기능(revert / bisect / cherry-pick)은 커밋이 깔끔하게 나누어져 있을 때 비로소 사용할 수 있습니다.

그리고 여기서 중요한 점은, Claude Code는 지시만 있다면 이것을 완벽하게 해낼 수 있다는 것입니다. 인간이 귀찮아서 게을리하는 "자주 하는 커밋"을 AI는 담담하게 실행할 수 있습니다. 이는 오히려 AI에게 맡겼을 때 품질이 올라가는 영역입니다.

커밋 분할의 원칙은 단 하나입니다. 하나의 커밋에는 하나의 의도(Intent)만 담는다.

"의도"란, 커밋 메시지의 본문을 읽지 않아도 요약 한 줄로 설명할 수 있는 단위를 말합니다.

좋은 단위 (1커밋 1의도):
- 사용자 검색 API 추가
- 검색 API의 유효성 검사(Validation) 에러 처리 수정
...

이를 Claude Code가 지키게 하려면, CLAUDE.md에 적거나 구현을 요청할 때의 지시에 규칙으로 명시합니다.

CLAUDE.md에 적는 예시:

## 커밋 규약
- 1커밋 = 1개의 의도. 여러 관심사를 1커밋에 섞지 말 것
- 리팩토링과 기능 추가는 반드시 별도의 커밋으로 나눌 것
...

포인트: "리팩토링과 기능 추가를 분리한다"를 명시하는 것이 효과적입니다. AI는 한 번의 구현에서 리팩토링과 신규 기능을 동시에 수행하는 경향이 있고, 그것을 한꺼번에 커밋해버리는 것이 거대 커밋의 가장 큰 요인이기 때문입니다.

Before (지시 없음):

당신: "사용자 검색 기능을 구현해서 커밋해줘"
Claude: (구현 후)
$ git add -A
...

After (1커밋 1의도 지시):

당신: "사용자 검색 기능을 구현해줘. 커밋은
'1커밋 1의도'로 분할해줘"
Claude: (구현 후)
...

같은 구현이라도 후자는 git log를 보는 것만으로 무엇을 했는지 알 수 있습니다. 그리고 세 번째 것만 revert 하는 등의 조작도 자유롭게 할 수 있습니다.

"의미 있는 메시지를 작성해줘"라고만 하면 사람에 따라 (혹은 AI의 기분에 따라) 편차가 생깁니다. 포맷을 고정하고 싶다면 Conventional Commits가 정석입니다.

형식은 심플합니다.

<type>(<scope>): <설명>
[본문 (임의)]
[푸터 (임비)]

type에서 자주 사용하는 것은 다음과 같습니다.

type용도
feat신규 기능feat(auth): 로그인 화면을 추가
fix버그 수정fix(api): null 참조로 인해 충돌하는 문제를 수정
refactor동작을 변경하지 않는 코드 정리refactor(user): 중복 로직을 공통 함수로 추출
test테스트 추가 및 수정test(api): 검색의 이상 케이스 테스트를 추가
docs문서 관련docs: README에 설정 절차를 추가
chore빌드, 의존성, 설정chore: eslint를 9 버전으로 업데이트
style포맷팅만 변경 (동작 불변)style: prettier로 포맷팅

이 내용을 CLAUDE.md에 넣어두면, Claude Code는 매번 이 형식에 맞춰 커밋을 수행합니다.

## 커밋 메시지 규약
Conventional Commits 형식을 엄수할 것:
<type>(<scope>): <일본어/한국어 설명>
...

type을 올바르게 지정하게 만드는 것만으로도 부수적인 효과가 있습니다. Claude가 "이 변경이 feat인지 refactor인지"를 고민하는 과정에서, 커밋 분할도 자연스럽게 적절해지기 때문입니다. 하나의 커밋 안에 feat와 refactor가 섞여 있으면 type을 결정할 수 없으므로, AI가 스스로 "분리해야 한다"는 것을 깨닫게 됩니다.

보충: 팀 단위로 운영한다면 commitlint + husky를 사용하여 기계적으로 강제하는 방법도 있지만, 개인 개발이라면 CLAUDE.md에 작성하는 것만으로도 충분히 기능합니다.

리뷰 용이성은 커밋을 나누는 방식뿐만 아니라 차분(diff) 그 자체를 만드는 방식에 의해 결정됩니다. 같은 기능이라도 차분을 어떻게 만드느냐에 따라 리뷰 부하가 크게 달라집니다.

리뷰어(본인 포함)가 가장 힘들어하는 경우는 "기능 변경"과 "무관한 변경"이 동일한 차분에 섞여 있는 케이스입니다.

읽기 어려운 차분의 예:
함수 A의 버그를 한 줄 수정하고 싶었는데,
같은 커밋에서 파일 전체가 prettier로 재포맷팅되어,
...

이를 피하기 위한 지시 사항을 구현을 요청할 때 덧붙입니다.

리뷰하기 쉬운 차분을 만들어 주세요. 구체적으로:
1. 무관한 포맷 변경을 기능 변경과 섞지 말 것
(포맷팅만 하는 경우 별도의 커밋 style: 으로 분리)
...

더욱 효과적인 방법은 커밋 전에 차분의 요약(summary)을 출력하게 하는 것입니다.

당신: "커밋하기 전에, 지금부터 만들 각 커밋의
'type / 대상 파일 / 한 줄 설명'을 목록으로 보여줘.
OK라고 하면 커밋해"

이렇게 하면 "커밋한 뒤에 내용을 확인하는" 것이 아니라 "커밋 계획을 리뷰한 뒤에 실행하는" 흐름이 됩니다. Before/After를 비교하면 차이는 극명합니다.

Before:

Claude: (임의로 5개 파일을 1개 커밋으로 처리)
"update search feature"
당신: (git show를 한 뒤) "이건 나눠줬으면 했는데..."
...

After:

Claude: 커밋 계획입니다. 승인을 부탁드립니다:
1. feat(api): src/api/search.ts 검색 API 추가
2. feat(api): src/api/validation.ts 쿼리 검증 추가
...

계획을 먼저 확인하므로, 되돌리는 작업(rework)이 사라집니다.

"좋은 커밋"을 규칙화하는 것만큼이나, "해서는 안 될 패턴"을 명시적으로 금지하는 것이 효과적입니다. AI는 금지 사항이 명시되면 더 잘 지킵니다.

CLAUDE.md에 안티 패턴(anti-pattern)을 나열해 둡니다.

## 커밋 시 금지 사항
- ❌ `git add -A` / `git add .`로 무차별적으로 스테이징하지 말 것
→ 관련된 파일만 명시적으로 add 할 것
...

특히 첫 번째인 ** git add -A 금지**는 매우 강력합니다. 거대 커밋(Huge commit)의 대부분은 "전부 한꺼번에 add 하는" 습관에서 비롯됩니다. 이를 금지하고 "관련된 파일만 명시적으로 add 할 것"을 강제하면, 커밋은 자연스럽게 의미 있는 단위에 가까워집니다.

거대 커밋의 전형적인 사례와 그 분할 예시를 표로 나타내면 다음과 같습니다.

거대 커밋 (NG)분할 후 (OK)
feat: 대시보드 일체로 +900행feat(api): 집계 엔드포인트feat(ui): 그래프 표시feat(ui): 필터 UItest: 집계 테스트
fix: 여러 가지 수정으로 5개 파일fix(auth): 세션 만료 판정 수정 / fix(api): 검색 시 빈 배열 대응을 별도 커밋으로 분리
기능 추가와 전체 파일 재포맷이 공존style: 전체 포맷을 먼저 독립 커밋 → 그 위에 feat:를 쌓음

세 번째인 "포맷을 먼저 별도 커밋"은 실용적인 테크닉입니다. 먼저 포맷만 커밋해 두면, 그 이후의 기능 커밋의 차분(diff)이 본질적인 내용만 남게 되어 가독성이 극적으로 좋아집니다. Claude에게도 이 순서를 지시할 수 있습니다.

여기까지는 "처음부터 깔끔하게 커밋하는" 이야기였습니다. 하지만 현실에서는 이미 작업이 끝나서 차분이 엉망진창인 상황이 더 많을 것입니다.

그럴 때는 Claude Code에게 **커밋 재구성(Re-committing)**을 맡길 수 있습니다. 작업 트리(Working tree)에 미커밋 변경 사항이 쌓여 있는 상태에서 시작합니다.

당신: "현재의 미커밋 변경 사항을 의미 있는 단위의
여러 커밋으로 나누어 주세요.
절차:
...

Claude는 차분을 읽고, 예를 들어 다음과 같이 제안합니다.

Claude: 현재 변경 사항을 3개 그룹으로 나눌 수 있습니다:
그룹 A (기능 추가):
src/api/search.ts, src/api/validation.ts
...

한 파일 안에 여러 의도가 섞여 있는 경우에는 git add -p (Hunk 단위 스테이징)를 사용하도록 지시할 수도 있습니다.

당신: "한 파일 안에 기능 수정과 포맷이 섞여 있어.
`git add -p`로 Hunk 단위로 나누어서,
기능 수정과 포맷을 별도 커밋으로 만들어줘."

이렇게 하면 "이미 어질러진 작업 트리"에서도 깔끔한 이력으로 정리할 수 있습니다. 커밋 재구성은 사람이 하면 번거롭고 시간이 많이 걸리는 작업의 대표 격입니다. 그렇기에 AI에게 맡겼을 때의 가치가 매우 큽.

주의: 이미 원격(Remote)에 push한 커밋을 rebase로 다시 쓰는 것은 공유 브랜치에서 사고의 원인이 됩니다. 재구성은 "아직 push하지 않은 로컬 변경 사항"에 한정하도록 CLAUDE.md에 적어두는 것이 안전합니다.

유형요점
1. 1커밋 1의도리팩토링과 기능 추가를 반드시 분리할 것. 요약 한 줄로 설명 가능한 단위로
...git add -A 금지 · 100행 초과 시 분할안을 먼저 제시
5. 커밋 재구성어질러진 작업 트리를 의도별로 재구성하도록 함

Claude Code의 커밋이 엉망이 되는 것은 모델의 실력이 부족해서가 아닙니다. "어떤 단위로 · 어떻게 써주길 원하는지"를 전달하지 않았기 때문입니다.

역으로 말하면, CLAUDE.md에 커밋 규약을 몇 줄 적어두는 것만으로도 Claude는 사람이 게을러지기 쉬운 "자주, 의미 있게 커밋하기"를 묵묵히 수행해 줍니다. 이는 AI에게 맡겼을 때 오히려 품질이 올라가는 몇 안 되는 영역 중 하나입니다.

우선 "유형 1: 1커밋 1의도"와 "유형 4: git add -A 금지" 이 두 가지만이라도 CLAUDE.md에 추가해 보세요. 다음에 구현을 요청할 때 git log의 모습이 달라져 있을 것입니다.

본 기사의 내용을 실제 프로젝트에서 테스트하려면, 토대가 되는 CLAUDE.md와 폴더 구조가 있으면 원활합니다. 제가 사용하는 스타터 구성을 무료로 공개하고 있습니다.

무료 스타터 (GitHub):

더 나아가 워크플로우나 서브 에이전트 설계를 "실행 가능한 스킬 파일"로 정리한 패키지도 준비되어 있습니다. 로컬에서 /명령어 형태로 호출할 수 있는 형태입니다.

  • 스타터 팩 (¥1,980): CLAUDE.md 템플릿 7종 · Hooks · MCP 설정

https://streamsolty.gumroad.com/l/gliwz -
워크플로 OS (¥9,800): 79개의 스킬 + 3개의 워크플로 (Workflow) + 10종의 프롬프트 (Prompt)

우선은 무료 리포지토리 (Repository)부터 시도해 보시고, 더 체계적으로 사용하고 싶어지면 그때 검토해 주셔도 충분합니다. 기사의 내용만으로도 효과를 보실 수 있습니다.

최신 팁 (Tips)은 X에서도 발신하고 있습니다: @k___n___t_1125

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0