git stash 저장, 삭제, 취소, 복구, 내용 확인 등
이번 포스팅의 주제는 git stash
명령어입니다. git add, git commit 보다도 생각보다 자주 사용하게 되는 handy한 명령어인 만큼 잘 익혀 개발 생산성을 올려보세요.
1. git stash 란?
git stash
명령어는 현재 작업중인 변경사항들을 잠시 저장해두는 기능을 합니다.
이러한 임시 저장 기능이 유용한 이유는, 브랜치 변경 등 현재 변경 사항을 커밋해서 작업 트리가 깨끗할 때 만 실행할 수 있는 명령어들이 있기 때문입니다.
이럴 때 git stash
로 잠시 작업 상황을 임시 저장한 후, 여러 명령어를 처리하고 다시 돌아와 작업을 이어갈 수 있습니다.
우리가 git stash
명령어를 입력하면 Git은 현재 unstaged 상태의 변경 사항과 staged 되어 있는 변경 사항 (index) 를 모두 모아 새로운 stash object 로 저장합니다.
그런 다음 별도의 공간에 임시 저장하는데 이 공간의 이름이 stash
입니다.
stash가 실행되면 현재 브랜치는 직전 커밋 완료 상태가 됩니다. 이 상태에서는 거의 모든 Git 명령어를 자유롭게 사용할 수 있습니다.
이제 git stash
명령어를 사용하는 다양한 방법을 실제 예제와 함께 살펴보겠습니다.
2. push 명령어로 새로운 stash 생성
git stash
의 시작이 되는 push
명령어입니다. 이 명령어로 현재 변경 사항을 저장하며, 원한다면 이 stash 를 구별할 수 있도록 별도의 message 도 입력할 수 있습니다.
이전에는 git stash save
명령어를 사용했는데, 많은 기능들이 추가된 git stash push
명령어가 새로 추가되었습니다.
그래서 이제는 push
명령어를 사용합니다.
push
명령어를 통해 추가된 대표적인 기능은 untracked files, all files, 그리고 특정 파일 혹은 디렉토리를 지정해 stash를 실행하는 것입니다.
다음과 같이 사용합니다.
$ git stash push -m [message]
실행 결과를 보겠습니다.
위에서부터 보겠습니다. 1.md
파일에 새 변경 사항을 추가하니 git switch
명령어가 abort 되었습니다.
Git은 switch하고 싶으면 commit 혹은 stash 하라고 조언합니다.
git stash
명령어로 stash 하니 working tree 가 깨끗해졌고 git switch
명령어를 실행할 수 있게 되었습니다.
push
명령어는 -u
옵션으로 untracked 파일을 포함해서, -a
옵션으로 ignored 파일까지 모두 포함해서 stash에 저장할 수 있습니다.
또한, 아래와 같이, 특정 파일 혹은 디렉토리 이름을 입력해서 저장할 수도 있습니다.
위에서 본 예제와 달리 -m
옵션으로 메시지를 입력하지 않으니, Git에서 커밋 ID를 가진 메시지를 알아서 생성해준 것도 확인할 수 있습니다.
3. list 명령어로 stash 목록 조회
직전 예제에서 잠깐 보았듯이 list
명령어는 저장한 stash 목록을 보여줍니다.
모든 브랜치에서 만든 stash를 모두 조회하며, 최근에 저장할수록 0
에 가까운 번호로 등록되어 있습니다.
명령어는 다음과 같이 사용할 수 있습니다.
$ git stash list
main
브랜치와 develop
브랜치에서 stash 를 하나씩 더 생성한 후 list
명령어를 실행해보겠습니다.
git stash list
명령어는 총 3개의 stash 목록을 보여주고 있습니다.
우리가 develop
브랜치에서 2개의 stash를 메시지 없이 저장하니 목록만 보고서는 변경사항이 무엇인지 알 수 없게 되었습니다.
이런 경우를 대비해 push
명령어의 -m
옵션을 잊지 맙시다.
4. show -p 명령어로stash 내용 보기
방금 전 보았던 예제처럼 stash list 만 보고서는, 각 stash에 어떤 변경 사항이 저장되어 있는지 모르는 경우도 발생할 수 있습니다.
이럴 때 유용하게 사용할 수 있는 명령어가 show -p
입니다.
show
명령어는 stash에 저장된 변경사항에 해당하는 파일명과 수정된 라인 수만 간단하게 알려줍니다.
-p
옵션을 붙아면 git diff
명령어를 실행해서 파일 내부에 변경사항까지 상세하게 알려줍니다.
명령어는 다음과 같습니다. [stash-number]
를 입력하지 않으면 자동으로 가장 최근인 0
번 stash를 대상으로 실행합니다.
$ git stash show -p [stash-number]
실행 결과는 알아보기 위해 2.md
파일에 새로운 내용을 추가하고 push
명령어를 입력합니다.
이제 show
명령어를 입력합니다.
위와 같이,-p
옵션의 여부에 따라, 출력 내용이 달라집니다.
5. apply 명령어로 stash 복구
push
명령어를 통해 stash를 저장하고 모든 작업을 마친 후에는, 저장해 둔 변경사항을 되돌리기 위한 작업을 해야 합니다.
이 작업을 위해서는 apply
명령어와 pop
명령어를 사용할 수 있습니다.
이 중 apply
명령어는 stash 복구 후에도 저장된 stash가 삭제되지 않고 남아있습니다.
명령어는 다음과 같습니다. [stash-number]
를 입력하지 않으면 자동으로 가장 최근인 0번 stash를 대상으로 실행합니다.
$ git stash apply [stash-number]
실행 결과로 보여드리겠습니다.
for stash
라는 메시지를 가진 stash 를 저장한 후, apply
명령어로 가져왔습니다. apply
명령어는 git status
명령어를 실행해
현재 작업 트리의 상황을 보여줍니다.
apply
이후에 stash list 를 확인하면, 복구한 stash가 아직 남아 있는 것을 확인할 수 있습니다.
6. pop 명령어로 stash 복구 후 삭제
pop
명령어도 apply
명령어처럼 임시 저장한 변경 사항을 되돌리기 위한 명령어이며, 복구한 다음 기존 stash 를 삭제합니다.
명령어는 다음과 같으며, 역시 [stash-number]
를 입력하지 않으면 자동으로 가장 최근인 0
번 stash를 대상으로 실행합니다.
$ git stash drop [stash-number]
실행하면 다음과 같습니다.
이번에도 for stash 이라는 메시지를 가진 stash를 push했습니다. 이후 pop
명령어로 변경사항을 복구했고 apply
명령어를 입력했을 때와 같은 출력 메시지를 받았습니다.
1가지 차이점은 해당 stash가 삭제되어 더이상 stash 목록에 나타나지 않는다는 점입니다.
7. drop 혹은 clear 명령어로 stash 적용하지 않고 제거 list 삭제
drop
명령어는 특정 stash의 변경사항을 작업 트리에 되돌리지 않고 삭제하는 명령어입니다.
다음과 같은 명령어로 사용하며, [stash-number]
를 입력하지 않아면 자동으로 가장 최근인 0번 stash를 대상으로 실행합니다.
$ git stash drop [stash-number]
pop
명령어의 실행 결과를 보겠습니다.
0번이었던 for stash
메시지의 stash가 제거 완료된 것을 확인할 수 있습니다.
만약 더 이상 stash 목록의 모든 stash가 필요하지 않게 되어 삭제하고 싶다면, clear
명령어로 한 번에 삭제가 가능합니다.
명령어는 다음과 같습니다.
$ git stash clear
다음과 같이, 간단하게 실행할 수 있습니다.
clear
명령어 실행 후 stash 목록이 모두 제거되었습니다.
8. stash branch 명령어로 현재 변경 사항을 새 브랜치로 이동하는 방법
때로는, 현재 브랜치에서 작업을 하던 변경 사항을 모두 새 브랜치에 옮겨서 해당 브랜치에서 작업을 해야 하는 경우가 있습니다.
위 작업은 git add 명령어와 git checkout/git switch 명령어 조합으로 완료할 수 있습니다.
그런데 git stash branch
명령어는 이 작업을 명령어 하나로 가능하게 합니다.
아래 명령어를 사용하며,[stash-number]
를 입력하지 않아면 자동으로 가장 최근인 0번 stash를 대상으로 실행합니다.
$ git stash branch [new-branch-name] [stash-number]
그리고 다음과 같이 실행하면 됩니다.
9. 마치며
많은 Git 커맨드가 커밋 완료 상태에서 실행되기 때문에, git stash
명령어는 매일 손이 가는 명령어 중 하나입니다.
이 포스팅이 매일의 개발 생산성을 높이는 데 도움이 되었으면 좋겠습니다.