콘텐츠로 이동

2장: 실수했을 때 되돌리기 - git restore, reset, revert

도입: "아, 망했다!"

코드를 작성하다 보면 실수는 반드시 일어납니다. 중요한 건 어떻게 되돌리느냐입니다. Git은 이걸 위해 여러 가지 방법을 제공합니다.

상황별 대처법

상황 1: 아직 add 안 했는데 파일을 수정해버렸다

# 수정 전으로 되돌리기
git restore hello.py

# 또는 예전 방식 (아직도 많이 쓰임)
git checkout -- hello.py

주의: 이 명령어는 되돌리면 수정한 내용이 완전히 사라집니다. 진짜 복구 불가능합니다.

상황 2: add는 했는데 commit은 아직 안 했다

# 스테이징 영역에서만 빼기 (파일 수정 내용은 유지)
git restore --staged hello.py

# 또는 예전 방식
git reset HEAD hello.py

git status로 확인하면 다시 "Untracked" 또는 "modified" 상태로 돌아와 있습니다.

상황 3: 커밋을 했는데, 바로 전 커밋에 뭔가 빠뜨렸다

# 파일 수정 후
git add .
git commit --amend -m "수정된 커밋 메시지"

--amend가장 최근 커밋 하나를 수정하는 명령어입니다. 커밋 메시지를 고치거나, 빠뜨린 파일을 추가할 때 씁니다.

중요: 이미 GitHub에 올린(push 한) 커밋에는 절대 --amend 쓰지 마세요!

상황 4: 몇 커밋 전으로 완전히 되돌리고 싶다

방법 A: git reset (히스토리를 지우는 방식)

# 커밋 히스토리 확인
git log --oneline
# a1b2c3d 세 번째 커밋
# e4f5g6h 두 번째 커밋
# i7j8k9l 첫 번째 커밋

# 두 번째 커밋으로 되돌리기 (수정 내용은 스테이징 영역에 유지)
git reset --soft e4f5g6h

# 두 번째 커밋으로 되돌리기 (수정 내용은 작업 디렉토리에 유지)
git reset --mixed e4f5g6h

# 두 번째 커밋으로 되돌리기 (수정 내용 완전 삭제!! 주의!!)
git reset --hard e4f5g6h
옵션 커밋 히스토리 스테이징 영역 작업 디렉토리
--soft 삭제 유지 유지
--mixed (기본값) 삭제 삭제 유지
--hard 삭제 삭제 삭제

초보자 추천: --soft를 쓰는 습관을 들이세요. 안전합니다.

방법 B: git revert (히스토리를 유지하는 방식)

# 특정 커밋을 취소하는 "새로운 커밋"을 만든다
git revert a1b2c3d

reset과의 차이점: - reset: 커밋 히스토리를 삭제 (마치 없었던 일처럼) - revert: 취소하는 새 커밋을 추가 (히스토리에 기록이 남음)

reset:  A → B → C  ⟹  A → B        (C가 사라짐)
revert: A → B → C  ⟹  A → B → C → C'  (C를 취소하는 C'가 추가됨)

언 revert를 쓰나요? 이미 GitHub에 올린(push 한) 커밋을 되돌릴 때. 협업할 때 다른 사람의 히스토리를 망가뜨리면 안 되니까요.

상황 5: "아, 방금 지운 커밋 다시 살리고 싶어"

# 내가 한 모든 행동 기록 보기
git reflog

# 특정 시점으로 돌아가기
git reset --hard a1b2c3d

git reflog는 Git의 "타임머신"입니다. reset --hard로 지운 커밋도 reflog에 남아 있으면 복구할 수 있습니다. 단, 보관 기간은 약 90일입니다.

핵심 정리

수정만 했음       → git restore <파일>
add만 했음        → git restore --staged <파일>
방금 커밋했음     → git commit --amend
과거로 돌아가고 싶음 → git reset (로컬) / git revert (공유)
다 잃어버린 것 같음 → git reflog

실습 미션

  1. 1장에서 만든 practice 저장소로 이동하세요
  2. oops.py 파일을 만들고 커밋하세요
  3. oops.py를 수정한 후 git restore로 되돌려 보세요
  4. oops.py를 다시 수정하고 git addgit restore --staged로 스테이징을 취소해 보세요
  5. 실수 커밋을 하나 만들고 git reset --soft로 되돌려 보세요
  6. git reflog로 방금 한 행동들이 기록되어 있는지 확인하세요

이전 장: 01-git-basics.md 다음 장: 03-git-branch.md - 브랜치로 평행 우주 만들기