GitGit 입문버전 관리GitHub협업Claude CodeAI 코딩 에이전트git worktree체크포인트권한 설정위험한 git 명령
Git, 이것만 알면 협업한다 7편 — Claude Code 시대의 git: 에이전트에게 맡기고, 사람이 감독하는 법
AI 코딩 에이전트가 파일을 고치고 git 명령까지 직접 실행하는 시대에는 git 기초가 오히려 더 중요해집니다. 시리즈 마지막 편에서는 Claude Code가 git을 어떻게 쓰는지(상태 확인·브랜치·커밋·PR·worktree·체크포인트)를 공식 문서로 확인하고, 사람이 감독할 지점과 위험한 명령, 에이전트에게 말하는 법, 1~6편 전체 치트시트까지 한 번에 정리합니다.
지난 여섯 편 동안 민지는 동네 카페 웹사이트 cafe-menu를 만들면서 git을 하나씩 익혔습니다. 세이브 포인트(커밋)를 남기고, GitHub에 올리고, 도윤과 브랜치를 나눠 작업하고, 충돌을 풀고, Pull Request로 리뷰를 주고받았습니다.
그리고 가을이 왔습니다. 사장님이 "가을 시즌 메뉴 페이지를 따로 만들어 달라"고 부탁했고, 민지는 이번에는 직접 HTML을 쓰는 대신 Claude Code(터미널에서 동작하는 Anthropic의 AI 코딩 에이전트)에게 맡겨 보기로 했습니다. 에이전트는 파일을 읽고, 새 파일을 만들고, 기존 파일을 고치고, git status나 git commit 같은 명령도 직접 실행합니다.
여기서 흔히 생기는 오해가 하나 있습니다. "AI가 알아서 해 주니까 이제 git은 몰라도 되겠지." 실제로는 정반대입니다. 에이전트가 빠르게, 많이, 스스로 움직일수록 사람은 "지금 무엇이 바뀌었나", "되돌릴 수 있나", "남에게 공유해도 되나"를 판단해야 하고, 그 판단의 언어가 바로 git입니다. 이번 편은 시리즈의 마지막으로, 1~6편에서 배운 개념이 에이전트와 일할 때 어디서 쓰이는지 전부 연결합니다.
이 글의 기준 — Claude Code 기능 설명은 2026년 9월 기준 공식 문서(code.claude.com/docs)와 로컬에 설치한 Claude Code 2.1.283의 claude --help로 확인한 내용만 담았습니다. git 출력 예시는 모두 git 2.55에서 직접 실행해 얻은 것입니다. Claude Code는 업데이트가 잦으니, 설정을 바꾸기 전에는 공식 문서를 한 번 더 확인하세요.
1. 무엇이 달라졌나: git이 "안전망 · 감사 기록 · 인수인계 창구"가 된다
사람이 혼자 코드를 고칠 때는 한 번에 한두 파일을 천천히 바꿉니다. 무엇을 바꿨는지 대개 머릿속에 남아 있죠. 에이전트는 다릅니다. 한 번의 요청에 파일 열 개를 몇십 초 만에 고치고, 테스트를 돌리고, 결과에 따라 또 고칩니다. 사람이 그 속도를 눈으로 따라가기는 어렵습니다.
그래서 git의 역할이 세 가지로 커집니다.
🛟
안전망 — "망쳐도 돌아갈 곳이 있다"
에이전트에게 일을 시키기 직전에 깨끗한 커밋이 있으면, 결과가 마음에 안 들어도 그 지점으로 돌아가면 됩니다. 커밋이 없으면 "원래 어땠는지"를 아무도 모릅니다(5편의 restore·revert·reflog가 여기서 빛납니다).
🔍
감사 기록 — "무엇이 바뀌었는지 증거로 본다"
에이전트가 "다 했어요"라고 말해도, 실제로 무엇이 바뀌었는지는 git diff가 말해 줍니다. 말이 아니라 diff를 믿는 습관이 에이전트 시대의 핵심 기술입니다(2편).
🤝
인수인계 창구 — "에이전트와 사람이 브랜치·커밋·PR로 주고받는다"
에이전트는 브랜치에서 작업하고 커밋 메시지로 설명을 남기고, 사람은 PR에서 리뷰합니다. 동료 개발자와 협업할 때 쓰던 그 흐름(4편·6편)이 사람과 에이전트 사이에도 그대로 쓰입니다.
한 문장으로 줄이면 이렇습니다. 에이전트는 손이 빠른 동료이고, git은 그 동료와 일하는 규칙입니다. 규칙을 모르면 빠른 동료는 오히려 위험해집니다.
Claude Code는 대화가 시작될 때 저장소의 git 상태 스냅샷을 Claude에게 넘겨줍니다. 설정 문서에 따르면 이 스냅샷에는 현재 브랜치, 메인 브랜치, git status 출력, 최근 커밋이 들어 있습니다. 그래서 첫 질문을 하기도 전에 에이전트는 "지금 main에 있고, 수정 중인 파일이 두 개 있다" 정도는 알고 시작합니다.
주의할 점은 이것이 시작 시점의 사진이라는 것입니다. 대화 도중에 사람이 터미널에서 브랜치를 바꾸거나 커밋해도 스냅샷은 그대로이므로, 에이전트는 필요할 때 git status·git diff·git log를 다시 실행해 최신 상태를 확인합니다. 이 명령들은 읽기 전용이라 권한 확인 없이 실행되는 기본 목록(git의 읽기 전용 형태 포함)에 들어 있습니다.
💡
그래서 시작 전 "깨끗한 작업 폴더"가 중요합니다. 작업 폴더에 내가 고치다 만 파일이 섞여 있으면, 에이전트는 그것까지 "지금 상태"로 받아들이고 작업합니다. 나중에 diff를 볼 때 어디까지가 내 것이고 어디부터가 에이전트 것인지 구분하기도 어려워집니다.
2-2. 세션 안에서 변경 사항 보기: /diff
Claude Code 안에서 /diff를 입력하면 작업 폴더의 변경 사항을 바로 볼 수 있습니다. 공식 문서 표현으로는 "Claude가 지금까지 만든 수정과 아직 커밋하지 않은 다른 변경을 함께" 보여 줍니다. 즉 /diff는 에이전트만의 특별한 기록이 아니라 git이 보는 작업 폴더 변경분입니다. 터미널에서 직접 git diff를 실행해도 같은 내용을 확인할 수 있습니다.
2-3. 커밋과 PR을 만든다 — 공동 작성자 표시와 함께
Claude Code에는 커밋 메시지와 Pull Request를 쓰는 방법에 대한 기본 지침이 내장되어 있습니다(설정 includeGitInstructions를 false로 두면 이 지침과 앞의 git 상태 스냅샷을 함께 뺄 수 있습니다). "지금 변경 사항 커밋해 줘", "PR 만들어 줘"라고 부탁하면 에이전트가 메시지를 써서 커밋하고, GitHub CLI(gh)로 PR을 엽니다.
Claude Code가 만든 커밋에는 기본적으로 공동 작성자 트레일러(커밋 메시지 끝에 붙는 키: 값 형식의 꼬리표)가 붙습니다. 설정 문서에 따르면 기본값은 Co-Authored-By: <모델 이름> <noreply@anthropic.com> 형식이고, 이름에는 커밋할 때 쓰던 모델 이름(예: Claude Sonnet 5)이 들어갑니다. 덕분에 나중에 git log만 봐도 어떤 커밋에 AI가 참여했는지 알 수 있습니다. 이 문구는 attribution 설정으로 바꾸거나 숨길 수 있습니다.
json
{"attribution":{"commit":"Co-Authored-By: Claude <noreply@anthropic.com>","pr":""}}
위 예시는 커밋 트레일러를 고정 문구로 바꾸고, PR 설명의 AI 표시는 빈 문자열로 숨기는 설정입니다. 팀 규칙에 맞게 고르면 됩니다.
또 하나 유용한 점이 있습니다. Claude가 gh pr create로 PR을 만들면 그 세션이 PR에 연결되어, 나중에 claude --from-pr 1234처럼 PR 번호로 당시 대화를 다시 찾아 열 수 있습니다. "이 PR은 왜 이렇게 만들었더라?"를 물어볼 곳이 남는 셈입니다.
2-4. worktree로 여러 작업을 동시에 — claude --worktree
worktree(워크트리)는 하나의 저장소에서 작업 폴더를 여러 개 꺼내 쓰는 git 기능입니다. 폴더마다 다른 브랜치를 체크아웃해 두고, 기록(.git)은 함께 씁니다. 한 폴더에서 에이전트가 기능을 만드는 동안 다른 폴더에서 다른 에이전트가 버그를 고쳐도 파일이 서로 부딪히지 않습니다.
Claude Code는 이것을 옵션 하나로 해 줍니다.
bash
claude --worktree seasonal-menu
공식 문서에 따르면 이렇게 실행하면 저장소 루트의 .claude/worktrees/seasonal-menu/에 새 작업 폴더가 생기고, worktree-seasonal-menu라는 새 브랜치에서 세션이 시작됩니다. 이름을 생략하면 이름을 자동으로 지어 줍니다. 기본적으로 새 worktree는 원격의 기본 브랜치(보통 main)에서 갈라져 나오므로, 저장소에 커밋이 하나 이상 있어야 합니다.
세션을 끝낼 때의 정리 규칙도 알아 두면 좋습니다.
worktree 상태
세션 종료 시 Claude Code의 동작
변경도 새 커밋도 없음 (깨끗함)
이름을 붙이지 않은 세션이면 worktree와 브랜치를 자동으로 지움. 이름 붙인 세션이면 먼저 물어봄
수정·새 파일·새 커밋이 있음
남길지 지울지 물어봄. 남기면 폴더와 브랜치가 유지되고, 다시 돌아올 명령을 알려 줌. 지우면 그 안의 작업도 함께 사라짐
상태를 확인할 수 없음
자동으로 지우지 않고 물어봄
문서는 .claude/worktrees/를 .gitignore에 넣으라고 권합니다. 안 그러면 메인 작업 폴더에서 git status를 칠 때 worktree 내용이 추적되지 않은 파일로 보입니다. 원리가 궁금하다면 같은 일을 git 명령으로 직접 해 보면 됩니다.
bash
git worktree add .claude/worktrees/fix-typo -b worktree-fix-typo
git worktree list
text
Preparing worktree (new branch 'worktree-fix-typo')
HEAD is now at 1e2e8da Add autumn seasonal menu page
/Users/minji/cafe-menu 1e2e8da [feature/seasonal-menu]
/Users/minji/cafe-menu/.claude/worktrees/fix-typo 1e2e8da [worktree-fix-typo]
git branch를 치면 다른 worktree에서 체크아웃 중인 브랜치 앞에 + 표시가 붙습니다. 다 쓴 worktree는 이렇게 치웁니다.
worktree = 4편의 브랜치 + 폴더 하나 더. 브랜치는 "기록의 갈래"이고, worktree는 "그 갈래를 펼쳐 놓을 책상"입니다. 책상이 하나면 브랜치를 바꿀 때마다 책상 위를 치워야 하지만(git switch), 책상이 여러 개면 동시에 펼쳐 둘 수 있습니다. 그 밖에 한 세션 안의 서브에이전트를 각자 worktree에서 돌리는 방법, 여러 작업 단위를 worktree 여러 개로 나눠 병렬 처리하는 /batch 같은 기능도 있으니 필요해지면 공식 문서의 Worktrees 페이지를 참고하세요.
2-5. GitHub에서 @claude로 부르기 (짧게)
Claude Code는 GitHub Actions와도 연결할 수 있습니다. 설정을 마친 저장소에서는 이슈나 PR 댓글에 @claude를 적어 부탁하면 Claude가 코드를 분석하고, 수정하고, 커밋을 push합니다. 설정은 Claude Code 안에서 /install-github-app을 실행하면 안내에 따라 진행되고(저장소 관리자 권한 필요), 워크플로 파일은 anthropics/claude-code-action@v1을 씁니다. 공식 문서는 이때도 "Claude의 변경 사항을 머지 전에 검토하라"고 강조합니다. 결국 여기서도 사람이 할 일은 6편에서 배운 PR 리뷰입니다.
3. 체크포인트(/rewind)와 git 커밋은 다릅니다
Claude Code에는 체크포인트라는 되돌리기 기능이 있습니다. 에이전트와 일하다 보면 "git 커밋이랑 뭐가 다르지?"가 꼭 헷갈리니, 여기서 확실히 정리합시다.
공식 문서에 따르면 Claude Code는 사람이 프롬프트를 보낼 때마다 그 직전의 코드 상태를 자동으로 저장합니다. /rewind를 입력하거나, 입력창이 비어 있을 때 Esc를 두 번 누르면 되감기 메뉴가 열리고, 원하는 시점을 골라 코드와 대화 모두 되돌리기 / 대화만 되돌리기 / 코드만 되돌리기 등을 선택할 수 있습니다. 편리하지만 한계가 분명합니다.
구분
체크포인트 (/rewind)
git 커밋
누가 만드나
Claude Code가 프롬프트마다 자동으로
사람(또는 부탁받은 에이전트)이 의도적으로
무엇을 기억하나
Claude의 파일 편집 도구로 바뀐 파일
스테이징한 모든 파일의 전체 스냅샷
놓치는 것
Bash 명령으로 바뀐 파일(rm·mv·cp 등), 대부분의 서브에이전트 편집, 사람이 직접 고친 파일, 다른 세션의 편집
커밋하지 않은 것 (그래서 자주 커밋)
어디에 있나
내 컴퓨터의 세션 기록 안 (최근 100개, 기본 약 30일 뒤 정리)
저장소 기록 안. push하면 원격에도
누가 볼 수 있나
나만
push하면 팀 전체
적합한 용도
"방금 그 시도 취소" 같은 세션 안의 빠른 실행 취소
오래 남길 기록, 협업, 리뷰, 배포
공식 문서도 체크포인트를 설명하며 "버전 관리를 대신하지 않는다"고 분명히 적어 둡니다. 세션 수준의 빠른 복구용이고, 영구 기록과 협업에는 git 커밋·브랜치를 계속 쓰라는 것입니다. 특히 첫 번째 한계가 중요합니다. 에이전트가 터미널 명령으로 파일을 지우거나 옮기면 /rewind로는 되돌릴 수 없습니다. 그때 믿을 곳은 작업 전에 만들어 둔 커밋뿐입니다.
⚠️
이름이 비슷해서 헷갈리는 것 하나 더. Claude Code의 /branch 명령은 git 브랜치가 아니라 대화를 갈래로 나누는 기능입니다. 대화를 이 시점에서 복제해 다른 방향을 시도해 보는 것이지, 저장소에 브랜치를 만들지 않습니다. git 브랜치가 필요하면 "새 브랜치 만들어서 작업해 줘"라고 말하세요.
에이전트가 git 명령을 직접 실행할 수 있다는 것은, 설정하기에 따라 git push나 git reset --hard도 실행할 수 있다는 뜻입니다. Claude Code는 이를 권한 모드와 권한 규칙으로 다룹니다.
4-1. 권한 모드 한눈에 보기
모드
묻지 않고 실행되는 것
어울리는 상황
default (화면 표시: Manual)
읽기만
모든 동작을 직접 확인하고 싶을 때
acceptEdits
읽기, 파일 편집, mkdir·mv·cp 같은 흔한 파일 명령
편집 결과는 나중에 git diff로 볼 생각일 때
plan
읽기 (계획만 세우고 소스 파일은 편집하지 않음)
고치기 전에 계획부터 검토할 때
auto
대부분, 단 별도의 분류 모델이 실행 전에 검사
긴 작업, 확인 창이 너무 많을 때
dontAsk
읽기와 미리 허용한 도구만. 물어볼 상황이면 거부
CI·스크립트처럼 잠가 둔 환경
bypassPermissions
전부
격리된 컨테이너·VM에서만
세션 중에는 Shift+Tab으로 모드를 돌아가며 바꿀 수 있고, 시작할 때 claude --permission-mode plan처럼 지정할 수도 있습니다. 알아 둘 변화가 하나 있습니다. 공식 문서에 따르면 Claude Code 2.1.283부터는 터미널과 VS Code의 대화형 세션이 기본적으로 auto 모드로 시작합니다(그 이전 버전에서는 Pro·Max·Team 요금제에서만 기본값).
4-2. auto 모드는 무엇을 막고, 무엇을 허용하나
auto 모드의 분류 모델은 기본적으로 강제 push(force push)를 막습니다. 또 커밋하지 않은 변경을 날릴 수 있다고 보고 git reset --hard, git checkout -- ., git restore ., git clean -fd, git stash drop, git stash clear도 막는 목록에 올려 둡니다. 이 명령들이 실행되기 전에는 Claude Code가 직접 git status를 돌려서, 날아갈 작업이 있는지 분류 모델에게 보여 준다고 문서에 적혀 있습니다.
반면 지금 작업 중인 저장소의 어느 브랜치로든 push하는 것은 기본적으로 허용됩니다. 기본 브랜치(main)도 포함입니다(내용에 비밀 정보가 섞였는지 등은 따로 검사하고, 원격 저장소의 브랜치 보호 규칙은 그대로 적용됩니다). 즉 auto 모드를 그대로 쓰면 "push는 내가 할게"라는 바람은 설정으로 표현해 두지 않는 한 보장되지 않습니다.
대화로 선을 그을 수도 있습니다. 문서에 따르면 "push하지 마"나 "내가 검토하기 전엔 배포하지 마"처럼 대화에서 말한 경계를 분류 모델이 차단 신호로 읽습니다. 다만 규칙으로 저장되는 게 아니라 대화 기록에서 다시 읽는 것이어서, 긴 대화가 요약(compaction)되며 그 메시지가 빠지면 경계도 사라질 수 있습니다. 확실하게 막으려면 아래처럼 설정 파일에 규칙으로 적으라는 것이 문서의 권고입니다.
4-3. settings.json으로 git 명령에 규칙 걸기
권한 규칙에는 세 종류가 있습니다. allow(묻지 않고 허용), ask(매번 확인), deny(거부). 평가 순서는 deny → ask → allow이고, 먼저 걸린 규칙이 결과를 정합니다. 더 구체적인 allow 규칙이 있어도 deny를 뚫지 못합니다. 그리고 deny 규칙은 bypassPermissions를 포함한 모든 모드에서 적용됩니다.
민지가 프로젝트의 .claude/settings.json(팀과 공유되는 프로젝트 설정)에 넣을 만한 예시는 이렇습니다.
push는 할 때마다 확인 창을 띄우고(auto 모드에서도 이런 ask 규칙은 확인 창을 띄웁니다),
강제 push·reset --hard·clean은 아예 막습니다.
규칙 문법에서 *는 "아무 글자나"를 뜻하고, 끝의 *는 인자 없는 명령도 포함합니다. 그래서 Bash(git clean *)은 git clean과 git clean -fd 모두에 걸립니다. 규칙은 세션 안에서 /permissions로 확인·수정할 수도 있습니다. 나만 쓰는 설정은 .claude/settings.local.json에 두면 되는데, Claude Code가 이 파일을 처음 만들 때 git 전역 제외 목록에 넣어 커밋되지 않게 해 줍니다.
🧱
규칙은 "보안 장벽"이 아니라 "울타리"입니다. 공식 문서가 직접 밝히듯 Bash 규칙은 명령을 쓰인 그대로 비교합니다. Bash(git push *)는 git push origin main은 잡지만 git -C . push origin main처럼 다르게 쓴 명령은 잡지 못합니다. 규칙은 에이전트가 평소 쓰는 형태를 막아 주는 좋은 기본값이고, 진짜 최후의 방어선은 GitHub 쪽의 main 브랜치 보호 규칙(6편)입니다. 둘 다 거세요.
4-4. 훅(hook)으로 한 번 더 막기
훅은 Claude Code가 특정 시점에 자동으로 실행하는 사용자 스크립트입니다. PreToolUse 훅은 도구가 실행되기 직전에 돌고, 스크립트가 종료 코드 2로 끝나면 그 실행을 막으며 오류 메시지를 Claude에게 이유로 전달합니다. 공식 문서의 예시를 git에 맞게 바꾸면 이런 모양입니다.
bash
#!/bin/bash# .claude/hooks/block-dangerous-git.sh
INPUT=$(cat)
COMMAND=(echo"(echo "(echo"INPUT" | jq -r '.tool_input.command')
ifecho"COMMAND"∣grep−Eq′git(push.∗(−−force∣−f)(∣COMMAND" | grep -Eq 'git (push .*(--force|-f)( |COMMAND"∣grep−Eq′git(push.∗(−−force∣−f)(∣)|reset --hard|clean -[a-z]*f)'; then
echo "Blocked: 위험한 git 명령은 사람이 직접 실행합니다" >&2
exit 2
fi
exit 0
이 패턴으로 직접 시험해 보면 git push --force origin main, git push -f, git reset --hard HEAD~1, git clean -fd는 막히고, git push --force-with-lease와 미리 보기인 git clean -n -d는 통과합니다. 다만 권한 규칙과 마찬가지로 글자 패턴을 검사하는 것이라 완벽하지는 않습니다. 예를 들어 브랜치 이름 앞에 +를 붙이는 강제 push(git push origin +main)는 이 패턴을 빠져나갑니다. 팀 방침에 맞게 다듬으세요. 그래도 "에이전트가 무심코 치는 위험 명령"을 한 번 더 걸러 주는 역할로는 충분합니다. 참고로 .git 폴더 자체는 Claude Code가 보호 경로로 취급해, bypassPermissions가 아닌 한 그 안에 쓰는 동작이 자동 승인되지 않습니다.
5. 1~6편 개념이 에이전트와 일할 때 쓰이는 곳
시리즈에서 배운 개념을 에이전트 상황에 한 장으로 연결해 봅시다. 가운데 열은 에이전트가 하는 일, 오른쪽 열은 그때 사람이 확인할 것입니다.
main..브랜치(점 두 개)는 "브랜치에만 있는 커밋 목록", main...브랜치(점 세 개)를 git diff에 쓰면 "브랜치가 main에서 갈라진 뒤 바뀐 내용"을 보여 줍니다. PR의 "Files changed" 탭과 같은 관점이라, PR을 열기 전에 로컬에서 미리 리뷰할 때 딱 좋습니다. --stat으로 규모를 먼저 보고, 예상 밖의 파일이 있으면 그 파일부터 git diff main...feature/seasonal-menu -- 파일이름으로 자세히 봅니다.
✅
리뷰할 때 특히 볼 것 다섯 가지 — ① 부탁하지 않은 파일이 바뀌었나 ② 설정·잠금 파일(package-lock.json 등)이 이유 없이 바뀌었나 ③ 비밀 정보가 들어갔나 ④ 테스트를 지우거나 건너뛰게 만들지 않았나 ⑤ 커밋 메시지가 실제 변경과 맞나
에이전트에게 git 일을 맡길 때는 범위(어디까지 해도 되는지)와 멈출 지점(어디서 사람을 기다릴지)을 함께 말하는 것이 핵심입니다. 자주 쓰는 부탁을 모았습니다. 그대로 복사해 써도 됩니다.
범위와 멈출 지점을 함께 말하기
시작할 때
"새 브랜치 feature/seasonal-menu에서 작업하고, 끝나면 커밋만 해 줘. push는 내가 할게."
커밋 정리
"지금 변경 사항을 요약하고, 커밋을 논리 단위로 나눠 줘. 각 커밋에 어떤 파일이 들어가는지 먼저 보여 주고 내가 좋다고 하면 커밋해."
충돌
"충돌 난 파일을 설명하고, 양쪽이 각각 무엇을 하려던 건지와 해결안을 제시해 줘. 적용은 내가 확인한 뒤에."
그 밖에 상황별로 쓸 만한 부탁입니다.
text
마지막 커밋을 revert 해 줘. reset은 쓰지 마. 이미 push한 커밋이야.
text
작업 전에 git status를 보여 주고, 커밋 안 된 변경이 있으면 멈추고 나한테 물어봐.
text
main 대비 이 브랜치에서 바뀐 걸 git diff main...HEAD 기준으로 파일별로 요약해 줘. 부탁하지 않은 변경이 있으면 따로 표시해.
text
PR을 만들어 줘. 제목은 한 줄, 본문에는 바꾼 이유, 확인 방법, 남은 할 일을 적어. 머지는 하지 마.
text
이 명령이 뭘 지우는지 설명만 해 줘. 실행은 하지 마: git clean -fd
text
worktree를 하나 만들어서 오타 수정만 따로 해 줘. 지금 작업 폴더는 건드리지 마.
🗣️
잘 되는 부탁의 공통점 — ① 브랜치 이름이나 대상 파일처럼 구체적인 범위 ② "push는 내가", "머지는 하지 마" 같은 명시적인 멈춤 ③ "revert로, reset은 쓰지 마"처럼 원하는 방법 ④ 실행 전에 보여 달라는 확인 요청. 앞에서 본 것처럼 auto 모드에서는 대화로 말한 "하지 마"가 차단 신호가 되지만, 반드시 지켜야 하는 선은 권한 규칙으로도 걸어 두세요.
8. 위험한 명령과 더 안전한 대안
에이전트가 제안하든 내가 치든, 아래 명령이 보이면 한 박자 멈추세요. 공통점은 되돌리기 어렵거나, 남의 작업까지 건드린다는 것입니다.
명령
무엇이 사라지나
왜 위험한가
더 안전한 대안
git reset --hard
커밋하지 않은 수정 전부 + 되감은 커밋
커밋 안 한 변경은 reflog로도 못 살림
git stash로 치워 두기, 공유된 커밋은 git revert
git push --force
원격 브랜치에서 내가 모르는 남의 커밋
동료의 작업을 원격에서 덮어씀
git push --force-with-lease, 애초에 공유 브랜치는 다시 쓰지 않기
git clean -fdx
추적 안 되는 파일·폴더 + ignore된 파일(.env 등)
git이 기록한 적 없는 파일이라 복구 불가
먼저 git clean -n -d로 미리 보기
git checkout . / git restore .
작업 폴더의 수정 전부
커밋 안 한 수정은 복구 불가
파일을 지정해서 git restore 파일, 또는 git stash
git branch -D
병합 안 된 브랜치의 커밋 (가리키는 이름)
경고 없이 지움
git branch -d (병합 안 됐으면 거절해 줌)
공유 브랜치에서 git rebase
원래 커밋 해시 (기록을 새로 씀)
동료의 기록과 갈라져 강제 push가 필요해짐
공유 브랜치에서는 merge, rebase는 나만 쓰는 브랜치에서만
git stash drop / clear
보관해 둔 변경
잊고 있던 작업이 사라짐
git stash list로 내용 확인 후 pop
git은 이런 명령 앞에서 꽤 친절하게 브레이크를 걸어 줍니다. 몇 가지를 직접 실행해 보았습니다.
git clean은 -n으로 미리 볼 수 있습니다. 실제로 지우지 않고 "지울 목록"만 보여 줍니다.
bash
git clean -n -d
text
Would remove notes-draft.txt
Would remove tmp/
git branch -d는 병합 안 된 브랜치를 지키려 합니다. 대문자 -D는 이 확인을 건너뜁니다.
bash
git branch -d feature/seasonal-menu
text
error: the branch 'feature/seasonal-menu' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/seasonal-menu'
hint: Disable this message with "git config set advice.forceDeleteBranch false"
--force-with-lease는 남의 커밋을 덮어쓰기 직전에 멈춥니다. 아래는 민지가 커밋을 고쳐 쓴(amend) 사이에 도윤이 같은 브랜치에 커밋을 push해 둔 상황입니다. 그냥 --force였다면 도윤의 커밋이 원격에서 사라졌겠지만, --force-with-lease는 "내가 마지막으로 본 원격 상태와 다르다(stale info)"며 거절합니다.
bash
git push --force-with-lease
text
To ../origin.git
! [rejected] feature/seasonal-menu -> feature/seasonal-menu (stale info)
error: failed to push some refs to '../origin.git'
From ../origin
1e2e8da..c7551b7 feature/seasonal-menu -> origin/feature/seasonal-menu
* 390916b Add autumn seasonal menu page (amended)
| * c7551b7 Add apple cinnamon tea
| * 1e2e8da Add autumn seasonal menu page
|/
* 285f180 Add vanilla latte to menu
* b876176 Add first version of cafe site
그래프를 보면 도윤의 Add apple cinnamon tea가 원격에 살아 있습니다. 이제 민지는 강제로 덮어쓰는 대신 도윤의 커밋을 받아 합치는 쪽을 택하면 됩니다(5편·6편).
이미 공유한 커밋은 revert로 되돌립니다. 기록을 지우지 않고 "반대로 바꾸는 새 커밋"을 쌓으므로 동료의 기록과 어긋나지 않습니다.
bash
git revert HEAD
git log --oneline -3
text
[feature/seasonal-menu f4184cc] Revert "Add autumn seasonal menu page"
Date: Mon Oct 5 10:00:00 2026 +0900
2 files changed, 1 insertion(+), 12 deletions(-)
delete mode 100644 seasonal.html
f4184cc Revert "Add autumn seasonal menu page"
1e2e8da Add autumn seasonal menu page
285f180 Add vanilla latte to menu
아래 도구에 명령을 입력하거나 골라 보세요. 위험도, 사라지는 것, 더 안전한 대안을 알려 줍니다.
9. 시나리오: 민지와 Claude Code의 "가을 시즌 메뉴" 한 판
이제 처음의 장면으로 돌아갑니다. 민지는 cafe-menu 폴더에서 Claude Code를 열고 이렇게 부탁했습니다.
text
가을 시즌 메뉴 페이지(seasonal.html)를 만들고 index.html 메뉴 옆에 링크를 달아 줘.
새 브랜치 feature/seasonal-menu에서 작업하고, 끝나면 커밋만 해 줘. push는 내가 할게.
git의 눈으로 무슨 일이 일어나는지 순서대로 따라가 봅시다.
① 상황 파악. 에이전트는 대화 시작 때 받은 스냅샷에 더해 최신 상태를 확인합니다.
bash
git status
git log --oneline -3
text
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
285f180 Add vanilla latte to menu
b876176 Add first version of cafe site
② 브랜치 만들기. 부탁대로 새 브랜치로 옮깁니다. 이제부터의 변경은 main과 분리됩니다.
bash
git switch -c feature/seasonal-menu
text
Switched to a new branch 'feature/seasonal-menu'
③ 파일 편집. 에이전트가 파일 편집 도구로 seasonal.html을 만들고 index.html의 메뉴 줄을 고칩니다. 이 편집은 체크포인트에도 기록됩니다. 이 시점의 git 상태는 이렇습니다.
text
On branch feature/seasonal-menu
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.html
Untracked files:
(use "git add <file>..." to include in what will be committed)
seasonal.html
no changes added to commit (use "git add" and/or "git commit -a")
민지는 여기서 /diff로 한 번 들여다봅니다. 바뀐 건 링크 한 줄과 새 파일 하나. 부탁한 범위 그대로입니다.
④ 스테이징과 커밋. 에이전트는 관련 파일만 골라 스테이징합니다. git add .로 폴더를 통째로 올리지 않는 것이 좋은 습관입니다.
bash
git add seasonal.html index.html
git status --short
text
M index.html
A seasonal.html
커밋 메시지 끝에는 공동 작성자 트레일러가 붙습니다.
text
commit 1e2e8da7a478cc8c0b2363fcd003bc23eadf5134
Author: Minji <minji@example.com>
Date: Mon Oct 5 10:00:00 2026 +0900
Add autumn seasonal menu page
- New seasonal.html with two autumn drinks
- Link it from the nav in index.html
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
작성자(Author)는 git 설정에 등록된 민지이고, 트레일러가 "Claude와 함께 만들었다"는 사실을 남깁니다. 에이전트는 부탁대로 여기서 멈추고 "커밋까지 했습니다. push는 직접 해 주세요"라고 보고합니다.
⑤ 사람의 리뷰. 민지는 체크리스트의 "후" 단계를 밟습니다. git diff --stat main...feature/seasonal-menu로 두 파일만 바뀐 것을 확인하고, 브라우저로 seasonal.html을 열어 봅니다.
⑥ push와 PR은 사람이. 확인이 끝나면 민지가 직접 push합니다.
bash
git push -u origin feature/seasonal-menu
text
To ../origin.git
* [new branch] feature/seasonal-menu -> feature/seasonal-menu
branch 'feature/seasonal-menu' set up to track 'origin/feature/seasonal-menu'.
(예시에서는 로컬 가짜 원격 ../origin.git을 썼습니다. 실제로는 GitHub 주소가 보입니다.) 그다음 PR을 열어 도윤에게 리뷰를 부탁하면, 6편에서 배운 흐름 그대로 이어집니다. PR 작성까지 에이전트에게 맡겨도 되지만, 머지 버튼은 사람이 누르는 것이 이 시리즈의 결론입니다.
아래 재생기로 같은 세션을 한 단계씩 넘겨 보세요. 각 단계에서 어느 공간이 바뀌는지, 사람이 무엇을 확인해야 하는지 표시됩니다.
10. 시리즈를 마치며: 전체 명령 치트시트
일곱 편 동안 다룬 명령을 한곳에 모았습니다. 검색하거나 편별로 걸러 보세요. 각 줄의 편 번호를 누르면 해당 편으로 이동합니다.
git worktree add/list/remove · claude --worktree 이름
작업 폴더 여러 개로 병렬 작업
7
에이전트
git clean -n -d · git push --force-with-lease
지우기 전 미리 보기 / 남의 커밋을 지키는 강제 push
7
git의 역사나 내부 구조(객체·해시·참조)까지 궁금해졌다면 Git 완전 정복에서 더 깊이 들어가 볼 수 있습니다.
자주 하는 질문(FAQ)
Q1. 체크포인트가 있는데 굳이 에이전트 작업 전에 커밋해야 하나요?
네. 체크포인트는 Claude의 파일 편집 도구로 바뀐 파일만 기억하고, Bash 명령(rm, mv 등)으로 바뀐 파일이나 내가 직접 고친 파일은 되돌리지 못합니다. 내 컴퓨터의 세션 안에만 있어서 동료와 공유되지도 않습니다. 공식 문서도 체크포인트는 버전 관리를 대신하지 않는다고 말합니다. 작업 전 커밋 한 번이 가장 확실한 보험입니다.
Q2. 에이전트가 만든 커밋의 작성자는 누구로 남나요?
커밋의 Author는 그 컴퓨터의 git 설정(user.name, user.email)에 적힌 사람입니다. Claude Code는 여기에 더해 커밋 메시지 끝에 Co-Authored-By: <모델 이름> <noreply@anthropic.com> 트레일러를 기본으로 붙입니다. 팀 규칙에 따라 attribution 설정으로 문구를 바꾸거나 숨길 수 있습니다.
Q3. "push하지 마"라고 말하면 확실히 안 하나요?
auto 모드에서는 대화에서 말한 경계를 분류 모델이 차단 신호로 씁니다. 하지만 규칙으로 저장되는 것이 아니라서, 긴 대화가 요약되며 그 문장이 빠지면 효력이 사라질 수 있다고 공식 문서가 설명합니다. 반드시 지켜야 한다면 settings.json에 "ask": ["Bash(git push *)"]나 deny 규칙을 넣고, GitHub에서 main 보호 규칙까지 켜 두세요.
Q4. worktree를 쓰면 저장소가 두 개가 되나요?
아니요. 작업 폴더만 여러 개이고 기록(.git)은 하나를 함께 씁니다. 그래서 한 worktree에서 만든 커밋은 다른 worktree에서도 git log --all로 보입니다. 다만 같은 브랜치를 두 worktree에서 동시에 체크아웃할 수는 없으므로, 보통 worktree마다 새 브랜치를 씁니다(claude --worktree는 worktree-<이름> 브랜치를 자동으로 만듭니다).
Q5. 비개발자인데 에이전트가 만든 diff를 다 이해해야 하나요?
코드 한 줄 한 줄을 다 이해하지 못해도 괜찮습니다. 대신 ① 바뀐 파일 목록이 부탁한 범위와 맞는지(git diff --stat) ② 비밀 정보나 엉뚱한 파일이 없는지 ③ 결과물을 직접 열어 보고 테스트했는지는 확인할 수 있습니다. 모르는 부분은 에이전트에게 "이 diff를 줄 단위로 설명해 줘"라고 물어보면 됩니다. 설명을 듣고 판단하는 사람이 여러분이라는 점이 중요합니다.
Q6. 권한 확인 창이 너무 많이 떠서 귀찮아요. 전부 끄면 안 되나요?
bypassPermissions는 공식 문서가 "격리된 컨테이너나 VM에서만" 쓰라고 권하는 모드입니다. 대신 자주 쓰는 안전한 명령(예: Bash(git commit *), 테스트 명령)은 allow 규칙으로 풀어 주고, push·강제 push·reset --hard처럼 되돌리기 어려운 것만 ask/deny로 남기는 편이 확인 창도 줄이고 안전도 지키는 방법입니다.
이번 편 요약
주제
기억할 것
왜 git이 더 중요해졌나
에이전트는 빠르고 많이 바꾼다 → git은 안전망 · 감사 기록 · 인수인계 창구
Claude Code의 git 사용
시작 시 git 상태 스냅샷을 읽음 · /diff · 부탁하면 커밋/PR(gh) · Co-Authored-By 트레일러 · claude --worktree
체크포인트 vs 커밋
/rewind·Esc Esc는 세션 안의 되감기. Bash로 바뀐 파일은 못 되돌림. 영구 기록은 커밋
선 긋기
2.1.283은 기본 auto 모드 · auto는 force push·reset --hard 등을 막지만 push는 허용 → ask: Bash(git push *) · deny로 위험 명령 차단 · 훅 · main 보호 규칙
감독 체크리스트
전: 깨끗한 작업 폴더 + 새 브랜치 / 중: 작은 커밋 / 후: git diff main...브랜치 · 테스트 · PR 읽기