Reset: 특정 과거 시점으로 돌아가기
Revert: "변경 커밋을 남기며" 특정 과거 시점으로 돌아가기
기본적으로 둘다 과거 시점으로 돌아가기 위해 사용하는 명령어지만,
엄연히 둘 간의 차이점이 있다. 알아보도록 하자!
reset의 경우 과거로 돌아가는 방법에는 3가지가 있으며,
방법에 따라 변화가 달라진다.
option | Working Directory | Staging Area | Local Repository |
---|---|---|---|
--soft | 변화 없음 | 변화 없음 | reset 시점(commit id) |
--mixed | 변화 없음 | reset 시점(commit id) | reset 시점(commit id) |
--hard | reset 시점(commit id) | reset 시점(commit id) | reset 시점(commit id) |
명확한 이해를 위해 예시를 통해 자세히 살펴보자.
현재 HEAD가 Main Branch가 가리키고 있는 274aacc를 가리키고 있는 상황이다.
그 상태에서 Working Directory에서 코드를 추가로 작성하여 변경사항이 발생하였다.
이 때,
git reset --hard Da3de11
를 실행한다면
Working Directory 뿐만 아니라 Staging Area, Local Repository까지 Da3de11 시점으로 돌아가게 된다.
반면,
git reset (--mixed) Da3de11
(reset의 default값은 --mixed이므로 생략 가능)
의 경우에는 Working Directory만 변경되지 않고, 나머지는 모두 Da3de11 커밋 시점으로 돌아갈 것이다.
마지막으로,
git reset --soft Da3de11
(reset의 default값은 --mixed이므로 생략 가능)
의 경우에는 Local Repository만 Da3de11 커밋 시점으로 돌아갈 것이다.
결국 reset을 사용할 때는 다음을 고려하여 옵션을 결정하고 사용해야 한다.
아래는 원래 HEAD가 90ac000 커밋을 가리키고 있었으나
git reset --hard 48ea1f3
을 통해 48ea1f3 커밋 시점으로 되돌아간 상태를 보여주고 있다.
option이 --hard이므로 Local Repository로부터 Working Directory까지 모두 48ea1f3 시점으로 변경된 상태이다.
근데 reset을 잘못하여 다시 원래대로 돌아가고 싶을 때 어떻게 해야할까?
당황스러운 마음으로 일단,
git log
를 입력해보지만, 이미 reset 되어 다시 원래대로 가고자 하는 commit은 전혀 보이지 않는다... 눈물을 머금고 코드를 다시 작성해야 할까?
아니다! 다시 복원할 수 있다. "git reflog"와 "git reset"을 활용하여 "reset을 다시 reset" 할 수 있다.
git reset --hard (유실된 commit id)
를 통해 다시 원래대로 돌아갈 수 있다.
git push --force
로 해결도 가능
revert의 경우 reset과 달리 option이 없고 변경 커밋을 남기며 과거 시점으로 돌아간다는 것이 핵심이다. reset과의 비교를 통해 알아보자.
위와 같은 상태에서 Da3de11 커밋 시점으로 돌아가고자 한다.
먼저, reset의 경우에는 HEAD를 돌아가고자 하는 커밋 시점을 가리키게 한다. 물론 이로 인해 유실된 commit id는 git reflog를 통해 확인할 수 있다.
다음으로 revert의 경우를 살펴보자.
revert의 경우는 변경 커밋을 남기면서 돌아가고자 하는 시점의 커밋과 동일한 내용으로 만든다.
과거 시점 커밋의 내용과 동일하게 만들기 위해 가장 최근 시점의 커밋부터 차례대로 이를 상쇄하는 변경 커밋을 만들어간다고 이해하면 될 것이다.
따라서, 실행 결과는 과거 시점 커밋의 내용과 일치하지만 reset과 달리 HEAD는 미래 시점의 커밋을 가리키고 있다.
아래 그림은
git revert 274aacc...Da3de11
를 실행한 결과를 그림으로 보여준다.