ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Git] commit 또는 push 된 내용 되돌리기 (reset, revert)
    저장소/git 2020. 2. 16. 20:10

    commit 또는 push했던 내용이 잘못되어서 이전 상태로 되돌려야 하는 경우는 종종 발생합니다. 로컬에 commit만 하는 경우엔 쉽게 reset 기능으로 처리할 수 있지만 원격 저장소까지 push가 된 경우엔 revert라는 기능을 사용해야 합니다. (reset --f를 사용하지 않는다면)

    아래에선 reset과 revert기능을 위주로 언제 사용하고 어떠한 기능이 있는지 설명합니다.

    git reset

    먼저 reset의 기능은 의미 그대로 reset하고자 하는 커밋으로 돌아간 다음, 해당 커밋 이후의 이력을 전부 삭제합니다. reset에는 hard, mixed, soft와 같이 3 가지 기능을 제공하는데 아래 예시를 들어 설명합니다.


    먼저 아래와 같이 커밋이 되어 있다고 가정합니다.


    현재 활성화된 커밋은 커밋 세번째인데 커밋 첫 번째로 reset을 진행하려 합니다.

    reset 명령어는 git reset [--옵션] [돌아갈 커밋] 으로 사용합니다.

    git --hard 467cfb1ca7146adfbd46d202968e9769996bd7c3

    먼저 hard 옵션은 돌아간 커밋 이후의 변경 이력을 전부 삭제해버립니다. 즉, 커밋 두 번째와 커밋 세 번째에 변경하여 반영한 내용이 사라지게 됩니다. 

    git --mixed 467cfb1ca7146adfbd46d202968e9769996bd7c3

    변경 이력은 전부 삭제하지만 변경된 내용에 대해서는 남아있습니다. 하지만 unstage상태로 남아 있으므로 커밋을 진행하기 전에 stage에 먼저 추가해야 합니다.

    git --soft 467cfb1ca7146adfbd46d202968e9769996bd7c3

    변경 이력은 전부 삭제하지만 변경된 내용에 대해서는 남아 있습니다. mixed와는 다르게 stage에 올라간 상태이므로 바로 커밋을 진행할 수 있습니다.


    만약 reset한 커밋 위의 내용이 잘못 되어서 hard 옵션으로 reset을 진행한 다음, push를 하려 하면 아래와 같이 오류가 발생합니다.


    이러한 오류가 발생하는 이유는 로컬 저장소의 커밋 히스토리가 원격 저장소의 커밋 히스토리보다 뒤에 있는데 push를 진행하려고 하여 발생한 오류입니다. 이럴때는 강제로 덮어써야 하므로 push에 -f 또는 --force 옵션을 주어 강제로 덮어쓰도록 합니다.

    reset 주의사항

    reset을 사용하면 원격 저장소에 흔적도 없이 커밋들을 제거할 수 있어 좋아보이지만 혼자 사용하는 브랜치가 아니여서 reset 이후 삭제될 커밋 중 다른 사람이 작성한 커밋이 있거나  커밋들을 되돌리기 전에 다른 팀원이 내가 작성한 커밋들을 이미 땡겨갔다면 다른 사람들의 로컬 저장소에는 내가 되돌린 커밋들이 남아있게 됩니다. 

    이러한 주의사항이 있어서 reset 기능을 사용할 땐 아래와 같은 상황에서만 사용해야 합니다.

    • 혼자만 사용하는 브랜치일 때
    • 다른 사람들이 해당 브랜치를 받은 적이 없다고 확인된 경우

    git revert

    revert 기능은 특정 커밋을 되돌리는 작업도 하나의 커밋으로 간주하여 커밋 히스토리에 추가하는 방식입니다. 즉 revert를 진행하면 reset --soft 또는 --mixed와 동일한 결과를 가지지만 이력은 같지 않습니다. 


    바로 revert 진행


    revert 결과



    위와 같이 커밋 첫 번째의 해쉬값을 입력하면 커밋 첫 번째 이후의 커밋들이 삭제되는 것이 아닌, 커밋 첫 번째에 해당하는 내용만 삭제가 됩니다. 그리고 삭제된 내용을 커밋으로 다시 남기게 됩니다. 만약 reset 기능과 같이 사용하고 싶다면 reset 이후의 커밋들을 전부 revert로 입력해야 합니다.


    만약 자동으로 커밋을 진행하고 싶지 않다면 --no-commit 옵션을 주면 됩니다.


    되돌릴 커밋이 여러개라면 범위를 지정하여 아래와 같이 진행할 수 있습니다.

    $ git revert [되돌릴 커밋 hash]..[되돌릴 커밋 hash]


    이처럼 revert는 되돌릴 커밋이 중간에 있거나, 되돌린 후 어떤 커밋이 왜 revert가 되었는지 이력을 남길 수 있어서 유용합니다. 혼자 브랜치를 사용하는 경우가 아니라면 reset보단 revert를 사용하는 것이 좋습니다.

    댓글