Git 커밋&푸쉬 되돌리기/ 삭제 하기 총정리
다음과 같은 내용을 다룬다.
- 로컬 저장소 커밋 삭제
- 원격 저장소 커밋 삭제
- 맨 마지막에 예제 있음.
Head 란?
현재 위치해 있는 커밋을 가리키는 식별자.
HEAD가 커밋을 가르킬 때는 브랜치를 통해서 가리키는데 아래 그림이 예시다.
(GitBash에서 $ git log 를 치면 나온다.)
현재 HEAD가 4번째 커밋을 가리키고 있다. (HEAD -> master, origin/master)
커밋 삭제 명령어
Git에서 커밋을 삭제 한 후에는 복구가 안되므로 신중하게 해야 한다.
이제부터 커밋 되돌리기/ 삭제 예시는 위에 git log 그림 이다.
reset
$ git reset HEAD^
바로 이전 커밋으로 돌아감.
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 3번째 커밋
$ git reset HEAD~n
최근 n개의 커밋 삭제
ex) n = 2
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 2번째 커밋
reset 옵션 사용
$ git reset --옵션 돌아갈 커밋 아이디
--옵션 : --mixed, --soft, --hard
돌아갈 커밋 아이디 : 커밋 아이디 입력
4번 째 커밋 에서 2번 째 커밋으로 이동한다고 했을 때 3가지 옵션의 차이점은 아래 그림과 같다.
--soft : Head가 2 번째 커밋을 가리킴. Staging Area, Working Directory는 원래 커밋으로 유지.
--mixed : Head가 2 번째 커밋을 가리킴. Working Directory만 원래 커밋으로 유지.
--hard : Head가 2 번째 커밋을 가리킴. Staging Area, Working Directory가 2번째 커밋으로 변경.
1. --soft
$ git reset --soft 돌아갈 커밋 아이디
커밋을 되돌린 후 또 다시 커밋을 할 때 add 없이 바로 commit 하면 코드 반영됨.(이해 안되면 아래쪽에 예제 있음)
ex) 돌아갈 커밋 아이디 = 2번째 커밋
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 2번째 커밋
2. --mixed
$ git reset --mixed 돌아갈 커밋 아이디
unstage 상태로 코드가 남아 있으므로 코드를 반영하려면 add 명령어 사용하여 stage 반영 후 commit(이해 안되면 아래쪽에 예제 있음)
ex) 돌아갈 커밋 아이디 = 2번째 커밋
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 2번째 커밋
3. --hard
$ git reset --hard 돌아갈 커밋 아이디
현재 브랜치를 지정한 커밋으로 옮긴 후 해당 커밋의 내용을 작업폴더에 반영.
Working Directory가 두 번째 커밋 상태로 변경 되므로 복구가 불가능 하다. 그러므로 항상 신중하게 사용해야 한다.
ex) 돌아갈 커밋 아이디 = 2번째 커밋
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 2번째 커밋
$ git reset --hard HEAD^
최근 커밋 삭제 + 복구 불가능
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 3번째 커밋
$ git reset --hard HEAD~n
최근 n개의 커밋 삭제 + 복구 불가능
ex) n=2
현재 : HEAD -> 4번째 커밋
실행 : HEAD -> 2번째 커밋
원격 저장소(Github) 커밋 삭제
원격 저장소의 커밋 삭제 명령어는 없다.
push를 해서 원격 저장소를 갱신 해야한다. 아래 명령어가 일반적인 푸쉬 명령어다.
$ git push origin master
하지만 로컬 저장소와 원격 저장소의 히스토리가 뒤죽박죽되면 일반적인 푸쉬 명령어로 했을 때 오류가 발생 할 수 있다. 오류가 발생하면 강제로 푸쉬를 해줘야한다.(아래 명령어)
$ git push -f origin master
revert
reset은 이전 커밋을 다 삭제 했다면 revert는 이전의 커밋 내역을 남겨두고 새로운 커밋 을 생성하면서 과거로 돌아간다. 되돌렸다는 이력이 남아 유지보수 차원에서 reset보다 좋다.
revert 할때는 바로 직전의 커밋 버전으로만 돌아 갈수 있다. 예를 들어 현재 4번째 커밋 이라면 3번째 커밋으로 돌아 가서 3번째 커밋에서 부터 커밋을 할 수 있다.
현재 커밋인 4번째 커밋이 아닌 3번째, 2번째, 1번째 커밋을 revert 하려 하면 에러가 발생한다.
$ git revert 현재 커밋 아이디
위에 명령어를 실행하면 reset -- soft, reset --mixed와 같은 결과지만 log 가 아래 그림 처럼 남는다.
revert "2번 째 커밋"
4번 째 커밋
3번 째 커밋
2번 째 커밋
초기 커밋.
|
cs |
마치며
여러 명에서 원격 저장소를 사용 할 경우 reset을 쓰면 오류가 발생하거나 커밋이 뒤죽박죽 될 수 있다. 그래서 revert를 사용 한다.
하지만 혼자서 원격 저장소를 사용하거나 브랜치를 혼자서 쓴다면 reset을 사용해도된다.
위에서 말했듯 한번 reset --hard 명령어는 복구가 불가능 하니 신중하게 사용해야 한다.
사용 예제
reset, revert 명령어를 실행을 해봤다.
각각의 명령어를 사용하여 되돌렸을 때 몇 번째 커밋으로 가는지 확인 하면된다.
reset 예제는 아래 저럼 visual studio에서 커밋&푸쉬를 했다. (실수로 3번째 커밋을 2번 했으니 착오 없이 봐주길.)
◇ $ git reset HEAD^
● 가장 최신의 커밋을 되돌린다.
현재 HAED-> 10번째 커밋
명령문 실행
9번째 커밋으로 되돌아 갔다.
◇ $ git reset HEAD~n
● n 번째 버전으로 돌아감.
현재 HEAD -> 9번째 커밋
n = 2 를 넣는다.
7번째 커밋으로 되돌아갔다.
◇ $ git reset --soft 돌아갈 커밋 아이디
● 원하는 버전으로 되돌아가기(위에 soft, mixed, hard 차이 그림 이해하면 좋음.)
현재 : HEAD ->7번째 커밋
6번째 커밋으로 돌아가보자.
6번째 커밋 아이디 입력 후 실행.
6번째 커밋으로 돌아갔다.
이제 코드를 수정하고 새로운 커밋을 한다고 치자. 저장소를 생성한 visual studio로 들어간다.
'int b;' 추가 -> 저장.
git bash로 와서 커밋 해보자.(add 필요 x, soft와 mixed의 차이)
정상적으로 커밋이 된다.
◇ $ git reset --mixed 돌아갈 커밋 아이디
● 원하는 버전으로 되돌아가기(위에 soft, mixed, hard 차이 그림 이해하면 좋음.)
현재 : HAED -> 7번째 커밋
5번째로 돌아가보자. (돌아가는 것은 soft와 차이가 없다.)
5번째 커밋 아이디 입력 후 실행.
5번째 커밋으로 돌아왔다.
코드를 수정하고 새로운 커밋을 한다고 치자. 저장소를 생성한 visual studio로 들어간다.
'int c;'를 추가 -> 저장 해준다.
이제 커밋 해보자.
오류가 뜬다. soft와 달리 mixed는 staging Area 에 현재 다른 버전이 있기 때문에 stage(add)를 해줘야 한다.
커밋 하기전 코드를 수정한 cpp 파일을 add해주자.
이제 커밋이 정상적으로 된다.
git log 확인 하니 6번째로 커밋이 됐다.
◇ $ git reset --hard 돌아갈 커밋 아이디
● 원하는 버전으로 되돌아가기(이전 버전 이력, 내용 다 삭제 즉 복구 불가)
현재 : HEAD -> 6번째 커밋
5번째 커밋으로 돌아가보자.
5번째 커밋 아이디 입력 후 실행.
5번째 커밋으로 돌아왔다.
◇ $ git reset --hard HEAD~n
● 최근 n개의 커밋으로 되돌아가기(이전 버전 이력, 내용 다 삭제 즉 복구 불가)
현재 : HEAD -> 5번째 커밋
n = 2 를 넣어서 실행.
3번째 커밋으로 돌아왔다.
◇ $ git push -f origin master
● 강제로 커밋 내용 Push 하기
reset을 한 상태에서 일반적인 push를 해보자.
$ git push origin master
오류가 발생 할 거다. 로컬 저장소와 원격 저장소의 히스토리가 섞이면 오류가 발생을 한다.
일반적인 push 명령어가 안되면 아래 명령어를 사용하여 강제로 푸쉬하면 된다.
$ git push -f origin master
정상적으로 푸쉬가 됐다.
github 사이트에 들어가니 정상적으로 푸쉬가 됐다.(3번째 커밋 실수로 2번 커밋함)
◇ $ git revert 돌아갈 커밋 아이디
● 히스토리 기록 남기고 되돌리기(바로 전으로만 돌아 갈 수 있음) 헷갈리는 부분이니 잘 보셈.
revert는 바로 이전 커밋으로만 되돌릴 수 있다.
현재 : HEAD-> 3번째 커밋
바로 이전인 2번째 커밋으로 되돌리기 위해서 현재 커밋인 3번째 커밋의 아이디를 입력해야 한다.
3번째 커밋 아이디 입력 후 실행.
실행하면 이와 같은 화면이 나온다. 이 창을 종료.
git bash다시 실행해서 $ git log 명령어 입력해보면 Revert "3번째 커밋"이라고 뜬다.
현재 두번째 커밋으로 되돌아 간 상태다.