Skip to content

git reset (soft · mixed · hard) ​

bash
git reset [옵션][커밋 아이디]

git reset --hard HEAD^  #헤드가 이전 커밋을 가리킴
git reset --soft HEAD~x  #x단계 전에 있는 커밋을 말함
만약 HEAD~2 이면 현재 가리키고 있는 HEAD 커밋보다 2단계 이전을 말하는 거임

git reset의 3가지 옵션 ​

Git에서 git reset 명령어는 과거의 커밋으로 HEAD의 위치를 옮길 때 사용하며, 옵션에 따라 영향을 미치는 작업 영역이 다릅니다.

Git에는 3가지 작업 영역이 있습니다:

  • 워킹 디렉토리 (Working directory)
  • 스테이징 에어리어 (Staging area)
  • 레포지토리 (Repository)

옵션별 동작 ​

옵션레포지토리(HEAD)스테이징 에어리어워킹 디렉토리
hardOOO
mixedOOX
softOXX

▶ hard옵션:

  • 세 가지 작업 영역 모두 과거 커밋 상태로 리셋됨
  • 커밋 이후의 모든 변경사항이 사라짐(복구 불가)
  • 주의해서 사용해야 함

▶ mixed옵션:

  • 레포지토리(HEAD)와 스테이징 에어리어만 리셋
  • 워킹 디렉토리는 유지됨
  • 보통 기본 옵션(옵션 없이 사용 시 mixed가 기본)

▶ soft 옵션:

  • 레포지토리(HEAD)만 리셋
  • 스테이징 에어리어, 워킹 디렉토리는 그대로 유지됨

git reset 전체 요약 ​

  • hard → 모든 영역 리셋 (워킹 디렉토리까지)
  • mixed → 레포지토리와 스테이징 에어리어만 리셋 (워킹 디렉토리는 그대로)
  • soft → 레포지토리만 리셋 (나머지 그대로)

일반적으로 작업한 내용이 날아가면 안 되는 경우에는 soft나 mixed 옵션을 사용하는 것이 좋고, hard는 정말 필요할 때만 사용하는 것을 권장함.

git reset 커맨드의 동작원리 ​

1. git reset을 할 때 HEAD의 변화는? ​

지금 총 4개의 커밋을 한 아래와 같은 상황이라고 가정합시다.

현재 각 박스 안에 있는 텍스트는 각 커밋의 커밋 아이디 앞 부분입니다.

이 상태에서

git reset [--hard 또는 --soft 또는 --mixed] 9033

을 실행한다면 어떻게 될까요? 이전에 git reset을 배울 때를 떠올려보면 HEAD가 9033.. 커밋을 가리키게 되겠죠? 그럼 정확히 어떤 모습으로 가리키게 되는 건지 보여드리겠습니다. 어떤 옵션을 쓰든 아래 그림과 같은 결과가 됩니다.

지금 HEAD는 여전히 master 브랜치를 가리킵니다. 대신 master 브랜치가 가리키던 커밋이 바뀌었네요. 그래서 결과적으로 HEAD가 9033.. 커밋을 가리키게 된 겁니다.

방금 발생한 일을 정리하면 다음과 같습니다. git reset 커맨드를 사용하면

  1. HEAD는 여전히 같은 브랜치를 가리키고,
  2. HEAD가 가리키는 브랜치가 다른 특정 커밋을 가리키게 됩니다.
  3. 이 때문에 결국 HEAD가 간접적으로 가리키던 커밋도 바뀌게 되는 겁니다.

git reset을 했을 때 HEAD가 가리키던 커밋이 바뀐다는 말이 정확히 무슨 뜻인지, 이제 아시겠죠? 바로 이런 원리가 있었던 겁니다. 그리고 이전에 배운대로 각 옵션(--soft/--mixed/--hard)에 따라 과거의 커밋처럼 working directory나 staging area도 리셋되는지가 결정되는 거구요.

하지만 한 가지 더 알아야할 git reset의 비밀이 있는데요.

2. git reset을 한다고 그 이후의 커밋이 사라지는 건 아닙니다. ​

git reset을 한다고 하면 그 이후의 커밋이 삭제되는 것으로 착각하기 쉽습니다. 그러니까 위 상황에서 네 번째 커밋인 43kf.. 커밋이 사라진다고 오해하실 수도 있는데요. 전혀 그렇지 않습니다. 43kf.. 커밋은 계속 남아있습니다.

그리고 git reset은 꼭 과거의 커밋으로만 할 수 있는 것도 아닙니다. 현재 HEAD가 가리키고 있는 커밋 이후의 커밋으로도 리셋할 수 있죠.

  • 지금처럼 HEAD가 3번째 커밋인 9033.. 커밋을 가리키고 있는 상태에서

git reset 43kf

를 실행하면 master 브랜치가 다시 43kf.. 커밋을 가리키게 됩니다. 아래 그림처럼요.

그러니까 git reset에 관해서 분명하게 아셔야할 게

  1. 과거의 커밋으로 git reset을 한다고 그 이후의 커밋들이 삭제되는 게 절대 아닙니다. 계속 남아있습니다.
  2. git reset은 과거의 커밋뿐만 아니라 현재 HEAD가 가리키는 커밋 이후의 커밋으로도 할 수 있습니다.

이 사실을 확실히 알고 나면 앞으로 git reset을 사용해서 커밋 사이를 자유자재로 이동할 수 있을 겁니다.

여러 커밋을 하나의 커밋으로 만들기 (git reset 심화) ​

구체적으로, 실수로 불필요하게 커밋이 여러 개 생긴 경우,

필요 없는 커밋 이전으로 git reset --soft 또는 --mixed 옵션을 사용해서

HEAD(브랜치의 기준점)을 이전 커밋으로 되돌릴 수 있어요.

이렇게 하면 워킹 디렉토리(작업 파일)는 최신 상태로 유지되고,

여기서 다시 **git add .**와 git commit을 하면

불필요한 커밋들을 하나로 합칠 수 있습니다.

정리하자면

  • 없애고 싶은 커밋 이전 시점으로 git reset --soft 또는 -mixed
  • 워킹 디렉토리는 최신 상태로 유지됨
  • 다시 추가/커밋해서 깔끔하게 커밋 히스토리를 정리할 수 있음

이렇게 하면 커밋 히스토리가 깔끔해져서 관리하기가 쉬워집니다!

정리 ​

옵션레포지토리(HEAD)스테이징 에어리어워킹 디렉토리
--soft리셋유지유지
--mixed (기본)리셋리셋유지
--hard리셋리셋리셋 (변경사항 사라짐)
  • reset은 HEAD가 가리키는 브랜치를 다른 커밋으로 옮기는 것이고, 이후 커밋이 삭제되지는 않음

참고: 개인 Notion 학습 노트 (Git 공부)