앞서 git 명령어 블로그 포스팅에 이어서 시작하겠습니다.

이전 블로그 내용이 궁금하시면 다음 링크 (새창)선택하셔서 확인하시면 되겠습니다.



git revert: 공개된 commit의 변경 내역을 되돌립니다.

이미 공개된 commit 내역을 수정하는것은 매우 risk가 큽니다. 할 수는 있긴있으나 정말 웬만하면 하지마세요. 하지만 안전하게 변경내역을 되돌리는 방법이 있습니다. commit으로 발생한 변경 내역의 반대 commit을 하면됩니다. 다시말하자면, 추가했던 코드는 빼고, 지운 코드는 다시 추가하는 commit을 하는 것입니다. 이를 수행하는 명령어가 바로 git revert 입니다. 아래와 같이 사용합니다.


$ git revert 커밋SHA-1체크섬값


이 명령을 특정 지점의 commit SHA-1 체크섬 값을 입력하면 해당 지점까지 변경내역을 취소하게 됩니다. 먼저 가장 최근 commit 변경 내역을 되돌려 보겠습니다. 먼저 아래와 같이 명령을 칩니다.


$ git log -5


가장 최근것을 취소해보도록하게습니다. SHA값은 b92c이군요. 아래와 같이 명령 입력합니다.

$ git revert b92c

vim 창이 등장하면서 commit 메세지를 수정하게됩니다. 원래 '원래메세지' + revert가 추가된것을 확인하실 수 있습니다. 저는 그상태로 저장하고 끝냈습니다. 되돌리기가 완료되었습니다. 실제 파일 내용을 확인해보면 추가했던것이 사라진것을 확인하실 수 있어요.


그런데 정말 fact는 실제로 되돌리는것이아니라, 되돌리는 것같은 효과를 낸다는 것입니다. git revert를 실행한 시점부터, 대상 commit까지 변경내역을 거꾸로 적용하는 새로운 commit을 만드는 것입니다. 



 Com0 -> com1 -> com2 -> com3 -> com4 -> com5

com2, com3, com4를 지우고 싶어서 revert com2를 한경우 com5라는 commit이 생성되면서 com1로 되돌아 간것같은 효과가 납니다.


git commit -3을 하면, revert를 하기전의 commit 내역 역시 존재하는것을 확인하실 수 있습니다. 이미 공개된 commit 내역은 이런 안전한 방법으로 되돌려야 합니다.

.


git reset: 이전 작업 결과를 저장한 상태로 되돌립니다.


git reset 명령은 어떤 특정 commit을 사용하지않게 되어 다시 되돌릴떄 사용합니다. git revert명령이 이전 commit을 남겨두는 명령이었다면 git reset명령은 이전 commit을 남기지않고 새로운 commit을 남긴다는 차이가 있습니다. git reset명령은 현재 commit인 HEAD의 위치, 인덱스, 작업하는 저장소 디렉터리 등도 함께 되돌릴리를 선택하기 위한 모드를 지정할 수 있습니다. 아래의 표를 참고하시면 되겠습니다.


git reset 명령 모드

 모드

의미 

HEAD 위치 

인덱스 

저장소 디렉토리 

 hard

완전히 되돌립니다. 

변경 

변경 

변경 

mixed 

인덱스 상태를되돌림. 모드를 지정하지 않았을때의 기본값입니다. 

변경 

변경 

변경 안함 

soft 

커밋만 되돌립니다. 

변경 

변경 안함 

변경 안함 


인덱스는 실제 commit 전 변경 내역을 담는 준비 영역입니다. git add 명령을 실행했을 때 이영억으로 이동하게 됩니다. 저장소 디렉토리는 실제 파일이 담겨있는 작업영역을 의미한답니다.



git reset 명령 옵션

 ^ 혹은~

~ 은 커밋내역 하나를 의미합니다. 표시한 수 만큼 커밋을 되돌립니다. 하나면 최종 커밋내역일 것이고 두개면 최종 커밋내역과 바로 전 커밋 내역이 됩니다.

 ORIG_HAED

 git reset명령을 실행했을 때 지운 커밋 내역을 보관합니다. 해당 명령을 통해 git reset 명령으로 지운 커밋을 되돌릴 수 있습니다.

 

 


최근 commit의 세번째 commit까지, 그리고 commit만 되돌려보기 위해 soft모드를 사용하겠습니다. git log -5명령 실행해서 최근 다섯개의 commit내역을 확인합니다. 그리고 아래와 같이 명령을 실행합니다.


~은 커밋내역 하나를 의미한다고 했습니다.

$ git reset --soft HEAD~~~

명령을 수행하고 아무 결과가 나타나지않습니다. 하지만 git log -3 명령을 실행해보면 가장 최근 commit이 바뀐것도 확인하실 수 있습니다. 또한 cat hello.py명령을 실행해보면 실제로 파일 내용이 바뀐것이 아님을 알 수 있습니다.


아래와 같이 명령을 쳐서 reset으로 날린 commit을 다시 원래 상태로 되돌리겠습니다.


$ git reset --hard ORIG_HEAD

위와 같이 명령을 치시고 다시 git log -5를 하면 commit내역이 돌아온것을 확인하실 수 있습니다.


음 커밋은 reset되었는데 commit이랑 다르게 파일은 그대로 보관되는것을 확인하실 수 있었죠? 이제는 hard모드로 진행해보도록 하겠습니다.


$ git reset --hard HEAD~~~

현재 HEAD의 위치를 알려줍니다. 

$ cat hello.py

파일 내용이 바뀐것을 알 수 있습니다.

$ git log -3 

역시 커밋내역이 위와 동일하게 사라졌음을 알 수 있습니다. 커밋과 함께 파일내역 수정된것도 반영되어 되돌아갔음을 확인하실 수 있습니다.


자 다시 되돌립시다.

$ git reset --hard ORIG_HEAD


git checkout head -- filename : 특정파일을 최종 commit 시점으로 되돌립니다.

이번에는 파일 하나를 대상으로 변경 내역을 통째로 원래대로(변경직전의 최종커밋시점으로) 되돌릴떄 사용할 수 있는 유용한 명령을 보도록 하겠습니다.


$ git checkout HEAD -- 파일이름

위 명령을 실행하면 파일이름 파일의 내용이 최종 commit 시점으로 되돌아 가게됩니다 "--"는 포함하는 것이 좋습니다. git checkout 명령에 뒤따라 오는 것이 파일이라는 것을 확실하게 해주는 것이라는 표시입니다. 만약 --가 없다면, 파일 이름이 브랜치 이름과 같을 경우 해당 브랜치로 checkout하거나, 특정 commit 시점으로 저장소 전체가 되돌아 갈 수 있습니다.


아래서부터는 README.md 파일을 다루겠습니다. vim README.md 명령 실행하고 파일에 수정사항을 둡니다. git checkout HEAD TEST 라고 쓰겠습니다.

그리고 아래와 같이 실행합니다. 아래와 같이 명령을 실행하면 인덱스에 변경 내역을 저장하게 됩니다.

$ git add README.md

git status명령을 실행해보면 commit할 내역이 있다고 알려줍니다. 이제 아래와 같은 명열을 실행합니다. 음 아무런 표시가 안뜨는군요


$ git checkout HEAD -- README.md


자 아래와 같은 명령을 수행해서 확인해보겠습니다.

$ cat README.md

원래대로 돌아갔음을 확인하실 수 있습니다.

아래와 같이 명령을 치면 또한 commit할 내역이 없음을 확인할수있습니다.

$ git status


git checkout -- 파일이름 명령은 git add 파일이름 명령을 실행한 후 추가 수정사항이 있을때 [$ git add 파일이름] 명령을 실행한 상태로 되돌리는 명령입니다. HEAD가 빠져있음을 확인하세요~!


git reset역시 파일하나를 되돌릴 수 있는것처럼 설명되어있는데요. 하지만 다른점이있습니다. git reset명령은 hard모드가 아니라면 저장소 디렉터리의 파일 내용은 명령을 실행한 시점 그대로 남습니다. git reset명령으로 되돌린다음 필요한 부분만 수정작업하고 다시 commit할 수 있습니다. 하지만 git checkout은 파일을 완전하게 대상 commit 시점으로 되돌립니다. 파일 내용이 대상 commit시점으로 완전하게 되돌아 가는것입니다. 즉 git reset명령의 hard모드를 실행한것처럼 index와 작업전부를 되돌리게 됩니다. 




+ Recent posts