본문 바로가기
DevOps/Git

Git - 상태별 되돌리는 방법 예제로 알아보기 ( reset options )

by 맑은안개 2021. 9. 17.

스테이징 된 파일 되돌리기

📃 README.md파일 수정

  • before
# python3
python3 tutorial
  • After
# python3
python3 tutorial 

# Git commit test

변경 파일 add

add 명령 뒤에 . 을 지정하여 변경된 모든 파일을 스테이징 처리한다.

git add .
git status

On branch master
Your branch is up to date with 'python3/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md

스테이징 파일 되돌리기(add 취소)

  1. restore를 사용하여 unstage 목록 취소
git restore .

git restore -- /path/filename
  1. reset 명령을 사용하여 특정 커밋시점으로 복구
PS C:\\py3> git status  
On branch master  
Your branch is up to date with 'python3/master'.

Changes to be committed:  
(use "git restore --staged ..." to unstage)  
modified: README.md

PS C:\\py3> git reset HEAD  
Unstaged changes after reset:  
M README.md

커밋 되돌리기

reset 명령을 사용하여 커밋을 되돌린다. 다시 README.md 파일을 add 하여 스테이징에 올리고, commit 명령으로 커밋한다.

git add .  
git commit -m "update comments"

branch -vv 명령을 사용해 remote 커밋과 몇 단계 차이가 나는지 확인할 수 있다.

git branch -vv

-   master 108ba1d \[python3/master: ahead 1\] update contents

remote master 브랜치보다 로컬 commit이 한 단계 앞서 있다.

( 보통 remote는 origin/master 처럼 origin 으로 보인다. )

이제 이 커밋을 취소해보자. 취소 할 때는 스테이징 되돌리기 처럼 reset을 사용한다.

이때, 옵션으로 --hard, --soft, --mixed 세 가지가 있는데 어떤 차이가 있는지 예제를 통해서 확인해보자.

reset —mixed ( default )

reset을 하기 전에 git log 를 사용하여 어느 단계 커밋으로 reset 할 것인지 확인해보자.


git log --online

108ba1d (HEAD -> master) update contents  
2f8cf3d (python3/master) Merge branch 'master' of [https://github.com/choi\*\*/python3](https://github.com/choi**/python3)  
3bd5626 Resolve conflict  
2ea9da7 modified contents

여기서 HEAD가 가리키는 108ba1d 커밋이 위에서 커밋처리한 위치이다. HEAD 뒤에 ^, 혹은 ~1, ~2 등의 옵션을 주어 HEAD에서 부터 몇 단계 전으로 reset 할 것인지 지정할 수 있다.


git reset HEAD # HEAD 위치를 가르킨다. 이 명령은 아무 반응이 없다.

git reset HEAD^ # HEAD에서 한 단계 전을 가르킨다.

git reset HEAD~1 # HEAD에서 한 단계 전을 가르키며 HEAD^ 와 동일하다.

git reset HEAD~2 # HEAD에서 2커밋 전 단계를 가르킨다.

여기서는 HEAD^ 를 사용하여 한 단계 전으로 돌아가보자. --mixed 는 default 옵션으로 지정하지 않아도 무방하다.


git reset --mixed HEAD^  
Unstaged changes after reset:  
M README.md

git status  
On branch master  
Your branch is up to date with 'python3/master'.

Changes not staged for commit:  
(use "git add ..." to update what will be committed)  
(use "git restore ..." to discard changes in working directory)  
modified: README.md

no changes added to commit (use "git add" and/or "git commit -a")

Changes 상태로 돌아왔다. --mixed 옵션은 reset과 함께 되돌려진 파일을 Changes 즉, 스테이징 전 단계로 돌린다. git log 로 한 단계 전으로 reset 되었는지 확인해보자.


git log --oneline

2f8cf3d (HEAD -> master, python3/master) Merge branch 'master' of [https://github.com/choisoonsin/python3](https://github.com/choisoonsin/python3)  
3bd5626 Resolve conflict  
2ea9da7 modified contents  
75ee3dd Add chapter6 and regex exam

커밋이 한 단계 전으로 돌아갔고, remote의 master가 보고 있던 단계와 동일해 졌다.

다시 README.md 파일을 add commit 하고 --soft 옵션을 사용해 커밋을 돌려보자.

reset —soft


git add .

git commit -m "re commit"

git log --oneline

git reset --soft HEAD^

git status  
On branch master  
Your branch is up to date with 'python3/master'.

Changes to be committed:  
(use "git restore --staged ..." to unstage)  
modified: README.md

--soft--mixed 와 달리 스테이징 된 상태로 reset 된다.

이제 --hard 옵션을 사용해보자. 위와 동일하게 다시 진행한다.

reset —hard


git reset --hard HEAD^

--hard 처리 결과 README.md 의 변경내용이 사라지고 스테이징, Changes에도 보관되어 있지 않다. 이 처럼 --hard는 변경한 내용을 삭제한다.

reset 되돌리기

reflog를 사용하면 HEAD 변경 시점을 추적할 수 있다.


git reflog

2f8cf3d (HEAD -> master, python3/master) HEAD@{0}: reset: moving to HEAD^  
4d79430 HEAD@{1}: commit: re commit  
2f8cf3d (HEAD -> master, python3/master) HEAD@{2}: reset: moving to HEAD^  
81f1a7b HEAD@{3}: commit: re commit

제일 위의 2f8cf3d는 하드리셋한 뒤의 현재 HEAD상태를 나타내며, 4d79430은 하드리셋 하기 직전, re commit 한 commit이다. reset 전 시점으로 돌리기 위해 HEAD@{1} 로 되돌려보자.

git reset 'HEAD@{1}'

유의할 사항은 에디터 마다의 차이인지 모르겠으나, VSCode에서는 'HEAD@{1}' 처럼 싱글코테이션을 달아주어야 error: unknown switch `e' 에러가 발생하지 않는다.

반응형