들어가며
36차시로 **섹션 7(MCP 서버 연동)**이 끝났다. 거슬러 올라가면 섹션 4의 CLAUDE.md, 섹션 5의 Skills, 섹션 6의 Hooks, 섹션 7의 MCP까지 — 줄곧 Claude Code에 능력을 더하는 이야기였다. 메모리를 주고, 명령을 만들고, 자동화를 걸고, 외부 도구를 붙였다.
37차시부터 시작하는 **섹션 8(Git 통합 워크플로우)**은 방향이 다르다. 더한 능력으로 실제 개발 흐름을 돌린다. 그리고 거의 모든 개발 흐름의 한가운데에 Git이 있다.
그런데 Git을 “마지막에 커밋하는 절차”쯤으로 생각하면 이 섹션을 절반만 이해한다. 에이전트 시대의 Git은 그보다 훨씬 중심적이다. 09차시에서 봤듯 Claude Code는 스스로 파일을 고치고 명령을 실행한다. 그런 에이전트에게 Git은 두 가지를 동시에 한다.
- 되돌릴 수 있는 안전망 — 에이전트가 과감하게 움직여도, 커밋 단위로 언제든 되돌아갈 지점이 있다.
- 변경을 검토하는 표면 — 에이전트가 무엇을 했는지 사람이 확인하는 곳이 바로
git diff다. 받아들이기 전에 보는 창이다.
즉 Git은 에이전트의 자율성과 사람의 통제가 만나는 지점이다. 37차시는 그 지점의 토대를 깐다 — 변경을 읽고(git status·diff·log), 분석하고, 그 위에서 안전하게 Git을 다루는 원칙. 38차시(커밋)·39차시(PR)·40차시(코드 리뷰)는 전부 이 토대 위에 올라간다.
먼저 자주 헷갈리는 둘부터 갈라 두고 시작한다.
체크포인트(/rewind)는 Git이 아니다
섹션을 시작하자마자 못 박을 게 하나 있다. Claude Code에는 **체크포인트(checkpointing)**라는 자체 안전망이 있어서, 이걸 Git과 혼동하기 쉽다.
체크포인트는 Claude가 편집 도구(Edit·Write 등)로 파일을 바꾸기 직전 상태를 자동으로 스냅샷한다. 매 프롬프트마다 체크포인트가 생기고, 세션을 재개해도 유지되며, /rewind(또는 프롬프트 입력이 빈 상태에서 Esc 두 번)로 메뉴를 열어 코드·대화·둘 다를 이전 시점으로 되돌린다. 과감한 작업을 시도하다 어긋나면 “방금 그거 되돌려”라고 하거나 /rewind로 돌아오면 된다.
편리하지만, 이건 Git의 대체가 아니다. 공식 문서가 한계를 분명히 적어 둔다.
- Bash로 일어난 변경은 추적하지 않는다. Claude가
rm file.txt·mv old new·cp a b를 실행해 파일이 바뀌면, 그건/rewind로 되돌릴 수 없다. 추적되는 건 파일 편집 도구로 한 변경뿐이다. - 외부 변경은 추적하지 않는다. 다른 에디터로 직접 고친 것, 동시에 돌던 다른 세션의 편집은 (같은 파일을 건드린 게 아닌 한) 잡히지 않는다.
- 세션과 함께 30일쯤 뒤 정리된다(설정 가능). 영구 기록이 아니다.
공식 문서의 표현을 그대로 옮기면 이렇다.
체크포인트는 “local undo”로, Git은 “permanent history”로 생각하라. 체크포인트는 적절한 버전 관리를 보완할 뿐 대체하지 않는다.
베스트 프랙티스 문서도 같은 경고를 붙여 둔다 — “Checkpoints only track changes made by Claude, not external processes. This isn’t a replacement for git.”
정리하면 이렇다. 체크포인트는 세션 안에서의 빠른 되돌리기, Git은 영구적인 기록과 협업. 둘은 층이 다르다. 이 차시부터 다루는 모든 Git 작업은 영구 기록 쪽의 이야기다.
왜 Claude는 Git 작업을 늘 “상태 읽기”로 시작하나
사람에게 “이 변경 커밋해줘”라고 부탁받았다고 하자. 사람은 보통 먼저 git status와 git diff를 친다 — 지금 뭐가 바뀌어 있는지 봐야 커밋 메시지를 쓰고, 빠뜨린 게 없는지 확인하니까. Claude Code도 똑같이 한다. 그리고 여기엔 비용·위험 양쪽에서 분명한 근거가 있다.
상태를 읽는 건 공짜이고 안전하다. 17차시에서 본 권한 시스템은 도구를 세 계층으로 나눈다.
| 도구 유형 | 예 | 승인 필요 |
|---|---|---|
| 읽기 전용(Read-only) | 파일 읽기, Grep | 아니오 |
| Bash 명령 | 셸 실행 | 예 |
| 파일 수정 | Edit/Write | 예 |
그리고 Bash 안에서도 읽기 전용으로 분류된 명령은 어느 모드에서나 프롬프트 없이 돈다. 공식 문서가 그 목록을 명시하는데, 거기 git이 들어 있다.
다음은 읽기 전용으로 인식되어 권한 프롬프트 없이 실행된다 —
ls,cat,echo,pwd,head,tail,grep,find,wc,which,diff,stat,du,cd, 그리고 읽기 전용 형태의git.
즉 git status·git diff·git log 같은 읽기 전용 git은 Claude가 승인을 묻지 않고 바로 실행한다. 보안 문서도 같은 예를 든다 — “ls, cat, git status 같은 내장 읽기 전용 명령은 프롬프트 없이 실행된다.”
그래서 Claude는 Git 작업을 상태 읽기부터 시작한다. 아무것도 망가뜨리지 않고, 멈춰서 승인을 받을 필요도 없으면서, 그다음 단계(커밋 메시지·PR 본문)에 필요한 모든 맥락을 모으기 때문이다.
변경을 읽는 세 명령 — status·diff·log
읽기 전용 Git 세 가지가 각자 다른 질문에 답한다.
git status — 무엇이 바뀌었나
가장 먼저, 지금 작업 트리에 무엇이 바뀌어 있는지 본다. 어떤 파일이 수정·추가·삭제됐는지, 스테이징된 것과 안 된 것은 무엇인지, 추적되지 않는(untracked) 파일은 무엇인지.
자연어로는 이렇게 부른다.
git status 확인해줘
변경된 파일들을 보여줘
git diff — 어떻게 바뀌었나
status가 “어떤 파일”이라면 diff는 “그 안에서 무엇이 어떻게”. 줄 단위로 무엇이 더해지고 빠졌는지를 본다. 스테이징 안 된 변경은 git diff, 스테이징된 변경은 git diff --staged로 나뉜다.
방금 변경한 내용을 diff로 보여줘
이 diff가 곧 사람의 리뷰 표면이다. Claude가 커밋하거나 PR을 올리기 전에, 사용자가 받아들이기 전에 보는 창이 바로 여기다. 보안 문서가 사용자 책임으로 못 박는 부분이기도 하다 — “제안된 코드와 명령을 승인 전에 검토하는 것은 당신의 몫이다.”
git log — 이 저장소는 어떻게 일해 왔나
log는 현재 변경이 아니라 과거의 흐름을 본다. 38차시에서 다룰 커밋 메시지 스타일(이 팀은 feat:을 쓰나? 한 줄인가 본문이 있나?), 39차시의 PR 컨벤션이 전부 여기서 읽힌다. Claude가 커밋 메시지를 쓰기 전에 git log를 보는 이유 — 기존 스타일에 맞추기 위해서다.
log는 단순한 기록 조회를 넘어 코드의 내력을 묻는 출처로도 쓰인다. 베스트 프랙티스 문서의 예시처럼.
ExecutionFactory의 git 히스토리를 훑어서 이 API가 어떻게 지금 모양이 됐는지 정리해줘
세 명령을 한 줄로 요약하면 이렇다. status는 무엇이, diff는 어떻게, log는 어떤 맥락에서. 그리고 셋 다 읽기 전용이라 자유롭게, 자동으로 돌릴 수 있다.
변경 분석 — Claude가 diff를 읽는 법
Claude는 diff를 출력만 하지 않는다. 읽어서 해석한다. 이 분석이 다음 차시들의 원재료다.
- 의도를 읽는다. 흩어진 줄 변경에서 “이건 로그인 폼에 비밀번호 토글을 더한 변경”이라는 하나의 이야기를 끌어낸다. 38차시 커밋 메시지의 요약은 여기서 나온다.
- 관련된 것끼리 묶는다. 한 번에 여러 갈래의 변경이 섞여 있으면, 어디까지가 한 단위인지 가른다. 이것이 좋은 커밋·PR 경계를 만든다.
- 사고(事故)를 잡아낸다. diff 안에 들어가면 안 될 게 보일 수 있다 — 디버깅용
console.log, 임시 주석, 그리고 특히 민감 정보..env에 새로 박힌 API 키, 실수로 추가된*.key파일 같은 것. 뒤에서 볼 안전 원칙이 여기서 작동한다.
핵심은, 변경을 읽고 분석하는 단계 자체가 안전장치라는 점이다. 무엇을 바꿨는지 정확히 파악하지 못한 채 커밋·푸시로 넘어가지 않는다.
차시의 심장 — 안전한 Git 작업 원칙
Git은 강력한 만큼 되돌리기 어려운 명령을 품고 있다. force push 한 번에 동료의 커밋이 사라지고, hard reset 한 번에 작업이 날아간다. 그래서 Claude Code에는 Git을 다루는 안전 원칙이 동작에 박혀 있다. 이 원칙들은 37차시뿐 아니라 38·39·40차시의 모든 Git 작업에 그대로 적용된다.
커밋·푸시는 요청해야만 한다
Claude는 시키지 않으면 커밋하지 않는다. 변경을 만들었다고 알아서 커밋·푸시로 넘어가지 않는다. “변경사항 커밋해줘”, “PR 올려줘”처럼 명시적으로 요청해야 그 단계로 간다. 푸시도 마찬가지다 — 요청 없이 원격에 올리지 않는다.
베스트 프랙티스 문서의 4단계 워크플로우(Explore → Plan → Implement → Commit)에서도 커밋은 마지막의 별도 단계로, 사람이 지시해서 들어간다.
설명적인 메시지로 커밋하고 PR을 열어줘
기본 브랜치면 먼저 브랜치를 판다
main·master 같은 기본 브랜치 위에서 작업 중이라면, Claude는 커밋하기 전에 새 브랜치를 만든다. 기본 브랜치에 직접 쌓지 않는 건 협업의 기본 예의다(이런 저장소 규칙 — 브랜치 네이밍·PR 컨벤션 — 은 CLAUDE.md에 적어 두면 Claude가 따른다, 21차시).
파괴적·되돌릴 수 없는 명령은 금지
명시적으로 요청하지 않는 한, Claude는 되돌릴 수 없는 Git 명령을 실행하지 않는다.
- force push (
git push --force) — 원격 히스토리를 덮어쓴다. 특히main·master로의 force push는 하지 않는다. - hard reset (
git reset --hard) — 커밋되지 않은 작업과 커밋을 함께 날린다. - 히스토리 재작성 — rebase로 과거를 갈아엎는 류.
이런 명령이 꼭 필요하면 사용자가 콕 집어 요청해야 하고, 그때도 Claude는 위험을 알린다.
훅을 스킵하지 않는다
--no-verify, --no-gpg-sign 같은 플래그로 Git 훅을 건너뛰지 않는다 — 사용자가 명시적으로 요청하지 않는 한. 28~31차시에서 봤듯 pre-commit 훅은 팀의 품질 게이트(린트·테스트·포맷)다. 커밋을 통과시키려고 게이트를 끄는 건, 검증을 통째로 우회하는 것과 같다. 테스트가 막히면 끄는 게 아니라 고치는 쪽으로 간다.
--amend보다 새 커밋, 쓸 땐 authorship 확인
기본은 새 커밋을 쌓는 것이다. git commit --amend는 마지막 커밋을 갈아치우므로, 신중히 쓴다. --amend를 쓰는 경우는 두 가지로 좁다 — 사용자가 명시적으로 요청했거나, 방금 자기가 만든 커밋을 보정할 때. 그리고 amend 전에 반드시 authorship을 확인한다 — 다른 사람이 만든 커밋을 덮어쓰지 않기 위해서다.
git config는 건드리지 않는다
Claude는 git config를 수정하지 않는다. 사용자 이름·이메일·기본 동작 같은 환경 설정을 임의로 바꾸지 않는다는 뜻이다. (그래서 커밋 작성자 정보는 그대로 두고, Claude의 기여는 38차시에서 볼 Co-Authored-By 트레일러로 표시한다.)
인터랙티브 플래그(-i)는 미지원
git rebase -i, git add -i 같은 인터랙티브 플래그는 이 환경에서 지원되지 않는다. Claude는 이런 형태를 쓰지 않고, 비인터랙티브 방식으로 같은 일을 한다. (GitHub 작업은 gh CLI를 쓴다 — 39차시.)
민감 파일은 커밋하지 않는다
.env, *.key, 자격증명 파일처럼 저장소에 들어가면 안 되는 것은 커밋에 포함하지 않는다. 이건 변경 분석 단계에서 diff를 읽어 거르는 일이자, 권한 규칙으로도 보강할 수 있다 — 예컨대 .env 읽기 자체를 막는 Read(.env) deny 규칙처럼.
원칙을 “말”이 아니라 “장치”로 — 권한 시스템
위 원칙들은 Claude의 행동 지침이다. 그런데 지침은 어디까지나 모델이 따르려고 하는 것이다. 공식 문서가 분명히 한다.
권한 규칙은 모델이 아니라 Claude Code가 강제한다. 프롬프트나 CLAUDE.md의 지시는 Claude가 무엇을 시도할지를 형성하지만, Claude Code가 무엇을 허용하는지는 바꾸지 못한다.
그래서 진짜 가드레일은 17차시의 권한 시스템이다. 원칙이 의도라면, 권한 규칙은 그 의도를 강제하는 장치다.
읽기는 자동, 쓰기는 승인
앞서 본 대로 읽기 전용 git(status·diff·log)은 프롬프트 없이 돈다. 반면 git commit·git push는 시스템을 바꾸는 Bash 명령이라 승인을 거친다. 이 비대칭이 정확히 우리가 원하는 모양이다 — 보는 건 자유롭게, 바꾸는 건 확인하고.
규칙으로 못 박기
매번 클릭하기 번거롭다면, settings.json에 규칙을 박아 어떤 Git 명령을 자동 허용하고 어떤 것을 차단할지 정한다. 공식 문서의 예시가 정확히 이 차시의 주제를 담는다 — 커밋은 허용하되 푸시는 막는다.
{
"permissions": {
"allow": [
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
평가는 deny → ask → allow 순서이고 deny가 우선이라, 위 설정에서 git push는 어떤 경우에도 멈춰 선다. 베스트 프랙티스 문서도 안전하다고 아는 명령(npm run lint, git commit 등)만 골라 allowlist에 두라고 권한다.
알아 둘 안전장치 몇 가지
cd와git을 한 줄에 묶으면 항상 프롬프트가 뜬다 — 대상 디렉토리와 무관하게.cd는 보통 읽기 전용이지만,git과 결합하면 자동 승인에서 빠진다.git처럼 쓰기·실행 플래그가 가능한 명령은 unquoted glob이 끼면 프롬프트가 뜬다 — glob이-delete같은 플래그로 펼쳐질 수 있어서다.bypassPermissions모드는 신중히. 이 모드는 프롬프트를 건너뛰는데,.git·.config/git같은 경로에 대한 쓰기까지 스킵한다. 컨테이너·VM처럼 격리된 환경에서만 쓴다. (그래도rm -rf /·rm -rf ~같은 건 회로 차단기로 항상 프롬프트가 뜬다.)
권한 시스템 자체는 17차시에서, 그리고 43차시(전역 설정)·45차시(보안)에서 더 깊이 다룬다. 여기서는 안전 원칙이 권한 규칙으로 강제될 수 있다는 연결만 잡으면 된다.
안전한 루프, 한 장으로
37차시가 깔아 둔 토대를 한 흐름으로 묶으면 이렇다.
- 읽는다 —
git status로 무엇이,git diff로 어떻게,git log로 어떤 맥락에서. 전부 읽기 전용, 자동, 무해. - 분석한다 — 변경의 의도를 읽고, 단위로 묶고, 들어가면 안 될 것(디버그 코드·민감 정보)을 거른다.
- 사람이 검토한다 —
diff가 리뷰 표면이다. 받아들이기 전에 본다. - 안전하게 실행한다 — 커밋·푸시는 요청받아야, 기본 브랜치면 먼저 브랜치, 파괴적 명령·훅 스킵은 금지, 권한 시스템이 이 선을 강제한다.
그리고 이 모든 것 아래에, 영구 기록인 Git과 세션 단위 안전망인 체크포인트가 서로 다른 층으로 깔려 있다.
흔한 함정
/rewind(체크포인트)를 Git 대신 믿는다. 체크포인트는 local undo다. Bash로 일어난 변경(rm·mv)은 추적하지 않고, 30일쯤 뒤 정리되며, Git의 대체가 아니다. 영구 기록은 커밋으로 남긴다.- 읽기 전용 git까지 막아 두고 답답해한다.
git status·diff·log는 자동으로 돌아야 정상이다. 누가git전체에 ask/deny를 걸어 두지 않았는지부터 본다. - 테스트가 막힌다고
--no-verify로 넘긴다. 훅은 팀의 품질 게이트다. 우회가 아니라 고치는 게 맞다. Claude도 명시적 요청 없이는 훅을 스킵하지 않는다. --amend를 가볍게 쓴다. 마지막 커밋을 갈아치우므로, 방금 자기가 만든 커밋이 아니거나 남이 만든 커밋이면 위험하다. 기본은 새 커밋이고, amend 전엔 authorship을 확인한다.- 기본 브랜치에 바로 쌓는다.
main·master위라면 먼저 브랜치를 판다. 이런 규칙은 CLAUDE.md에 적어 두면 매번 말하지 않아도 된다. - 커밋·푸시가 자동으로 됐다고 기대한다(혹은 그 반대). Claude는 요청해야 커밋·푸시한다. 자동으로 돌리고 싶으면
allow Bash(git commit *)같은 권한 규칙을 명시적으로 둔다 — 단 푸시는deny Bash(git push *)로 막아 두는 편이 안전하다. - 민감 파일이 diff에 섞여 들어간다.
.env·*.key는 변경 분석에서 걸러야 하고,Read(.env)deny 같은 규칙으로 접근 자체를 막을 수 있다. bypassPermissions를 일상 모드로 쓴다..git쓰기까지 프롬프트를 스킵한다. 격리된 환경(컨테이너·VM) 전용이다.
정리
핵심 요점
- 에이전트 시대의 Git은 “마지막 절차”가 아니라 “자율성과 통제가 만나는 지점”이다. 되돌릴 수 있는 안전망이자, 변경을 사람이 검토하는 표면(
diff)이다. 섹션 8의 커밋(38)·PR(39)·리뷰(40)가 전부 이 토대 위에 올라간다. - 체크포인트(
/rewind)는 Git이 아니다. 세션 단위 local undo이고 Bash 변경(rm·mv)은 추적하지 않으며 30일쯤 뒤 정리된다 — 공식 표현 그대로 “local undo vs permanent history”, “Git의 대체가 아니다.” - 변경은 세 읽기 전용 명령으로 읽는다 —
status(무엇이)·diff(어떻게)·log(맥락). 셋 다 읽기 전용 git이라 권한 프롬프트 없이 돈다. Claude가 Git 작업을 늘 상태 읽기로 시작하는 이유다. - 변경 분석은 그 자체가 안전장치다. 의도를 읽고, 단위로 묶고, 디버그 코드·민감 정보를 거른다. 이 결과가 38·39차시의 커밋 메시지·PR 본문의 원재료가 된다.
- 차시의 심장은 내장 안전 원칙이다 — 커밋·푸시는 요청받아야, 기본 브랜치면 먼저 브랜치, 파괴적·되돌릴 수 없는 명령(force push·hard reset·히스토리 재작성) 금지, 훅 스킵(
--no-verify) 금지,--amend보다 새 커밋(쓸 땐 authorship 확인), git config는 그대로, 인터랙티브 플래그(-i) 미지원, 민감 파일(.env·*.key) 커밋 방지. - 원칙은 권한 시스템으로 강제된다(17차시). 읽기 전용 git은 자동,
git commit·git push는 승인.allow Bash(git commit *)+deny Bash(git push *)로 못 박고, 평가는 deny → ask → allow 순서라 deny가 우선이다.
다음 단계
이번 차시가 읽기와 안전의 토대였다면, 38차시는 그 위에서 처음으로 “쓰는” 작업 — 커밋 생성이다. status→diff→log로 분석한 변경을, Conventional Commits 형식의 메시지로 묶고, Co-Authored-By 트레일러로 Claude의 기여를 표시하고, HEREDOC으로 본문 있는 커밋을 만드는 흐름까지. 37차시에서 “왜 상태부터 읽는가”를 봤으니, 38차시에서 그 읽기가 어떻게 좋은 커밋 메시지가 되는지로 이어진다.
참고 자료
- Claude Code 보안 — 읽기 전용 기본 권한과
git status자동 실행, 사용자 검토 책임 - 권한 설정 — 읽기 전용
git형태,Bash(git commit *)허용·Bash(git push *)차단, deny→ask→allow 평가 순서 - 체크포인팅 —
/rewind, Bash 변경 미추적, “local undo vs permanent history”, Git의 대체 아님 - 베스트 프랙티스 — Explore→Plan→Implement→Commit 워크플로우, 체크포인트는 Git 대체 아님
- 일반 워크플로우 — 변경 요약·PR 생성 프롬프트 레시피,
gh pr create세션 링크