개인공부/궁금해서 찾아보는

Git과 git reset

soon327 2021. 6. 14. 23:58

프로젝트 중에 커밋을 잘못해서 되돌리느라 git reset을 사용한 적이 있다.
사용하면서 어떤 방식으로 커밋을 되돌리는지 궁금했었는데 오늘에서야 찾아봤다.

Git

git workFlow

Git의 주목적은 프로젝트의 스냅샷을 지속적으로 저장하는 것이다.

  1. git init명령어를 실행하면 Git 저장소가 생성된다. 이 시점에는 워킹 디렉토리에만 데이터가 있다.
  2. git add 명령어를 실행하면 워킹디렉토리의 내용을 Index로 복사한다.
    (인덱스에 파일 상태를 기록하는 것을 Staging이라고 부르기 때문에, 인덱스는 Staging Area 라고도 부른다. )
  3. git commit명령어를 실행하면 Index의 내용을 스냅샷(HEAD)으로 영구히 저장하고 그 스냅샷을 가리키는 커밋 객체를 만든다. 그리고는 master가 그 커밋 객체를 가리키도록 한다. (HEAD는 현재 브랜치의 마지막 커밋의 스냅샷이다.)
  4. git status명령어는 워킹디렉토리 - index - HEAD가 같은지 확인한다. 같다면 아무런 변경사항이 없다고 뜨고, 워킹디렉토리만 다르다면 빨간색, 워킹디렉토리와 Index만 같다면 녹색으로 표시된다.

Git Reset

reset명령은 워킹디렉토리, Index, HEAD를 조작함으로써 명령을 수행한다.

** checkout과 reset의 차이
checkout은 HEAD가 가리키는 브랜치를 바꾸지만, reset은 HEAD는 계속 현재 브랜치를 가리키고 있고 해당 브랜치가 가리키는 커밋을 바꾼다.
예를들어 master브랜치에서 작업하고있을때 git reset 9e5e6a4 명령은 master 브랜치가 '9e5e6a4'를 가리키게 한다.

reset --soft

브랜치가 가리키는 커밋만 이전으로 되돌린다. (HEAD는 현재브랜치의 마지막 커밋의 스냅샷이므로 HEAD도 이전으로 되돌려진다.)

reset --mixed (default)

Index를 현재 HEAD가 가리키는 스냅샷으로 업데이트한다. 즉 Staging Area가 비워진다.

reset --hard

워킹디렉토리의 내용까지 되돌린다. 이 hard옵션을 사용하면 워킹 디렉토리의 파일을 강제로 덮어씌운다. 만약 커밋하지 않았다면 덮어쓴 데이터는 복원할 수 없다.

정리

reset 명령은 정해진 순서대로 세 개의 트리를 덮어써 나가다가 옵션에 따라 지정한 곳에서 멈춘다.

  1. HEAD가 가리키는 브랜치를 옮긴다. (--soft 옵션이 붙으면 여기까지)
  2. Index를 HEAD가 가리키는 상태로 만든다. (--hard 옵션이 붙지 않았으면 여기까지)
  3. 워킹 디렉토리를 Index의 상태로 만든다.

Reference

Git --fast-version-control