| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- json
- 자바스크립트
- 이클립스
- java테스트
- IntelliJ
- 자바문법
- ArrayList
- 테스트자동화
- 정규식
- list
- string
- 단위테스트
- javascript
- input
- 자바
- js
- Eclipse
- 배열
- vscode
- junit
- CSS
- 문자열
- 인텔리제이
- junit5
- Visual Studio Code
- math
- Java
- Array
- HashMap
- html
- Today
- Total
어제 오늘 내일
[Git] 이미 커밋한 걸 취소하고 싶다면? Reset vs Revert 완벽 정리 본문
"아차, 비밀번호를 적은 채로 커밋했네?"
"오늘 짠 코드 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입니다.
'IT > Git' 카테고리의 다른 글
| [Git] 과거를 추적하는 법: git log로 커밋 기록 조회하고 검색하기 (0) | 2026.02.03 |
|---|---|
| [Git] 작업 합치기: Merge와 공포의 Conflict 해결법 (0) | 2026.02.03 |
| [Git] 현재 브랜치 확인하기 (0) | 2026.02.02 |
| [Git] 협업의 핵심, Branch 완벽 이해하기 (0) | 2026.02.02 |
| [Git] 내 소중한 코드 백업하기: GitHub 연결과 Push (0) | 2026.02.01 |
