git push는 신중하게 해야하지만 사람인지라 가끔 실수할 때가 있다.
개인 branch에 푸시 후 develop 브랜치에 머지하기 전이라 혼자 해결할 수 있었지만 develop이나 master 브랜치에 잘못 올렸을 경우 소중한 작업물이 날아갈 수 있기 때문에 팀원과 상의해서 해야한다.
git log
git log 명령을 실행하면 아래와 같이 출력된다.
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
커밋 히스토리를 시간순으로 보여준다. 가장 최근 커밋이 가장 먼저 나온다.
그리고 이어서 각 커밋의 SHA-1 체크섬, 저자 이름, 저자 이메일, 커밋한 날짜, 커밋 메시지를 보여준다.
git log
옵션 중 oneline
옵션은 각 커밋을 한 라인으로 보여준다. 이 옵션은 많은 커밋을 한 번에 조회할 때 유용하다.
$ git log --oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
git reset --hard <식별id>
위의 예제에서 first commit 으로 돌아가고 싶으면 아래처럼 하면된다
git reset --hard a11bef06a3f659402fe7563abf99ad00de2209e6
hard는 인덱스와 작업 트리를 재설정한다. 이후 작업 트리에서 추적된 파일에 대한 모든 변경 사항 commit
은 무시된다. 작업한 파일이 모두 날아가므로 신중하게 해야한다.
git reset --soft <식별id>
헤드를 재설정하면서 인덱스 파일이나 작업 트리를 건드리지 않으려면 --hard
대신 --soft
를 사용하면 된다. 이렇게 하면 변경된 모든 파일이 커밋할 변경 사항(commit
전 add
상태)으로 남게 된다.
git push origin <브랜치명>
위 처럼 push
를 하면 아래와 같은 오류가 나타날 것이다.
힌트: 현재 브랜치의 끝이 리모트 브랜치보다 뒤에 있으므로 업데이트가
힌트: 거부되었습니다. 푸시하기 전에 ('git pull ...' 등 명령으로) 리모트
힌트: 변경 사항을 포함하십시오.
힌트: 자세한 정보는 'git push --help'의 "Note about fast-forwards' 부분을
힌트: 참고하십시오.
일반적으로 git push
는 덮어쓰는데 사용된 로컬 참조의 조상이 아닌 원격 참조 업데이트를 거부한다. -f
또는 --force
옵션은 원격 참조의 현재 값이 예상 값인 경우 이 제한을 무시한다. 지금 상황은 로컬 저장소의 히스토리를 원격 저장소의 히스토리에 강제로 덮어쓰는 것이므로 해당 옵션을 추가해야 한다.
git push -f origin <브랜치명>
이후 원격 저장소에서 커밋이 되돌려진걸 확인할 수 있다.
개인 브랜치가 아니라 master
브랜치 또는 develop
브랜치 등 다른 팀원과 공유해서 사용하는 브랜치에 이 방법을 사용하였을 경우, commit
을 되돌리기 전에 다른 팀원이 pull
받으면 다른 팀원의 로컬 저장소에 되돌린 커밋들이 남아있게 된다. 따라서 다른 팀원과 상의해서 되돌려야 한다.
공문을 읽다보니까 --force-with-lease
옵션이 있길래 force
와 어떤 차이점이 있는지 궁금해서 찾아보았다. stackoverflow에서 잘 정리해놓은 답변이 있었는데 아래와 같다.
force
원격 분기를 로컬 분기로 덮어쓴다
--force-with-lease
더 많은 커밋이 원격 분기에 추가된 경우(동료나 본인의 작업물) 원격 분기의 작업을 덮어쓰지 않는 더 안전한 옵션이다. 강제로 밀어 다른 사람의 작업을 덮어쓰지 않도록 한다.
다른 팀원과 공유되는 브랜치를 되돌릴 경우 --force-with-lease
옵션이 좀 더 안전하겠다.
해결했습니다 감사합니다!!