Git에서 강제로 진행한 push를 되돌리는 방법 (사고침) + git reset --hard

지누·2023년 10월 13일
0
post-thumbnail
post-custom-banner

사건의 전말

큐시즘 세미밋업 제출 자료인 README.md 파일을 모든 조가 한 레포지토리에 올린다.

17시쯤 git pull하고 공부하고 밥먹고 온뒤, 19시에 우리 조 README.md 파일을 수정하여 git push하려고 했으나, 다음과 같은 에러가 발생했다.

원격 저장소에 변경된 사항 있어서 내 로컬에서 변경된 사항과 통합해야 하는데, 그러지 못해서 발생하는 경고 메세지이다.

너무나 당연한 경고메세지이고 git pull로 변경 사항을 동기화 해주면 되는데, 평소에 강제로 push하던 습관때문에 git push -u origin +main 를 입력했다.

근데 이렇게하면, 변경 내역만 반영이 되는 것이 아니라 소스 전체가 덮어씌워진다.

20시에 제출 마감이라, 열심히 수정을 하던 다른 팀원의 리드미가 17시에 내가 pull했던 버전으로 돌아와 버린것.

커밋내역과 소스 전부가 덮어쓰기 되어서, 커밋내역을 보아도 17시 이후에 수정한 커밋 내역은 남아있지 않다. 결론을 말하자면 강제로 push하여 올라가버린 원격 저장소의 내역은, 이전으로 되돌릴 수 없다.

git revert VS git reset

맨날 pushpull만 하고, reset이나 revert명령어는 거의 쓰지 않아서 필요할 때 마다 구글링했는데, 한바탕 사고를 치고 나니 잊을 수 없을 것 같다.

reset명령어와 revert명령어는 둘 다 이전 커밋 내역으로 되돌아가는 명령어이고, 잘못 push를 한 경우에도 이전 버전으로 되돌아가 다시push를 해 주면 된다.

다만 이 두 명령어도, 이전 커밋 내역으로 되돌아가는 것인데, 강제로 push를 했으므로 2시간의 커밋 내역이 존재 할 수가 없다. 아래의 커밋으로 되돌아 가 봤자 내 변경사항만 롤백한 셈이다. 사라져버린 2시간의 기록을 되돌릴 수 있는 방법은 없다.

그래도 revertreset의 차이는 확실히 알게 되었다.
revert는 커밋을 되돌아간다는 내역도 커밋로그를 남겨주고, reset은 해당 커밋으로 되돌아가고, 해당 커밋 이후의 커밋로그는 지워버린다.

그래서 협업을 할 때는 반드시 revert를 사용하고, 개인 레포의 경우는 깃로그를 깔끔하게 하기위해, reset을 사용해서 아예 지워버리는 것이 나을 것 같다.

git reset

다음과 같은 코드를 작성하고, 커밋을 했다고 하자. 해당 커밋번호는 A번이다.

이렇게 코드를 작성한후, A커밋으로 되돌아 갈려고 하면 git reset A처럼 작성할 수 있다.
이 때 reset 명령어에 적용할 수 있는 옵션이 있다.

git reset --hard


--hard 옵션을 붙여서 reset하게 되면, 내가 작성한 스파게티코드를 전부 지운 상태로 되돌려 준다.

  • current working directory의 작업 내용을 커밋 상태와 동일하게 만든다.
  • staging Area에 staging한 내역이 있더라도 커밋 상태와 동일하게 만든다.

git reset --mixed (default)


--mixed옵션을 붙이거나 디폴트로 reset하게 되면, 해당 커밋 이후의 변경 내역을 지우지 않고 그대로 둔다.

  • current working directory의 작업 내용을 변경하지 않는다.
  • staging Area에 staging한 내역이 있더라도 커밋 상태와 동일하게 만든다.

git reset --soft

--soft옵션을 붙여reset하게 되면, 해당 커밋 이후의 변경 내역을 지우지 않고, Unstaging된 상태로 놔둔다.

--mixed 옵션과 비슷하지만, 스테이징된 내용을 그대로 둔다. 작업별로 스테이징과 커밋을 잘 구분하지 않기 때문에, --hard옵션만 잘 이해하면 될 것 같다.


오늘의 결론 : 강제로 진행하는 cli 명령은 조심해서 쓰자. 경고를 띄워주는데는 그만한 이유가 있다.

profile
열심히 좀 살자😱
post-custom-banner

0개의 댓글