커밋 되돌리기 (reset, branch, revert)
작업을 하다보면 커밋을 되돌려야하는 상황이 발생한다.
이럴 때 어떻게 해결하면 되는지 알아보자.
😎 reset
리셋은 과거 시점으로 커밋을 되돌려버린다.
git reset --hard
내 프로젝트의 파일이 해당 커밋 시점으로 되돌아간다.
그런데 위의 상황은 아주 다행이라고 할 수 있다.
내 원격 저장소에 파일이 올라가 있기 때문에 origin/main 에서 원래 가지고 있던 최신 내용을 유지해준다.
병합을 하기도 쉽다.
만약 그렇지 않은 상황이라면 어떻게 될까?
새로운 커밋을 하고 원격 저장소에 push하지 않은 상황이다.
여기서 reset을 통해 이전에 작업하던 커밋으로 돌아간다면 push 하지 않았던 작업 내용은 전부 날아간다. 주의하자.
이와같이 reset은 굉장히 쉽다 라는 장점이 있는 한 편 커밋이 날아간다 라는 단점이 있다.
그렇기 때문에 reset을 사용할 땐 굉장히 조심해야한다.
이번엔 새로운커밋을 푸시한 상황에서 이전 커밋으로 reset 하였다.
그리고 파일의 내용을 수정해서 커밋한다.
이미 origin/main이 있었는데 새로 커밋이 되었기 때문에 분기점이 달라졌다.
현재 origin이 아닌 내가 최신에 커밋한 내용으로 수정하고 싶다.
여기서 push를 한다면?
경고 메세지를 읽어보면 내가 현재 push하려는 내용은 원격 저장소보다 과거의 시점에서 시작했기 때문에 push를 할 수 없다는 내용
머지하고 push하는 방법도 있겠지만 '강제 푸시 (force push)'를 이용하면 된다.
😎 브랜치사용하기
이번엔 브랜치를 사용해서 커밋을 되돌려보자. 어쩌면 가장 익숙한 방법이지 않을까싶다.
현재 커밋한 내용이 있는데 아직 원격 저장소에는 올리지 않은 상황이다.
해당 작업에 수정이 필요해서 과거 커밋부터 다시 작업을 진행해야한다.
자신이 작업해야하는 시점의 커밋에서 브랜치를 만들고 체크아웃한다.
여기서 작업을 통해 내용을 수정하고 커밋한다.
이제 업데이트할 내용이 완성되었으니 main 브랜치로 작업 내용을 모두 합치면된다.
main 브랜치를 체크아웃하고 원하는 업데이트가 있는 커밋을 병합할 때 충돌이 날텐데 충돌해결으로 현재 내가 업데이트하고 싶은 내용으로 수정해주면된다.
브랜치 사용은 어느정도 익숙할 텐데 장점은 역시나 쉽다. 그리고 reset을 사용할 때와는 달리 기록이 사라지지 않는다.
그렇기 때문에 혼자 작업을 할 때 추천하는 방식이다.
굳이 단점을 꼽자면 트리가 지저분해진다.
😎 revert
이번엔 revert를 통해 커밋 내용을 과거로 되돌려보자.
revert를 할 때 중요한 점은 과거의 커밋을 건드리는 것이 아니라 내가 지금 보고 있는 커밋 통해 과거의 내용을 복원한다는 것이다.
커밋을 revert 시키면 해당 커밋의 내용을 바꾸는 것이 아니라 한 단계 전의 커밋을 복원한 Revert 커밋이 생성된다.
대상 커밋을 HEAD 커밋의 자식으로 새로 생성한다.
그렇기 때문에 revert 대상 커밋은 사라지지 않고, revert 대상 커밋의 내용을 되돌린 새로운 커밋이 생겨난다.
하나의 파일만 변경되면 모르겠지만 프로젝트 단위로 업무를 진행하다보면 여러 개의 파일을 수정하기 때문에 충돌이 날 수도 있다.
- 장점 : 이전 커밋 기록이 다 남아있다.
- 단점 : 충돌 날 가능성이 높다. 다소 어렵다.
🤔 만약 revert로 여러 커밋을 되돌리고 싶다면?
테스트를 위해 브랜치를 만들고 3개의 커밋을 올렸다.
commit 3에서 revert 시킨다면 commit 2의 내용이 될 것이다.
만약 commit 1의 내용으로 되돌아 가고 싶다면?
commit 2에서 '커밋 되돌리기 (revert)' 를 사용하면 되지 않을까?
그렇게되면 현재 내용은 commit 3이지만 commit 1의 내용이 겹치기 때문에 충돌이 일어난다.
충돌이 난 파일을 해결하고 진행하면 되지 않겠냐 생각하겠지만, 이는 바람직하지 못하다.
그렇다면 어떻게 해결하는 것이 바람직할까?
최신 커밋 부터 순차적으로 리버트시키면 된다.
여기서는 commit 3을 리버트 시킨 후 commit 2를 리버트 시키면 된다.
터미널을 열어 명령어로 하면 조금 더 간단하다.