AI가 짠 코드에 영혼을 털리지 않는 법: 시니어가 전수하는 Git 생존 실전

🚀 AI가 짠 코드에 영혼을 털리지 않는 법: 시니어가 전수하는 Git 생존 실전
(아래 글은 시니어 개발자 페르소나로 설정하여 gemini에서 생성한 글입니다. )
서론: 우리는 '작성자'가 아니라 '편집장'이다
주니어 시절, git commit은 숙제 제출 버튼과 같았습니다. 하지만 AI가 초당 100줄의 코드를 쏟아내는 지금, Git은 '쓰레기 코드를 걸러내는 정수기'이자 '시간을 되돌리는 타임머신'이어야 합니다.
여러분의 AI(이하 'AI 사수')는 멍청하고 빠릅니다. 가끔 천재적이지만, 가끔은 멀쩡한 코드를 폭파시킵니다. 금요일 오후 5시, 쇼핑몰 결제 버튼이 작동하지 않는다는 버그 리포트가 들어온 상황을 가정해 봅시다. 김신입 사원과 AI 사수의 좌충우돌 디버깅 현장으로 들어갑니다.
🎬 상황: 금요일 오후 5시, "결제 버튼이 안 눌려요!"
미션: CheckoutButton.js의 클릭 이벤트를 수정하고 배포하라.
도구: Cursor (AI 에디터), Git, 그리고 식은땀.
Phase 1. 검증(Verification): AI의 과잉 친절 걸러내기
김신입은 AI에게 프롬프트를 날립니다. "결제 버튼 클릭 시 중복 요청 막는 로직 추가해줘."
AI는 3초 만에 코드를 수정합니다. 김신입은 습관적으로 git add .를 치려다가, 제 목소리("멈춰!")를 떠올립니다.
1. git add -p (AI야, 이 부분은 빼고 가자)
AI가 작성한 코드를 보니, 결제 로직은 잘 짰는데 뜬금없이 "코드 스타일이 마음에 안 든다"며 파일 전체의 들여쓰기(Indent)를 2칸에서 4칸으로 바꿔버렸습니다. 이걸 그대로 올리면 팀장님께 등짝 스매싱을 맞습니다.
Bash
$ git add -p src/components/CheckoutButton.js터미널이 묻습니다.
"Hunk 1: 결제 중복 방지 로직 (Is this change okay?)" -> y (Yes)
"Hunk 2: 파일 전체 공백 수정 (Is this change okay?)" -> n (No)
김신입은 AI가 친 '사고'를 n을 눌러 가볍게 무시하고, 필요한 로직만 스테이징합니다.
2. git diff --check (보이지 않는 암살자 제거)
로직은 완벽해 보입니다. 하지만 AI는 가끔 인간의 눈에 보이지 않는 'Trailing Whitespace(줄 끝 공백)'를 남깁니다.
Bash
$ git diff --check
> src/components/CheckoutButton.js:45: trailing whitespace.역시나 있군요. 이게 있으면 나중에 코드 리뷰 툴에서 빨간 줄이 쫙 그어집니다. 김신입은 에디터 설정을 통해 이를 수정하고 넘어갑니다.
3. git clean -fd (청소는 배포의 기본)
git status를 쳐보니 AI가 테스트하느라 만든 test_payment_dummy.json, debug.log 파일이 널브러져 있습니다.
Bash
$ git clean -fd
> Removing debug.log
> Removing test_payment_dummy.json깔끔하게 추적되지 않는(Untracked) 파일들을 날려버립니다. 이제 커밋할 준비가 되었습니다.
Phase 2. 안전망(Safety Net): 앗, API 키를 올렸다!
마음이 급해진 김신입. git add . 후 git commit -m "fix"를 날렸습니다. 그런데 아차, 로컬 테스트용으로 만든 .env 파일(AWS 비밀키 포함)이 같이 커밋됐습니다. 3초 뒤 깃허브 보안 봇이 경고 메일을 보낼 기세입니다.
4. git reset --soft HEAD~1 (시간을 1분 전으로)
커밋을 취소해야 합니다. 하지만 작성한 코드는 날리면 안 됩니다.
Bash
$ git reset --soft HEAD~1이 마법의 주문을 외우면, 방금 한 커밋은 취소되지만 수정한 파일들은 스테이징 상태(Staged)로 그대로 남습니다. 김신입은 안도의 한숨을 쉬며 .env 파일을 스테이징에서 뺍니다.
5. git restore --staged .env (너는 여기 끼면 안 돼)
비밀 파일만 콕 집어서 스테이징 무대에서 내려보냅니다.
Bash
$ git restore --staged .env이제 다시 안전하게 커밋할 수 있습니다.
6. git reflog (신이시여, 저를 구하소서)
그런데 여기서 김신입이 큰 실수를 합니다. reset을 하다가 옵션을 헷갈려 git reset --hard를 쳐버린 겁니다.
"악! 아까 AI랑 1시간 동안 고친 코드가 다 날아갔어!"
터미널은 깨끗해졌고, 파일은 수정 전으로 돌아갔습니다. 김신입의 얼굴이 사색이 됩니다. 퇴사 각입니다.
하지만 시니어는 당황하지 않습니다.
Bash
$ git reflog
> a1b2c3d HEAD@{0}: reset: moving to HEAD~1
> 9f8e7d6 HEAD@{1}: commit: fix payment button logic (방금 날린 커밋)Git은 당신이 버린 커밋도 기억합니다. 9f8e7d6이라는 해시값을 찾았습니다.
Bash
$ git reset --hard 9f8e7d6좀비처럼 코드가 되살아납니다. 김신입은 Git을 숭배하게 됩니다.
Phase 3. 기록(Documentation): 흔적 지우기
급하게 고치느라 커밋 로그가 지저분합니다.
fix: button logicfix: typochore: remove console.logfix: really final fix
이대로 PR(Pull Request)을 올리면 "커밋 정리 좀 하세요"라는 코멘트를 받을 게 뻔합니다.
7. git rebase -i HEAD~4 (역사 조작단)
최근 4개의 커밋을 하나로 합칩니다.
Bash
$ git rebase -i HEAD~4에디터가 열리면 첫 번째 커밋은 pick, 나머지는 s (squash)로 바꿉니다.
이제 4개의 자잘한 커밋이 "fix: resolve payment button overlap issue"라는 하나의 우아한 커밋으로 재탄생합니다.
8. git stash (잠깐만, 기획자가 불렀어)
한창 리팩토링 중인데 기획자가 달려옵니다. "지금 당장 메인 배너 문구만 바꿔주세요!"
작업하던 파일이 섞이면 안 됩니다.
Bash
$ git stash작업하던 코드를 임시 주머니(Stash)에 넣고, 워킹 트리를 깨끗하게 만듭니다. 배너 문구를 수정하고 커밋한 뒤, 다시 꺼냅니다.
Bash
$ git stash pop완벽한 문맥 전환(Context Switching)입니다.
Phase 4. 디버깅(Debugging): 범인은 이 안에 있다
배포가 끝났습니다. 그런데 월요일 아침, "장바구니 기능이 안 된다"는 연락이 옵니다. 금요일에 건드린 건 결제 버튼뿐인데 왜 장바구니가 터졌을까요? 지난 일주일간 쌓인 커밋은 100개. 도대체 어디서부터 잘못된 걸까요?
9. git bisect (이진 탐색 탐정)
100개의 커밋을 하나하나 확인할 순 없습니다. Git에게 범인을 찾게 시킵니다.
Bash
$ git bisect start
$ git bisect bad # 지금 상태가 버그가 있음
$ git bisect good <일주일_전_해시> # 이때는 잘 됐음Git은 딱 중간 지점의 커밋으로 이동합니다.
"지금은 돼요?" -> 테스트해보니 됩니다.
Bash
$ git bisect good그럼 범인은 후반부 50개 중에 있습니다. Git은 다시 그 중간으로 이동합니다.
이렇게 몇 번만 반복하면, 수학적으로 $O(log n)$의 속도로 범인 커밋을 찾아냅니다.
범인은... "feat: AI optimized rendering speed" 커밋이었습니다. AI가 렌더링 속도를 높인답시고 장바구니 로직을 건너뛰게 만들었군요.
10. git blame (실명제)
누가 이 코드를 승인했습니까?
Bash
$ git blame src/utils/rendering.js라인 옆에 이름이 뜹니다. Antigravity (3 days ago).
...네, 범인은 저였군요. (AI가 짠 코드를 대충 리뷰하고 넘긴 제 탓입니다.)
🎁 보너스: 생산성 2배 업! .gitconfig Alias 설정
위의 시나리오를 겪고 나면, 매번 긴 명령어를 치는 게 고역일 겁니다.
아래 설정을 여러분의 홈 디렉토리 .gitconfig 파일에 붙여넣으세요. 이제 여러분의 손가락은 날개를 답니다.
Ini, TOML
# ~/.gitconfig 파일을 열어서 [alias] 섹션에 추가하세요.
[alias]
# 1. 상태 확인 및 로그 (가장 많이 씀)
s = status -s # 짧고 굵게 상태 확인
lg = log --oneline --graph --all --decorate # 지하철 노선도처럼 로그 보기
# 2. 작업 및 검증 (AI 코드 검수용)
ap = add -p # 조각내서 스테이징 (필수!)
dc = diff --cached # 스테이징된 내용 확인 (커밋 직전 리허설)
d = diff # 작업 중인 내용 확인
# 3. 커밋 및 수정 (실수 방지)
c = commit -m # 커밋 메시지 작성
ca = commit --amend # 방금 전 커밋 수정 (메시지나 파일 추가)
can = commit --amend --no-edit # 방금 전 커밋 수정 (메시지는 그대로, 파일만 덮어쓰기)
# 4. 안전망 및 복구
rh = reset --hard # 주의! 강제 초기화
rs = reset --soft # 커밋만 취소, 파일은 살림 (가장 유용)
re = restore # 작업 취소
res = restore --staged # 스테이징 취소
# 5. 브랜치 및 동기화
co = checkout
sw = switch
br = branch
st = stash
stp = stash pop
p = push
pf = push --force-with-lease # 그냥 force보다 안전한 강제 푸시
# 6. 고급 기능
sq = rebase -i # 스쿼시(Squash) 하러 가기
who = blame # 범인 찾기적용 후 변화된 삶
Before:
git add -p(타닥타닥) ->git commit -m "fix bug"(타닥타닥)After:
git ap(탁) ->y,n,y->git c "fix bug"(탁)
마치며: 도구는 거들 뿐, 본질은 '판단'
AI는 엄청난 속도로 코드를 생산합니다. 그 속도에 휘둘리지 않으려면 브레이크(git add -p)와 핸들(git rebase), 그리고 내비게이션(git bisect)을 능숙하게 다뤄야 합니다.
오늘 소개한 명령어들이 여러분을 단순한 '코더(Coder)'에서 코드의 역사를 책임지는 '엔지니어(Engineer)'로 만들어 줄 것입니다.
지금 바로 터미널을 열고 git ap를 입력해보세요. 그게 바로 시니어의 '바이브'입니다. 🚀
