git을 통해서 프로젝트 버전 관리를 하는 도중에 실수로 push를 진행해서 remote repository (github)에 업데이트 되었다.
이를 취소하기 위해서 git push 등을 통해 repository에 업데이트 된 내용들을 취소하는 방법을 찾아보았다.
1. git add 취소하기
git add [file name] 명령어를 사용하는 경우 파일의 변경사항이 local의 index에 staging 상태로 올라가게 된다. 이때 reset 명령어를 사용해서 unstaging 상태로 원복할 수 있다.
$ git reset HEAD [file name]
입력된 file name에 대해서 staging 되어있는 변경사항이 unstaging 된다.
file name을 따로 입력하지 않는 경우에는 현재 staging 되어있는 모든 변경사항들이 unstaging 상태로 바뀌게 된다.
※ HEAD는 현재 branch를 가리키는 포인터이다. 현재 branch에 commit들 중에서 가장 마지막에 commit 된 상태를 가리키는데, 이 commit은 다음에 신규로 생성되는 commit의 부모가 된다.
2. git commit 취소하기
git commit 명령어를 통해서 local repository의 HEAD로 새로운 변경사항이 업데이트되게 된다. 이때 reset HEAD^를 통해서 원복할 수 있는데, 이때 몇가지 옵션을 사용할 수 있다. 각 옵션에 따라서 commit 취소 후 변경된 파일들의 상태를 다르게 할 수 있다.
// commit 원복 기본 명령어. default option은 --mixed이다.
$ git reset HEAD^
// commit을 취소하고 해당 파일들은 staged 상태로 워킹 디렉터리에 보존.
$ git reset --soft HEAD^
// commit을 취소하고 해당 파일들은 unstaged 상태로 워킹 디렉터리에 보존. git reset HEAD^의 기본 옵션
$ git reset --mixed HEAD^
// commit을 취소하고 해당 파일들은 unstaged 상태로 워킹 디렉터리에서 삭제
$ git reset --hard HEAD^
※ ^(tilde) vs ~(caret)
- git 명령어를 보다보면 위의 두 특수문자를 종종 만날 수 있다. ^(tilde)는 HEAD의 부모를, ~(caret)은 조상을 나타낸다.
- HEAD^n: HEAD의 부모가 여럿일 때, n번째 부모를 의미한다. n을 따로주지 않는 경우는 바로 전의 커밋(부모)를 나타낸다.
- HEAD~n: HEAD의 n번째 조상을 의미한다.
3. git push 취소하기
앞의 두경우와는 달리 push는 local이 아닌 remote에 덮어쓰기 하는 방법이기 때문에 사용시에 더욱 주의하여야 한다.
local의 commit을 원복하여 수정한 후 다시 remote에 commit하여 덮어쓰기 되도록 하는데, 이때 원복된 중간의 commit은 사라진다.
// 1. 마지막 commit을 취소한다.
$ git reset HEAD ^
// 2. 두개의 명령어 중 하나를 사용하여 git log를 확인한다.
$ git reflog
$ git log -g
// 3. git log를 확인하여 commit 상태의 번호나 id를 통해 원복한다.
$ git reset HEAD@{n} // n번 commit 으로 원복한다.
$ git reset [commit id] // commit id의 commit이 진행되었던 상태로 원복한다.
// 4. 되돌려진 상태를 새로 커밋한다.
$ git commit -m "new commit message"
// 5. git push force 옵션을 사용하여서 remote에 강제로 push 하도록 한다.
// ex) git push +master: master branch에 강제로 push한다.
$ git push origin [branch name] -f
$ git push origin +[branch name]
[reference]
- 7.7 Git 도구 - Reset 명확히 알고 가기
- [Git] git add 취소하기, git commit 취소하기, git push 취소하기
'기타 > Git' 카테고리의 다른 글
[git] git hooks / pre-commit (0) | 2023.02.03 |
---|---|
[git] git 브랜치 병합 전략 (merge, rebase) (0) | 2022.06.15 |
[git] git stash (0) | 2021.10.30 |
[git] squash로 commit 합치기 (0) | 2021.10.30 |
[git] git submodule / subtree (0) | 2021.10.19 |