본문으로 건너뛰기
개발 머꼬
개발 노트Git
hohyeon.dev27

git reset --hard를 습관적으로 썼다가 작업 내용을 통째로 잃은 이유

  • #Common Pitfall
  • #Engineering Note
  • #Git

문제 발생

마지막 커밋을 취소하려고 git reset --hard HEAD~1을 실행했는데, 그 커밋 이후 아직 커밋하지 않은 작업 내용까지 전부 사라졌습니다.

원인 분석

git reset은 Git의 세 가지 영역(커밋 히스토리 = HEAD가 가리키는 위치, 스테이징 영역 = index, 작업 디렉터리 = 실제 파일) 중 어디까지 되돌릴지를 옵션으로 정합니다.

  • --soft: HEAD(브랜치가 가리키는 커밋)만 되돌립니다. 스테이징 영역과 작업 디렉터리는 건드리지 않습니다 — 즉 되돌린 커밋의 변경사항이 스테이징된 상태(git add된 상태)로 그대로 남습니다. 커밋 메시지만 다시 쓰거나 여러 커밋을 하나로 합치고 싶을 때 유용합니다.
  • --mixed(기본값, 옵션 생략 시): HEAD와 스테이징 영역을 되돌립니다. 작업 디렉터리(실제 파일 내용)는 그대로 둡니다 — 되돌린 커밋의 변경사항이 스테이징 안 된(unstaged) 상태로 남습니다.
  • --hard: HEAD, 스테이징 영역, 작업 디렉터리까지 전부 되돌립니다 — 그 커밋의 변경사항이 파일 시스템에서 완전히 사라집니다. 이게 위 사고의 원인입니다 — HEAD~1로 되돌아가면서, 그 시점 이후의 모든 변경(아직 커밋 안 한 것 포함)이 파일 자체에서 삭제됩니다.

해결 방안

  1. --hard는 항상 신중하게 씁니다 — 작업 디렉터리의 실제 파일을 되돌리는 유일한 옵션이고, 이건 곧 커밋되지 않은 변경사항은 복구할 표준적인 방법이 없다는 뜻입니다(Git이 아예 추적한 적 없는 내용이므로 reflog로도 못 찾습니다).
  2. 단순히 마지막 커밋을 취소하고 싶을 뿐이라면 --mixed(기본값) 또는 --soft로 충분한 경우가 대부분입니다 — 변경사항은 남기고 커밋 상태만 되돌리는 것이 더 안전한 기본 선택입니다.
  3. 실행 전에 git status로 현재 뭐가 커밋 안 된 상태인지 확인하는 습관이 중요합니다 — --hard를 실행하기 전에 이 상태가 사라져도 되는지 항상 되짚습니다.
  4. 만약 되돌리려는 게 이미 커밋된 상태라면(즉 reset --hard 이후에도 그 커밋 자체는 존재했다면), git reflog로 그 커밋의 해시를 찾아 git reset --hard <해시>git cherry-pick <해시>로 복구할 수 있습니다 — 이건 어디까지나 "커밋된 것"에만 해당하고, 애초에 커밋한 적 없는 변경사항에는 적용되지 않습니다.
  5. 정말로 다른 사람과 상태를 맞추기 위해 로컬 변경을 통째로 버려야 하는 상황이 아니라면, git reset보다 git revert(기존 히스토리를 유지하면서 그 변경을 취소하는 새 커밋을 추가)가 공유 브랜치에서는 더 안전한 선택인 경우가 많습니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.