git 의 변경은 작업 트리, 스테이징, 저장소(커밋 히스토리) 세 공간을 거칩니다. 되돌릴 명령은 이 중 어디를 대상으로 하는지로 고릅니다.
| 되돌릴 위치 | 상황 | 명령 |
|---|---|---|
| 작업 트리 | 커밋 안 한 파일 수정을 취소 | git restore <file> |
| 스테이징 | add 한 것만 취소 | git restore --staged <file> |
| 저장소(개인 커밋) | 아직 공유 안 한 커밋 취소 | git reset |
| 저장소(공유 커밋) | 이미 push 한 커밋 취소 | git revert |
| 작업 상태 전체 | 하던 작업을 잠시 치워두기 | git stash |
git restore <file> 은 작업 트리의 파일만 스테이징(또는 HEAD) 상태로 되돌립니다. 스테이징이나 커밋 히스토리는 건드리지 않는 가장 안전한 되돌리기입니다.
git restore --staged <file> 은 git add 한 것만 취소합니다. 작업 트리의 수정 내용은 그대로 남아 다시 add 하거나 restore 로 버릴 수 있습니다.
git restore --source=HEAD~1 <file> 은 과거 커밋의 파일 내용을 지금 작업 트리로 가져옵니다. --staged 를 함께 쓰면 스테이징까지 그 시점 내용으로 바뀝니다.
reset 전: HEAD,main -> C3 --- 스테이징: C3 --- 작업 트리: C3
--soft HEAD,main -> C2 스테이징: C3(그대로) 작업 트리: C3(그대로)
--mixed HEAD,main -> C2 스테이징: C2로 초기화 작업 트리: C3(그대로)
--hard HEAD,main -> C2 스테이징: C2로 초기화 작업 트리: C2로 초기화| 모드 | HEAD | 스테이징 | 작업 트리 |
|---|---|---|---|
--soft |
이동 | 그대로(이전 커밋 diff 유지) | 그대로 |
--mixed(기본값) |
이동 | 대상 커밋으로 초기화 | 그대로 |
--hard |
이동 | 대상 커밋으로 초기화 | 대상 커밋으로 초기화 |
--soft 는 커밋만 합치고 수정 내용은 다시 커밋하고 싶을 때 씁니다. --mixed 는 스테이징만 풀고 파일은 그대로 두고 싶을 때, --hard 는 그 커밋 이후 모든 변경을 완전히 버릴 때 씁니다. --hard 는 작업 트리까지 지우므로 되돌릴 수 없는 명령입니다.
방금 만든 커밋의 메시지나 내용이 잘못됐을 때 가장 흔히 쓰는 형태입니다. git reset HEAD~1 (mixed 기본값)은 커밋만 취소하고 변경 내용은 스테이징에 남겨, 고쳐서 다시 커밋하기 좋습니다.
--amend 는 새 커밋을 만드는 대신 마지막 커밋을 교체합니다. 메시지만 고치려면 -m 을, 파일을 더 담으려면 add 뒤 --amend 만 붙입니다. amend 는 커밋 해시를 바꾸므로 push 하기 전에만 씁니다.
revert 는 과거 커밋을 지우지 않고, 그 변경을 반대로 적용하는 새 커밋을 만듭니다. 이미 다른 사람이 받아간 커밋을 취소할 때는 reset 대신 반드시 revert 를 씁니다. 병합 커밋을 되돌릴 때는 어느 부모를 기준으로 할지 -m 1(보통 main 쪽)로 지정해야 합니다.
git stash push -m "메시지" 는 추적 중인 파일의 변경을 저장하고 작업 트리를 깨끗하게 되돌립니다. 기본은 추적 파일만 담고, untracked 파일까지 담으려면 -u 를 붙입니다.
| 명령 | 동작 |
|---|---|
git stash push -m "..." |
변경 저장하고 작업 트리 정리 |
git stash push -u -m "..." |
untracked 파일까지 포함 |
git stash list |
저장된 stash 목록 |
git stash pop |
최신 stash 적용 후 목록에서 제거 |
git stash apply stash@{N} |
지정한 stash 적용, 목록엔 남김 |
git stash drop stash@{N} |
지정한 stash 목록에서 제거 |
reset --hard 로 커밋이 로그에서 사라져도 실제로는 한동안 저장소 안에 남아 있습니다. git reflog 는 HEAD 가 가리켰던 위치 이력을 보여주므로, 잃어버린 커밋의 해시를 찾아 git reset --hard <해시> 로 되돌릴 수 있습니다.
git checkout 은 브랜치 이동과 파일 복원을 한 명령이 함께 처리해 실수하기 쉽습니다. 새 코드는 이동에 switch, 복원에 restore 를 씁니다. untracked 파일을 지우는 git clean 은 삭제 전 반드시 -n(드라이런)으로 대상부터 확인하고 -fd 로 실행합니다.