Git 이해하기 Part 2

김민준·2022년 4월 20일
0

Git

목록 보기
2/2

Reset vs Revert 이해하기

Reset: 특정 과거 시점으로 돌아가기
Revert: "변경 커밋을 남기며" 특정 과거 시점으로 돌아가기

기본적으로 둘다 과거 시점으로 돌아가기 위해 사용하는 명령어지만,
엄연히 둘 간의 차이점이 있다. 알아보도록 하자!

Reset 이해하기

reset의 경우 과거로 돌아가는 방법에는 3가지가 있으며,
방법에 따라 변화가 달라진다.

optionWorking DirectoryStaging AreaLocal Repository
--soft변화 없음변화 없음reset 시점(commit id)
--mixed변화 없음reset 시점(commit id)reset 시점(commit id)
--hardreset 시점(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을 사용할 때는 다음을 고려하여 옵션을 결정하고 사용해야 한다.

  • 코드 변경 상태 적용 여부
    • Working Directory만 변경 사항이 적용 되었는가?
    • Working Directory + Staging Area까지 변경 사항이 적용 되었는가?
    • Working Directory + Staging Area + Local Repository까지 변경 사항이 적용 되었는가?
  • 개발자의 reset 목적
    • Working Directory, Staging Area, Local Repository 중에서 특정 시점으로 되돌릴 대상은 명확히 어디인가?

🤔 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 reflog

  • reference log
  • git log와 달리 한번이라도 commit이 된 내용이라면 현재 저장소 tree에 일반적으로 보이지 않는 모든 commit들을 보여줌
  • 따라서 git reflog를 통해 reset으로 인해 유실된 commit id를 먼저 찾고,
git reset --hard (유실된 commit id)

를 통해 다시 원래대로 돌아갈 수 있다.

reset의 특징을 다시 정리해보면...

  • git reset --soft: Local Repo만 리셋
  • git reset --mixed: Local Repo + Staing Area만 리셋
  • git reset --hard: Working Directory까지 모두 리셋
  • 잘못된 리셋의 복구도 리셋으로 가능
    • git reflog를 통해 먼저 유실된 commit id를 확인
    • git reset --hard (유실된 commit id)를 통해 복구

reset의 주의사항!

  • 커밋의 시점을 변동하기 때문에, 협업 시 주의가 필요
    • reset했을 때 Local Repository가 변경되어 Remote Repository와 불일치하여 충돌 가능성이 다분

  • 따라서 "remote repo에 push하기 전" 상황에서 사용하는 것이 가급적 좋으며, "remote repo를 혼자 사용하거나 팀원과 협의된 경우"에는
git push --force

로 해결도 가능

Revert 이해하기

revert의 경우 reset과 달리 option이 없고 변경 커밋을 남기며 과거 시점으로 돌아간다는 것이 핵심이다. reset과의 비교를 통해 알아보자.

위와 같은 상태에서 Da3de11 커밋 시점으로 돌아가고자 한다.
먼저, reset의 경우에는 HEAD를 돌아가고자 하는 커밋 시점을 가리키게 한다. 물론 이로 인해 유실된 commit id는 git reflog를 통해 확인할 수 있다.

다음으로 revert의 경우를 살펴보자.
revert의 경우는 변경 커밋을 남기면서 돌아가고자 하는 시점의 커밋과 동일한 내용으로 만든다.
과거 시점 커밋의 내용과 동일하게 만들기 위해 가장 최근 시점의 커밋부터 차례대로 이를 상쇄하는 변경 커밋을 만들어간다고 이해하면 될 것이다.
따라서, 실행 결과는 과거 시점 커밋의 내용과 일치하지만 reset과 달리 HEAD는 미래 시점의 커밋을 가리키고 있다.

아래 그림은

git revert 274aacc...Da3de11

를 실행한 결과를 그림으로 보여준다.

revert의 특징을 다시 정리해보면...

  • 과거 커밋 시점으로 돌아갈 때, reset과 달리 변경 이력을 남기며 돌아감
  • 코드의 시점은 과거로 변하지만, 커밋은 미래 시점으로 변경
    • reset과 달리 충돌없이 Remote Repository Push가 가능
    • 협업시 가급적 reset이 아닌 revert가 권장됨

  • 다만, revert도 잘못 사용하면 충돌이 일어날 수도 있음
    • e.g. 과거 시점의 특정 commit만 revert 하는 경우(권장하지 않음)

🤔 git commit --amend

  • 가장 최근 커밋을 수정하는 편리한 방법
  • 새 커밋을 별도로 생성하는 것이 아니라 기존의 최신 커밋을 수정함
  • 사용 예시
    • commit의 message를 수정하고 싶을 때
      • git commit --amend 명령어 입력 후 message 수정 후 commit
    • commit된 file, code를 수정하고 싶을 때
      • git add 명령어를 통해 먼저 Staging Area를 변경
      • 그 이후에 git comit --amend 명령어 입력 후 다시 commit
  • 주의할 점은 수정 전의 최신 커밋을 이미 remote repo에 push한 경우에는 git commit --amend로 커밋을 수정한 후에 push할 때 충돌이 발생함
profile
trial and error

0개의 댓글