빠른 비교
# 로컬에서 아직 정리 중이면
git reset --soft HEAD~1
# 이미 공유된 커밋을 취소하려면
git revert <commit>갈리는 기준
어떤 되돌리기 방법을 먼저 떠올리면 되나
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 로컬 커밋만 다시 정리 | git reset --soft 또는 --mixed |
| 작업 트리까지 완전히 폐기 | git reset --hard |
| 이미 공유된 커밋 취소 | git revert <commit> |
| 취소 커밋을 바로 만들지 않고 먼저 모아 보기 | git revert --no-commit |
| 불가피한 강제 푸시 최소 안전망 | git push --force-with-lease |
reset은 브랜치 포인터를 과거로 이동시켜 히스토리를 다시 쓴다
git reset은 현재 브랜치 ref가 가리키는 commit SHA를 변경합니다. 즉, 브랜치 포인터 자체를 과거 commit으로 옮기는 것이며 이후 커밋들은 히스토리에서 제거됩니다. 이 작업은 세 가지 모드로 동작이 달라집니다. --soft는 작업 트리와 인덱스를 그대로 두고 포인터만 옮겨 "커밋만 취소"하는 효과입니다. --mixed(기본값)는 인덱스까지 초기화해 변경이 스테이징 해제 상태로 돌아옵니다. --hard는 작업 트리까지 모두 되돌려 파일 자체가 바뀝니다.
git reset --soft HEAD~1 # 커밋만 취소, 변경은 staged 상태로 남음
git reset --mixed HEAD~1 # 커밋 취소 + unstage, 변경은 작업 트리에 남음
git reset --hard HEAD~1 # 커밋 취소 + 작업 트리까지 완전 되돌림 (복구 불가)reset --soft, --mixed, revert는 되돌리는 대상이 다르다
마지막 커밋 메시지를 다시 쓰거나 커밋을 쪼개려면 --soft가 맞습니다. 변경은 남기되 다시 add부터 고르고 싶다면 --mixed가 맞습니다. 이미 팀과 공유된 커밋을 취소해야 한다면 revert가 맞습니다. 되돌리는 대상이 "브랜치 포인터인지", "스테이징 상태인지", "히스토리 의미인지"를 먼저 구분하면 헷갈림이 줄어듭니다.
git reset --soft HEAD~1 # commit만 취소, staged 유지
git reset --mixed HEAD~1 # commit 취소, staged 해제
git revert HEAD # 새 취소 commit 추가revert는 되돌리는 행위 자체를 새 커밋으로 기록해 히스토리를 보존한다
git revert는 대상 commit이 만든 변경의 역변환(diff를 뒤집은 것)을 새 commit으로 추가합니다. 기존 커밋은 히스토리에 그대로 남고, 취소 의도를 기록하는 commit이 하나 더 쌓입니다. 이 방식의 핵심 장점은 이미 공유된 브랜치에 안전하게 적용할 수 있다는 점입니다. 원격에 push한 커밋을 reset 후 강제 push하면 다른 협업자의 히스토리가 꼬이지만, revert는 새 커밋을 추가할 뿐이므로 일반 push로 처리됩니다.
git revert a1b2c3d # 해당 커밋의 변경을 되돌리는 새 커밋 생성
git revert HEAD~2..HEAD # 최근 2개 커밋을 순서대로 되돌림
git revert --no-commit a1b2c3d # 커밋 없이 되돌린 변경만 스테이징공유 브랜치에서 reset 후 강제 push는 협업자의 히스토리를 파괴한다
reset이 위험한 이유는 히스토리를 "다시 쓰기" 때문입니다. 이미 원격에 push한 커밋을 reset으로 제거한 뒤 git push --force하면, 다른 팀원이 이미 pull한 커밋들이 원격에서 사라집니다. 다음번 pull 시 충돌이 생기거나 협업자의 작업이 lost commit이 됩니다. --force-with-lease를 쓰면 원격에 자신이 모르는 커밋이 있을 경우 push를 거부해 최소한의 안전망을 제공하지만, 근본적으로 공유 브랜치의 히스토리 재작성은 팀 합의 없이는 피해야 합니다.
# 혼자만 쓰는 로컬 브랜치: reset 자유롭게 가능
git reset --soft HEAD~3
# 공유 브랜치: revert로 안전하게 취소
git revert a1b2c3d
# 불가피하게 강제 push가 필요할 때 최소 안전망
git push --force-with-lease선택 기준
| 상황 | 적합한 선택 |
|---|---|
| 로컬에서만 쓰는 브랜치, 마지막 커밋 재작성 | git reset --soft HEAD~1 |
| 작업 트리까지 완전히 되돌리고 싶을 때 | git reset --hard HEAD~1 |
| 공유 브랜치에서 특정 커밋 효과 취소 | git revert <commit> |
| 취소 이력을 명시적으로 남겨야 할 때 | git revert (새 커밋 생성) |
| 불가피한 강제 push 시 협업자 보호 | git push --force-with-lease |
주의할 점
이미 다른 사람이 pull한 브랜치에서 git reset 후 강제 push하면 협업자의 히스토리가
파괴됩니다. --hard 옵션은 작업 트리까지 되돌려 복구가 불가능하므로 특히 주의하세요.
공유 브랜치에서는 항상 git revert를 먼저 고려하고, reset은 자신만 사용하는 로컬
브랜치 정리에 한정하는 것이 안전합니다.
git reset --hard HEAD~1
git push --force
# 이미 origin/main을 pull한 협업자는
# 로컬 히스토리와 원격 히스토리가 어긋나 추가 복구 작업이 필요해짐참고 링크
2 sources