어제 오늘 내일

[Git] 이미 커밋한 걸 취소하고 싶다면? Reset vs Revert 완벽 정리 본문

IT/Git

[Git] 이미 커밋한 걸 취소하고 싶다면? Reset vs Revert 완벽 정리

hi.anna 2026. 2. 4. 00:52

"아차, 비밀번호를 적은 채로 커밋했네?"

"오늘 짠 코드 3개는 전부 엉망이야, 아침 상태로 돌아갈래!"

개발을 하다 보면 과거로 돌아가야 하는 순간이 반드시 옵니다.

Git에는 시간을 다루는 두 가지 마법, Reset(기록 삭제)Revert(취소 기록 생성)가 있습니다.

이 둘을 상황에 맞춰 골라 쓰는 법을 마스터해 봅시다.

 

1. 시간을 아예 삭제하는 git reset

Reset은 말 그대로 시계를 특정 시점으로 되돌리는 것입니다. 돌아간 시점 이후의 모든 기록은 삭제됩니다.

특장

  • 특징: 히스토리가 깔끔해집니다.
  • 사용처: 나 혼자 작업하는 로컬 브랜치 (아직 GitHub에 Push 하기 전).
  • 주의: --hard 옵션은 작성 중인 코드까지 모조리 지워버리므로 신중해야 합니다.

✅ 상황별 옵션 (매우 중요)

  • --soft: 커밋만 취소하고 코드는 그대로 둡니다. (다시 add된 상태)
  • --mixed: 커밋과 스테이징을 취소합니다. 코드는 남지만 다시 add해야 합니다. (기본값)
  • --hard: 주의! 커밋부터 수정된 코드까지 아예 깨끗이 지우고 그 시점으로 돌아갑니다.

 

[Case 1] "바로 직전의 커밋 1개만 지우고 싶어요!"

상황: 방금 feat: 로그인 기능을 커밋했는데, 치명적인 오타가 발견되어 삭제하고 싶습니다.

1. 현재 상태 확인 (git log)

$ git log --oneline
a1b2c3d (HEAD -> main) feat: 로그인 기능 (❌ 지우고 싶은 커밋)
z9y8x7w docs: README 수정 (✅ 돌아가고 싶은 지점)

2. Reset 실행 (1단계 뒤로)

# HEAD~1은 '현재로부터 1단계 전'을 의미합니다.
$ git reset --hard HEAD~1
HEAD is now at z9y8x7w docs: README 수정

3. 결과 확인
feat: 로그인 기능 커밋이 흔적도 없이 사라졌습니다.

 

[Case 2] "여러 단계(3개) 전으로 한 번에 돌아가고 싶어요!"

상황: 오늘 오전에 작업한 커밋 3개가 전부 마음에 안 들어서,

어제 퇴근하던 시점(init: 프로젝트 시작)으로 통째로 리셋하고 싶습니다.

1. 현재 상태 확인

$ git log --oneline
d4d4d4d (HEAD -> main) feat: 결제 기능 (❌ 삭제)
c3c3c3c feat: 장바구니 기능 (❌ 삭제)
b2b2b2b feat: 상품 목록 기능 (❌ 삭제)
a1a1a1a init: 프로젝트 시작 (✅ 여기로 점프!)

2. Reset 실행 (방법은 두 가지)

  • 방법 A: 상대 경로 사용 (추천)
# 3단계 전으로 이동
$ git reset --hard HEAD~3

 

  • 방법 B: 해시값 직접 사용 (확실함)
# 돌아가고 싶은 커밋의 ID(a1a1a1a)를 직접 입력
$ git reset --hard a1a1a1a

3. 결과 확인

$ git log --oneline
a1a1a1a (HEAD -> main) init: 프로젝트 시작
# 이후의 3개 커밋은 모두 삭제되었습니다.

 

 

 

 

2. 취소했다는 기록을 남기는 git revert

Revert는 과거의 기록을 지우지 않습니다. 대신 "과거의 작업을 반대로 수행(취소)하는 새로운 커밋"을 하나 더 만듭니다.

  • 특징: 히스토리가 지워지지 않고 계속 쌓입니다. (안전함)
  • 사용처: 이미 GitHub(원격 저장소)에 Push 해서 팀원들과 공유 중인 경우.

 

[Case 1] "이미 서버에 올린 특정 커밋 하나만 취소할래!"

상황: 며칠 전에 올린 bugfix: 폰트 수정 커밋이 오히려 디자인을 망치고 있어서 취소해야 합니다.

(바로 직전 커밋이 아니어도 가능합니다.)

 

1. 현재 상태 확인

$ git log --oneline
f9e8d7c (HEAD -> main) feat: 회원가입 완성
c3d4e5f bugfix: 폰트 수정 (❌ 이것만 콕 집어서 취소하고 싶음)
a1b2c3d docs: 문서 작업

2. Revert 실행
취소하고 싶은 커밋의 해시값(c3d4e5f)을 입력합니다.

$ git revert c3d4e5f
# (커밋 메시지 에디터가 뜨면 저장 후 종료)
[main g1h2i3j] Revert "bugfix: 폰트 수정"

3. 결과 확인

$ git log --oneline
g1h2i3j (HEAD -> main) Revert "bugfix: 폰트 수정"  <-- ✅ 취소 기록 추가됨
f9e8d7c feat: 회원가입 완성
c3d4e5f bugfix: 폰트 수정 (원본은 그대로 남음)

[Case 2] "여러 단계의 커밋을 순서대로 취소하고 싶어요!"

상황: 최근에 작업한 커밋 3개를 서버에 이미 올렸는데, 이 3개를 전부 취소하고 싶습니다. (Reset을 쓰면 동료들 코드가 꼬이므로 Revert를 써야 합니다.)

명령어: 범위(..)를 지정해서 한 번에 수행할 수 있습니다.

# 가장 최근(HEAD)부터 3번째 전(HEAD~3)까지의 범위를 역순으로 Revert
# (주의: 범위 지정 시 시작점은 포함되지 않음)
$ git revert --no-commit HEAD~3..HEAD
$ git commit -m "최근 3개의 작업 일괄 취소"
  • --no-commit: 커밋을 하나하나 만들지 않고, 3개의 취소 작업을 한 번에 묶어서 하나의 커밋으로 만듭니다.

 

3. 결정적 차이 요약 (Cheat Sheet)

구분 git reset git revert
핵심 동작 과거로 이동 + 이후 기록 삭제 내용을 반대로 뒤집는 새 커밋 생성
코드 상태 과거 상태로 돌아감 과거 상태로 돌아감
히스토리 짧아짐 (삭제됨) 길어짐 (추가됨)
언제 쓰나요? 나 혼자 볼 때 (Push 전) 팀과 공유할 때 (Push 후)

 

 

💡 절대 어기면 안 되는 규칙

"이미 GitHub에 Push 한 커밋은 절대 Reset 하지 마세요!"

 

내가 reset으로 과거를 지워버리면, 그 코드를 바탕으로 작업하던 동료들의 저장소와 충돌이 발생해 "헬게이트(Hell-Gate)"가 열립니다.

공유된 코드는 무조건 Revert입니다.

 

 

 

반응형
Comments