[ GIT ] 작업 되돌리는 명령어 Reset & Revert

김하영·2020년 7월 12일
4
  • Git 에서 작업 되돌리기

commit 또는 push 했던 내용이 잘못되어서 이전 상태로 되돌려야 하는 경우는 종종 발생한다.

로컬에 commit만 하는 경우에는 쉽게 reset 기능으로 처리할 수 있지만, 원격 저장소까지 push가 된 경우엔 revert를 사용한다.

Reset

Revert

  • 세 개의 트리

Git을 서로 다른 세 트리를 관리하는 컨텐츠 관리자로 생각하면 reset을 더 쉽게 이해할 수 있다,

트리 is '파일의 묶음'

Git은 일반적으로 세 가지 트리를 관리하는 시스템이다.

  1. HEAD
  • 마지막 커밋 스냅샷, 다음 커밋의 부모 커밋

  • 현재 브랜치를 가리키는 포인터이며, 브랜치는 브랜치에 담긴 커밋 중 가장 마지막 커밋을 가리킨다.

  • 현재 브랜치 마지막 커밋의 스냅샷 / 다음 커밋의 부모

  1. Index
  • 바로 다음에 커밋할 스냅샷

  • 'Staging Area' > 사용자가 git commit 명령을 실행했을 때 Git이 처리할 것들이 있는 곳

  • 워킹 디렉토리에서 마지막으로 checkout 한 브랜치의 파일 목록과 파일 내용으로 채우고, 이후 작업한 내용으로 index를 업데이트

git commit 명령을 실행하여 index는 새 커밋으로 변환

  1. 워킹 디렉토리
  • 샌드박스 ( 다음 커밋을 위한 작업 공간 )

  • HEAD 와 Index는 .git 디렉토리에 저장되고, 워킹 디렉토리는 실제 파일로 존재한다.

  • 바로 눈에 보이기 때문에 사용자가 편집하기 수월하며 commit 하기 전에는 Index에 올려놓고 얼마든지 변경할 수 있다.

  1. Reset
  • 특정 지점의 과거 커밋으로 이동, 이동된 이후의 커밋은 삭제된다.

  • 사용 상 주의 요망 : 과거 커밋으로 이동하면서 그 이후 커밋은 삭제되어 되돌릴 수 없으므로 주의가 필요하다.

  • 특히, push 후에는 다른 사람의 코드에 문제를 일으킬 소지가 있으므로 금지한다.

  • 즉, 애초에 commit 하지 않은 것처럼 예전 커밋으로 브랜치를 옮기는 것이다.

  • 기본 사용법

주로 사용하는 옵션 3가지 : --mixed, --hard, --soft / 기본값은 --mixed

커밋ID는 앞자리 일부만 사용 가능하다.

#git reset [--옵션] 커밋ID

  • git reset --hard
    --hard 옵션을 적용하면 해당 커밋ID의 상태로 워킹디렉토리와 Index 영역 모두 초기화 된다.
    변경 이력 및 내용 전부 삭제한다.
    HEAD / Index / 워킹디렉토리 reset
    ex

    프로젝트 디렉토리에 ‘text.txt’파일을 추가 커밋
    git reset --hard 이전커밋아이디 명령어를 실행한다.
    ‘text.txt’ 파일은 삭제되며 git status에서도 확인이 불가능하다.

  • git reset --mixed
    --mixed 옵션을 적용하거나 옵션을 적용하지 않으면 해당 커밋ID의 상태로 Index 영역은 초기화되고 워킹디렉토리는 변경되지 않는다.
    변경 이력 삭제, 변경된 내용은 남아있다. > unstage 상태로 남아 있으므로 커밋을 진행하기 전에 stage에 먼저 추가해야한다 (git add)
    HEAD / Index reset
    ex

    프로젝트 디렉토리에 ‘text.txt’파일을 추가 커밋
    git reset --hard 이전커밋아이디 명령어를 실행한다.
    ‘text.txt’파일은 살아있으며, Index영역에는 추가되지 않은 상태다.

  • git reset --soft
    --soft 옵션을 적용하면 해당 커밋ID의 상태로 Index 영역과 워킹디렉토리 모두 변경되지 않는다.
    변경 이력 삭제, 변경된 내용은 남아있다. > mixed와 다르게 stage에 올라간 상태이므로 바로 커밋을 진행할 수 있다.
    HEAD reset
    ex

    프로젝트 디렉토리에 ‘text.txt’파일을 추가 커밋
    다시 ‘text2.txt’ 파일을 git add text2.txt
    git reset --soft 이전커밋아이디 명령어를 실행한다. > ‘text.txt’, ‘text2.txt’ 파일 모두 git status를 확인 해보면 add된 상태

  • 돌아가고 싶은 commit으로 reset할 때

--hard: reset하기 전까지 했던 staging area, working directory의 작업까지 모두 reset!
(모든 게 잘못됐어! 나 돌아갈래~ 꽃피던 때부터 정갈하게 다시 해보자!)

--mixed(default): staging area은 reset, reset하기 전까지 했던 working directory의 작업은 남겨둠.
(현재 작업물은 지우긴 싫고, 이전 버전으로 돌아가서 add할지 말지 결정해야 할 때)

--soft: reset하기 전까지 했던 staging area, working directory의 작업은 남겨둠.

(reset한 버전과 현재까지의 작업을 합쳐 새로운 버전 만들 때)

  • reset 활용

$ git reset HEAD~6 : 현재부터 6개 이전 이력으로 돌아가라라고 상대적으로 지정할 수 있다.

  • reset 시, 주의사항
  1. hard 옵션으로 reset 후, push 할 때

로컬 저장소의 커밋 히스토리가 원격 저장소의 커밋 히스토리보다 뒤에 있어 (non-fast-forward) 인 경우, push를 진행시 오류가 발생한다.

이럴 때는 강제로 덮어써야 하므로 push에 -f 또는 -force 옵션을 주어 강제로 덮어쓴다.

  1. reset을 원격저장소에서 사용할 때

혼자 사용하는 브랜치가 아니므로 reset 후, 삭제될 커밋 중 다른 사람이 작성한 커밋이 있을 수 있다.

또, 커밋들을 되돌리기 전 다른 사람이 커밋들을 땡겨갔다면 다른 사람들의 로컬 저장소에는 내가 되돌린 커밋이 남아있다.

그래서 reset은 혼자만 사용하는 브랜치일 때 / 다른 사람들이 해당 브랜치를 받은 적이 없다고 확인된 경우 사용한다.

  1. Revert
  • reset 주의사항을 고려한 변경하고 해당 되돌린 내용을 다른 사람들과 공유할 수 있는 기능이다.

  • 특정 지점의 과거 커밋으로 이동, 변경 내역은 유지한다.

  • 즉, 이력이 남기 때문에 많은 사람들과 작업할때 유용하다.

git revert <되돌릴 커밋>

git revert 2664ce8

  • 되돌릴 커밋이 여러개라면 범위를 주어서 여러개를 선택할 수도 있다.

git revert 2664ce8..15413dc

  1. 깃(Git)에서 유실된 커밋 복원하기

작업을 하다가 rebase 실수 또는 잘못된 명령어나 조작 실수 등 다양한 이유로 인해 작업이 날라 가는 경우가 있다.
git의 명령어 중에 reference logs 라는 의미를 가진 reflogs 라는 옵션을 사용하여 해결한다.

git reflog

위 명령어가 실행되면 나오는 화면에서 저장소 tree에 일반적으로 보이지 않는 모든 commit들을 살펴볼 수 있다.

여기서 유실된 commit을 찾은 후 해당 commit의 commitID를 찾아서 상황에 맞게 다음 명령어들을 사용하면 된다.

해당 유실된 커밋을 HEAD로 하는 tree로 돌려놓으려면 아래처럼 리셋 명령어를 실행하면된다.

git reset --hard {commitID}

해당 유실된 커밋만 현재 브랜치로 가져오려면 아래처럼 체리픽을 이용한다.

git cherry-pick {commitID}

profile
Back-end Developer

0개의 댓글