[Git 명령어] git reset와 git revert 차이 바로 알기
Git reset vs revert 이해하기
둘 다 “되돌린다”는 뜻이지만, 실제로는 역할과 쓰임새가 완전히 다른 git reset과 git revert. 히스토리와 협업 관점에서 어떤 차이가 있는지 쉽고 자세하게 정리해봅니다.
한 줄로 요약하면 이렇게 말할 수 있습니다:
reset = “시간을 되감아서 히스토리를 고쳐 쓰기”
revert = “과거 잘못된 커밋을 반대로 뒤집는 새 커밋 만들기”
둘 다 “되돌린다”는 점은 같지만, 히스토리를 바꾸느냐 그대로 두느냐에서 엄청난 차이가 나고, 그래서 협업 중인 브랜치에서 써도 되는지 여부가 갈립니다. 아래에서 개념, 히스토리 변화, 협업 시 주의점까지 차근차근 살펴볼게요.
1. 개념 비교
🔁 git reset 이란?
- 브랜치(HEAD)가 가리키는 커밋 위치를 다른 커밋으로 옮기는 것
- “이 커밋까지만 있었던 걸로 치자” → 히스토리를 다시 쓰는 명령
--soft,--mixed,--hard옵션에 따라 스테이지/워킹 디렉토리까지 영향
비유하자면, 책의 마지막 챕터를 뜯어버리고
“원래 여기까지 밖에 안 썼어”라고 하는 느낌입니다.
🔄 git revert 란?
- 기존 커밋은 그대로 둔 채, 그 커밋을 무효화하는 ‘반대 내용’의 새 커밋 생성
- 과거 커밋 A가 있다면, A를 지우지 않고 A를 취소하는 B 커밋을 추가
이미 발행된 책에 “정정합니다” 페이지를 하나 더 넣는 것과 비슷합니다.
2. 히스토리 관점에서의 차이
✅ reset: 브랜치 히스토리 자체를 바꾼다
예를 들어 커밋 히스토리가 이렇게 있다고 해봅시다.
A - B - C - D (HEAD)
여기서 다음 명령을 실행하면:
git reset --hard B
브랜치 히스토리는 이렇게 됩니다.
A - B (HEAD)
- 브랜치가 더 이상 C, D를 가리키지 않기 때문에, C, D는 “없어진 것처럼” 보입니다.
- “이 브랜치의 공식 히스토리는 B까지”라고 다시 쓰는 셈입니다.
- 내부적으로 reflog로 복구할 수는 있지만, 일반적으로는 히스토리가 변경된 것입니다.
✅ revert: 히스토리를 유지한 채, 새로운 되돌림 커밋 추가
같은 상태에서, 이번에는 D 커밋을 되돌린다고 해볼게요.
git revert D
그러면 히스토리는 이렇게 됩니다.
A - B - C - D - E(= "Revert D") (HEAD)
- D 커밋은 여전히 남아 있고, D의 반대 변경을 담은 E 커밋이 추가됩니다.
- 최종 코드 상태는 “D를 안 한 것처럼” 되지만, 과정(히스토리)은 모두 보존됩니다.
3. 협업(원격 저장소)에서의 차이
🌐 reset – 공유 브랜치에서 조심해야 하는 이유
이미 원격 저장소에 push한 커밋들에 대해 다음과 같이 한다면:
git reset --hard B
git push -f
- 원격에 있던 C, D 커밋이 갑자기 사라져서, 다른 사람들의 로컬 히스토리와 원격 히스토리가 달라집니다.
- 동료가
git pull을 할 때 충돌/에러가 나거나, 강제로reset을 해야 할 수도 있습니다.
그래서 reset은 보통 이런 경우에만 사용합니다.
- 혼자 사용하는 브랜치에서 실험하다가 히스토리 정리할 때
- 아직 원격에 push하지 않은 커밋만 정리할 때
- 팀 합의 하에
push -f를 허용한 특수한 브랜치
🌐 revert – 협업에서 안전한 선택
이미 push까지 완료된 커밋을 되돌리고 싶다면, 보통 이렇게 합니다.
git revert <커밋해시>
git push
- 기존 히스토리는 그대로 두고, 되돌림 내용을 가진 새로운 커밋만 추가됩니다.
- 다른 사람들의 로컬 히스토리와 구조가 달라지지 않으므로, 협업 환경에서 매우 안전합니다.
그래서 공유 브랜치(main, develop 등)에서는 reset보다 revert가 사실상 표준이라고 생각해도 좋습니다.
4. 워킹 디렉토리/스테이지 관점에서의 차이
🔁 reset은 워킹 디렉토리와 스테이지까지 함께 조정
git reset은 단순히 HEAD만 옮기는 것이 아니라, 옵션에 따라 스테이지와 워킹 디렉토리 상태까지 같이 바꿉니다.
자주 쓰는 reset 옵션
git reset --soft HEAD~1
→ 마지막 커밋을 없애고, 그 변경을 스테이지에 그대로 유지git reset HEAD~1(기본 =--mixed)
→ 마지막 커밋을 없애고, 변경을 워킹 디렉토리에만 유지 (스테이지는 비움)git reset --hard HEAD~1
→ 마지막 커밋과 그 변경 사항을 워킹 디렉토리까지 포함해 완전히 제거
--hard 옵션git reset --hard는 커밋 + 스테이지 + 워킹 디렉토리의 변경을 모두 지웁니다.복구가 매우 까다로울 수 있으므로, 정말 필요할 때만 신중하게 사용하세요.
🔄 revert는 워킹 디렉토리를 거의 건드리지 않음
git revert는 보통 자동으로 되돌림 diff를 만들고, 바로 커밋까지 생성합니다.- 결과적으로는 “되돌림 커밋이 하나 더 생긴 깨끗한 상태”가 됩니다.
- 워킹 디렉토리는 대부분 변경 없이 그대로 유지됩니다.
5. 언제 reset, 언제 revert를 써야 할까?
✅ reset이 어울리는 상황
- 아직 push하지 않은 로컬 커밋을 정리할 때
- “방금 한 커밋을 없애고, 다시 예쁘게 커밋을 쌓고 싶다”
- 테스트용으로 만든 임시 커밋들을 한 번에 지우고 싶을 때
- 현재 작업 내용까지 완전히 버리고, 과거 상태로 돌아가고 싶을 때 (
--hard)
예시:
# 마지막 커밋만 지우고, 변경 내용은 그대로 유지
git reset HEAD~1
# 마지막 커밋과 변경 내용까지 완전히 제거
git reset --hard HEAD~1
✅ revert가 어울리는 상황
- 이미 원격에 push된 커밋을 되돌려야 할 때
- 여러 사람이 함께 사용하는 브랜치(main, develop 등)
- “언제 어떤 커밋을 되돌렸는지” 기록까지 남아야 하는 상황
예시:
# 직전 커밋 되돌리기
git revert HEAD
# 특정 커밋 되돌리기
git revert 1234abcd
6. 한눈에 보는 reset vs revert 비교
| 항목 | git reset | git revert |
|---|---|---|
| 히스토리 | 이전 커밋으로 되감아 히스토리를 다시 씀 | 되돌림 내용을 가진 새 커밋을 추가 |
| 기존 커밋 | 브랜치에서 “사라진 것처럼” 보임 | 그대로 남아 있고, 반대 커밋이 추가됨 |
| push 이후 사용 | 조심해야 함, 보통 지양 | 협업 환경에서 안전하고 권장 |
| 워킹 디렉토리/스테이지 | --soft/--mixed/--hard에 따라 큰 영향 |
대개 바로 커밋까지 되어 워킹 디렉토리는 거의 영향 없음 |
| 주요 사용 목적 | 로컬 히스토리 정리, 실수 커밋 삭제, 테스트 롤백 | 공유 브랜치에서의 롤백, 기록을 남기면서 되돌리기 |
7. 기억하기 쉽게 한 문장 정리
마지막으로, reset과 revert를 헷갈릴 때 떠올리기 좋은 문장을 하나씩 정리해볼게요.
- git reset:
“아까 했던 커밋? 없었던 걸로 치자.” → 히스토리를 고쳐 쓴다. - git revert:
“저때 한 실수는 이 커밋에서 정정합니다.” → 히스토리를 남긴 채 되돌린다.
혼자 쓰는 실험용 브랜치라면 reset으로 과감하게 정리해도 괜찮지만,
여러 사람이 함께 사용하는 main/develop 브랜치에서는 revert를 기본값으로 생각해 두면 안전하게 Git을 사용할 수 있습니다.