Quick Comparison
# 로컬에서 아직 정리 중이면
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 # ref/index/worktree를 target에 맞춤 (uncommitted overwrite 주의)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는 작업 트리의 uncommitted 수정·untracked 파일의 overwrite를 Git history에서 복구해 주지 않으므로 특히 주의하세요.
공유 브랜치에서는 항상 git revert를 먼저 고려하고, reset은 자신만 사용하는 로컬
브랜치 정리에 한정하는 것이 안전합니다.
git reset --hard HEAD~1
git push --force
# 이미 origin/main을 pull한 협업자는
# 로컬 히스토리와 원격 히스토리가 어긋나 추가 복구 작업이 필요해짐참고 링크
2 sources