Git으로 협업프로젝트를 진행하였다.
깃으로 협업하는데 익숙치 않은터라 한번 push를 잘못하거나, 로컬의 main 브랜치에서 원격저장소로부터 pull하고 거기서 의도와 다르게 다른 브랜치와 merge 해버리는.. 그리고 거기서 어떻게 되돌릴 줄 몰라 결국 다시 git clone으로 새로 시작해버리는 경우가 있었다(...🥺)
- 결국 Git으로 협업하는데에 필요한 지식이 부족함을 느끼고
reset
과revert
의 개념, 사용목적과 그 차이, 사용법을 다시 제대로 숙지해본다.
일단 간략하게 다뤄보자.
reset
: 시간을 아예 과거의 특정 사건(commit)으로 되돌린다.revert
: 현재에 있으면서 과거의 특정 사건(commit)들만 없던 일로 만든다.
둘의 공통점은 '과거로 되돌린다.'
는 것이지만, 가장 큰 차이점은 '과거로 되돌리겠다는 내용도 기록되는가?(== commit 이력에 남는가?)'
이다.
reset
은 아예 현재가 없었던 것 처럼 원하는 과거로 돌아갈 수 있다. 정말 말 그대로 '리셋'이다. reset
은 이력을 남기지 않는다. 따라서 현재까지의 commit 이력을 남기지 않고 원하는 시점으로 완전히 되돌아가고 싶을 때 사용할 수 있다.
revert
는 과거로 돌아가겠다는 이력을 남겨두고 원하는 시점으로 돌아간다. 즉, 이전의 commit 내역을 남겨두고 새로운 commit을 생성하면서 과거로 돌아가게 된다.
위의 그림에서 git reset --hard a0fvf8
을 해보자. 'a0fvf8' commit으로 돌아간다는 뜻이다.
commmit 히스토리에 C,D 커밋이 아예 사라진다.
revert
를 이용해 B 커밋으로 돌아가려면?
git revert 5lk4er
// D 커밋 revert
git revert 76sdeb
// C 커밋 revert
위와 같이 뒤 커밋부터 순차적으로 revert
해준다.
그럼 이렇게 revert한 내용의 커밋 이력을 남기면서 B로 돌아갈 수 있음을 확인할 수 있다!
협업프로젝트에서 다른 팀원과 같은 branch를 공유하는 상황일때, 가급적
revert
를 사용한다.
이유가 뭘까?
[영희]는 코드를 짜다 성에 차지않아 과거의 커밋으로 돌아가고자 한다. 그래서 reset
을 사용해 과거로 돌아가 다시 코드를 짜고 커밋을 진행했다. 이후 Github의 remote repository에 push를 한다면?
=> 충돌이 발생할 수 있다. 원격 저장소의 기존 commit 히스토리에는 영희가 날려버린 commit이 존재 할 수 있기 때문이다. (원격저장소에는 해당 커밋이 있지만 영희의 로컬저장소에는 해당 커밋이 없다.)
만약, [영희] 혼자 진행하는 프로젝트라면, 로컬과 원격의 커밋 히스토리가 불일치해도git push --force
를 이용해 연결할 수 있다.
다만 [영희] 혼자가 아닌 [영희]와 [철수]가 같은 branch를 공유하는 협업 프로젝트에서, [영희]가 멋대로 커밋 이력을 삭제해버린다면 [철수]가 push 할때 충돌이 날 것이다.
따라서, 협업 프로젝트에서 이전의 커밋으로 돌아가고 싶을 땐 revert
를 사용하는 것이 좋다.
git reset --soft [commit ID] git reset --mixed [commit ID] git reset --hard [commit ID] git reset HEAD~10 git reset HEAD^
soft
: commit된 파일들을 staging area로 돌려놓음. (commit 하기 전 상태로)mixed(default)
: commit된 파일들을 working directory로 돌려놓음. (add 하기 전 상태로)hard
: commit된 파일들 중 tracked 파일들을 working directory에서 삭제한다. (Untracked 파일은 여전히 Untracked로 남는다.)git reset --hard HEAD^
를 혼자 할땐 제일 많이 쓰게되더라..HEAD~취소할커밋수
: 현재로부터 원하는 만큼의 커밋이 취소된다.HEAD^
: 가장 최근의 커밋이 취소된다. (기본옵션mixed
)
git revert [commit ID]
돌아가고자 하는 commit ID를 적어준다.
revert
를 사용하면 중간에 무슨 문제가 있었는지, 왜 돌아갔는지 등의 기록이 가능하다는 장점이 있다. 또한 다른 사람과 같은 브랜치에서 함께 작업할 때 코드 충돌을 최소화할 수 있다.
reset
을 사용하면 커밋 히스토리를 깔끔하게 유지할 수 있고, 혼자 작업할 때 편하게 되돌아갈 수 있다는 장점이 있다. 그러나 타인과 같은 브랜치에서 함께 작업할 때 커밋이 뒤섞여버릴 수 있다는 위험한 단점이 있다.
감사합니다!