안녕하세요. 이번 시간에는 git restore 명령어에 대해 간단하게 알아봅시다. 사실 git status 명령어를 칠 때 마다 계속 이 명령어랑 add가 안내에 뜨길래 뭐 하는 것인가 싶어서 알아보게 되었어요.

 


 먼저 프로젝트의 구조는 위와 같습니다. 폴더 a 밑에 b.py와 1.txt가 있고, git_test 밑에 .gitignore, 1.txt, a.py, main.py, readme가 있습니다.

 

 수정하기 전 b.py는 1만 출력하는 문장만 있습니다.

 

 main.py에는 shutil.rmtree.avoid_symlink_attacks를 출력하는 부분만 있어요. 저는 local에서 main.py와 b.py와 1.txt를 바꾸었습니다. 아직 commit은 하지 않은 상태에요.

 

 

 b.py는 2를 출력하라는 문장이 추가되었어요.

 

 다음에 main.py에는 1을 출력하라는 문장만 있는 것으로 바뀌었습니다.

 

 

 1.txt에는 1이 추가되었습니다.

 

 git status를 통해서 보면, 변경이 되었는데, 아직 staged가 되지 않은 파일들이 3개가 있음을 볼 수 있어요. 1.txt, a/b.py, main.py 이렇게 3개인데요. git restore 명령을 쓰면, working directory에서의 change를 취소합니다.

 

 


 b.py를 예로 들어 설명해 보겠습니다. 처음에 b.py는 print('1')만 있는 상태였습니다.

 

 

 그런데 제가 b.py에 print('2')를 추가했어요. 그러니, working directory에는 print('1')과 print('2')가 있는 것이 올라갑니다. 이 변경을 discard 한다는 것은 변경 전에 print('1')만 있었던 상태로 되돌아 간다는 것입니다. 위 그림에서, 화살표 방향입니다. 즉, 내가 작업하고 있는 working directory에서 수정된 내용을 취소합니다. 돌려놓는다고 생각하면 편하겠습니다.

 

 이제, git restore *.py를 해 보겠습니다. 이것은 .py로 끝나는 패턴들의 파일에 대해서 working directory에 있는 변경사항들을 취소합니다. 해당 명령어를 입력한 후에, git status를 쳐 보면, modified에 1.txt만 있음을 확인할 수 있어요. main.py와 b.py의 내용을 보겠습니다.

 

 

 먼저 main.py에는 shutil.rmtree.avoid_symlink_attack의 값을 출력합니다. 변경 전의 내용이 복원되었습니다.

 

 

 다음에 b.py도 print('1')만 있습니다. 역시, 로컬의 working tree에서의 변경 사항이 버려졌음을 알 수 있습니다.

 


 commit 메세지가 res로 시작하는 커밋은 HEAD가 가리키고 있어요. 이 커밋의 3번째 이전인 변경 기록을 보니 BUSAN 밑에 무언가 추가된 기록이 있습니다. 그러면 1.txt가 hakata to tokyo nozomi, It's show time, BUSAN 이렇게 3줄만 나오게 하려면, HEAD로부터 4개 전으로 돌아가야 겠네요.

 

 

 --staged 옵션을 주면, 특정 커밋에서의 상태로 복구합니다. HEAD~4일 때 1.txt는 3개의 줄만 있던 파일이였습니다. 위와 같이 명령어를 입력하면, 1.txt는 어떻게 될까요?

 

 

 놀랍게도 HEAD로부터 4개 전 커밋에서의 1.txt로 복구되었음을 알 수 있습니다.