git reset --
git reset
명령어에는 아래 세 가지 옵션을 줄 수 있다.
1.soft
: commit된 파일들을 staging area
로 돌려놓는다. — commit 하기 전 상태
2.mixed(default)
: commit된 파일들을 working directory
로 돌려놓는다. — add 하기 전 상태
3.hard
: commit된 파일들 중 tracked 파일들을 working directory에서 삭제
한다. (단, Untracked 파일은 Untracked로 남는다.)
그림으로 나타내면 아래와 같다.
git reset
은 사용시 주의 사항이 있다. 예를 들어, 아래와 같이 커밋 로그가 있고 원격 저장소(GitHub)에도 push된 상태라고 가정하자.
이 때 B 커밋으로 reset --hard
를 하게 되면 C,D 커밋은 커밋 히스토리 상에서 사라진다.
git reset --hard a0fvf8
로컬 저장소에서는 C,D 커밋이 사라졌지만 원격 저장소에는 C,D가 남아있다. 따라서 이 상태로 원격 저장소에 push 하게 되면 충돌이 발생한다. 로컬 저장소에서 커밋 C,D가 사라짐으로써 원격 저장소와 커밋 히스토리가 불일치 하기 때문이다.
나 혼자 사용하는 브랜치라면 push --force
명령어로 원격 저장소에 올리면 된다.
하지만 위 브랜치가 팀원과 공유하는 브랜치라면 문제가 발생한다. 팀원과 공유하는 브랜치에 커밋 히스토리를 바꾸게 되면 다른 팀원이 push를 할 때 충돌이 발생하기 때문이다. 따라서 다른 사람과 공유하는 브랜치에서는 reset --hard
로 커밋을 지우면 안 된다.
그럼 공유하는 브랜치에서 이전 커밋을 수정하고 싶을 때는 어떻게 해야할까? 이 때 사용하는 것이 git revert
이다.
git revert
이전 커밋 내역을 그대로 남겨둔 채 새로운 커밋을 생성한다.
따라서 다른 사람과 공유하는 브랜치에서 이전 커밋을 수정하고 싶을 때는 revert
를 사용하는게 좋다.
그래야 커밋 히스토리가 바뀌지 않아 충돌이 발생하지 않는다.
아래와 같은 커밋 히스토리 상에서 C,D 커밋을 revert 해보자.
git revert 5lk4er // D 커밋 revert
git revert 76sdeb // C 커밋 revert
위 그림처럼 이전 C,D 커밋 내역을 그대로 남겨두면서 revert 커밋을 추가한다. 커밋 히스토리 변경 없이 해당 커밋 내용을 삭제한 것이다. 따라서 원격 저장소에 push해도 충돌이 발생하지 않는다.
다른 사람과 공유하는 브랜치에서 커밋 내역을 수정해야할 경우 git revert
를 사용하자.
나 혼자 작업하는 브랜치에서는 git reset
을 사용해도 문제 없다.
안녕하세요! 정리된 글 잘 읽고 갑니다! 혹시 블로그에 기록 작성하려고 하는데, 출처남기고 작성해도 괜찮을까요?