개요
작업 중 잘못 수정한 파일을 이전 상태로 되돌리거나, 스테이징을 취소하거나, 최근 커밋을 없었던 것처럼 만들고 싶을 때 **git reset**과 **git restore**를 사용할 수 있다. 이 글에서는 git reset의 세 가지 주요 모드(--soft, --mixed, --hard)가 작업 디렉터리(working tree), 인덱스(staging area), HEAD에 각각 어떤 영향을 주는지 정리하고, 특정 파일만 되돌리는 방법과 실무에서 자주 쓰는 시나리오를 다룬다.
대상 독자: Git을 일상적으로 쓰는 개발자, 커밋·스테이징을 실수했을 때 안전하게 롤백하고 싶은 사람.
git reset이 하는 일
git reset [--soft | --mixed | --hard] [<commit>]은 현재 브랜치의 HEAD를 지정한 커밋(기본값 HEAD)으로 옮기고, 옵션에 따라 인덱스와 작업 디렉터리까지 함께 맞춘다. 즉, “되돌리기"의 강도가 옵션마다 다르다.
| 옵션 | HEAD | 인덱스(스테이징) | 작업 디렉터리 |
|---|---|---|---|
--soft | 이동 | 변경 없음 | 변경 없음 |
--mixed (기본) | 이동 | 대상 커밋 기준으로 갱신 | 변경 없음 |
--hard | 이동 | 대상 커밋 기준으로 갱신 | 대상 커밋 기준으로 덮어씀 |
실행 전에 Git은 현재 HEAD를 ORIG_HEAD에 저장해 두므로, 필요하면 git reset --hard ORIG_HEAD로 되돌릴 수 있다.
reset 모드별 동작 (다이어그램)
아래 다이어그램은 working / index / HEAD가 각각 A, B, C 상태일 때, target 커밋(D)으로 git reset --option target을 실행한 뒤의 결과를 요약한 것이다. (공식 문서의 “DISCUSSION” 표를 기반으로 함.)
flowchart LR
subgraph StateBefore["실행 전"]
W1["working: A"]
I1["index: B"]
H1["HEAD: C"]
end
subgraph Soft["--soft target D"]
W2["working: A"]
I2["index: B"]
H2["HEAD: D"]
end
subgraph Mixed["--mixed target D"]
W3["working: A"]
I3["index: D"]
H3["HEAD: D"]
end
subgraph Hard["--hard target D"]
W4["working: D"]
I4["index: D"]
H4["HEAD: D"]
end
StateBefore --> Soft
StateBefore --> Mixed
StateBefore --> Hard
- –soft: HEAD만 D로 이동. 작업 디렉터리·인덱스는 그대로라, 직전 커밋 메시지 수정 후 다시 커밋하는 용도로 쓰기 좋다.
- –mixed: HEAD와 인덱스를 D로 맞추고, 작업 디렉터리 내용은 유지. 스테이징만 취소하고 싶을 때 유용하다.
- –hard: HEAD·인덱스·작업 디렉터리 모두 D로 덮어쓴다. 로컬에서만 쓰인 커밋/변경을 완전히 버릴 때만 사용하고, 이미 push한 히스토리에 대해서는 쓰지 않는 것이 안전하다.
전체 변경 사항 되돌리기 (작업 디렉터리 + 스테이징)
스테이징되지 않은 수정과 스테이징된 변경을 전부 마지막 커밋 상태로 버리고 싶을 때:
| |
또는 명시적으로:
| |
주의: 모든 로컬 수정이 사라지므로, 필요한 변경이 있다면 먼저
git stash로 감춰 두거나 브랜치를 만들어 두자.
특정 파일만 되돌리기
스테이징만 취소하고 작업 디렉터리 내용은 유지하려면 (Git 2.23 이상 권장):
| |
예: src/hello.c만 스테이징에서 빼기
| |
작업 디렉터리 파일 내용까지 마지막 커밋(또는 인덱스) 상태로 복원하려면:
| |
예: src/hello.c의 수정 내용을 버리고 복원
| |
같은 동작을 예전에는 git checkout -- src/hello.c로 많이 썼다. Git 2.23부터는 파일 복원은 git restore, 브랜치 전환은 git switch를 쓰는 것이 권장된다. git reset [<tree-ish>] -- <pathspec>은 “스테이징만 취소"와 동일하게 인덱스만 갱신하며, 작업 디렉터리 파일을 바꾸려면 git restore를 추가로 쓰면 된다.
시나리오별 사용 예
1. 방금 커밋을 취소하고 메시지나 내용만 고쳐서 다시 커밋
| |
-c ORIG_HEAD는 이전 커밋 메시지를 그대로 쓰고, -C는 수정 없이 재사용한다. 메시지만 고치려면 git commit --amend도 사용할 수 있다.
2. 스테이징만 취소 (작업 디렉터리는 그대로)
| |
특정 파일만 스테이징 취소:
| |
3. 로컬에서만 쓴 최근 N개 커밋 완전히 제거
| |
HEAD~3은 “현재 HEAD에서 3개 이전 커밋"을 가리킨다. 이미 push한 커밋에 대해서는 git reset --hard 대신 git revert를 사용하는 것이 원격 히스토리와 협업 관점에서 안전하다.
4. merge/pull 취소 (작업 디렉터리 변경은 유지)
merge 후 결과가 마음에 들지 않을 때, 로컬 수정은 남기고 merge만 취소:
| |
로컬 수정까지 모두 버리고 merge 전 상태로 돌아가려면:
| |
주의사항
- **
git reset --hard**는 지정한 커밋 이후의 작업 디렉터리·인덱스 변경을 복구할 수 없게 만든다. 반드시 로컬에서만 쓰인 변경에만 사용하자. - 이미 push한 커밋을 되돌리려면
git reset보다 **git revert**로 역커밋을 만드는 방식이 일반적이다. 팀원과 공유한 브랜치에서는reset --hard후 force-push는 피하는 것이 좋다. - 실수 후 복구가 필요하면
git reflog로 이전 HEAD 위치를 찾고, 그 커밋으로git reset --hard <commit>할 수 있다.
참고 문헌
git-reset - Git 공식 문서
--soft/--mixed/--hard/--merge/--keep설명과 working/index/HEAD 변화 표가 정리되어 있다.git-restore - Git 공식 문서
작업 디렉터리·인덱스 복원,--staged/--source사용법과 예제.Reset, restore and revert - Git 공식 가이드
reset, restore, revert의 역할 차이 요약.
![Featured image of post [Git] git reset 사용법과 restore로 파일 되돌리기](/post/2021-04-07-git-reset/wordcloud_hu_eda4d5f6dd18f988.webp)
![[Plex] Windows에서 Plex Media Server 재실행·자동 재시작 가이드](/post/2023-01-13-restart-plex-media-server/wordcloud_hu_ba5ac3c6f7684b1d.webp)
![[Tutorial] Learn Prompting - 프롬프트 엔지니어링 무료 가이드 정리](/post/2022-12-30-learn-prompting/wordcloud_hu_6a9d105de4834753.webp)
![[RPM] Spec 파일에서 주석과 매크로 동시 사용 시 주의사항](/post/2021-11-24-rpm-spec-comments/wordcloud_hu_6d09ac09623081c7.webp)
![[How-To] Windows 10 다중 사용자 카카오톡 실행 권한 부여](/post/2021-04-07-window10-multiuser-kakaotalk/wordcloud_hu_5fcf6a8683d09a52.webp)
![[Hardware] LattePanda Alpha에 Ubuntu 16.04 LTS 설치 가이드](/post/2018-12-06-install-ubuntu-16.04-on-lattepanda/wordcloud_hu_fc536f8de2cbd4bf.webp)