오늘은 Git stash에 대해 정리해보려고 한다.
기존 작업을 하다가 갑자기 급한 오류 수정 요청이 들어오거나, 현재 작업보다 더 우선순위가 높은 작업이 새로 들어올 때가 있다. 그럴 때 다른 브랜치로 이동하려면 하면 현재 변경사항을 commit 하거나, stash 해야한다.
(git switch 혹은 checkout을 할 때 다음과 같은 메세지를 본 적이 있을 것이다!)
나는 작은 단위의 기능도 구현이 안됐을 때에는 '[feat] ~기능 구현 중'이렇게 커밋 메세지를 쓰곤 했는데,
나중에 보니까 좀 지저분한 느낌이 들어서 git stash를 사용하게 됐다.
📌 git stash란?
git stash는 변경사항을 임시로 저장할 수 있도록 도와주는 기능이다.
가장 기본적인 사용법은 git stash로 모든 변경사항을 임시저장하고,
git stash pop으로 다시 모두 꺼내오는 것이다.
좀 더 자세히 설명하면, 커밋되지 않은 변경사항을 스택에 쌓아두고, 이걸 다시 꺼내오는 것이다.
git stash 명령어를 사용한 뒤, 새로운 커밋이 추가된 상태에서 git stash pop을 할 수도 있고, 다른 브랜치에서 stash된 내용을 pop할 수도 있다. 하지만 다른 변경사항들과 충돌이 나는 경우에는 merge 충돌처럼 충돌을 해결해줘야 한다.
그럼 이제 관련 명령어를 알아보자.
📌 git stash 관련 명령어
git stash
git stash (save) 명령어는 staged 변경사항과 unsatged 변경사항을 모두 저장해준다.
(참고로, untracked file은 stash되지 않는다.)
git stash 명령어를 사용한 예시를 보면 다음과 같이 저장되었다는 메세지가 나오는데,
Saved working directory and index state WIP on [브랜치이름]: [최근커밋] 이렇게 나오는 것 같다.
$ git stash
Saved working directory and index state WIP on fix/profile-상세조회-image-오류-#131: 2ca226f [fix] 프로필 상세조회 image 수정
이렇게 하고 git status로 확인해보면 state가 깨끗한 것을 볼 수 있다. 이 상태로 브랜치를 옮기면 된다!
stash에 이름 설정을 설정하지 않으면 자동으로 일련번호가 부여되는데, 이게 싫다면 이름을 설정해 줄 수도 있다.
$ git stash save [stash 이름]
그리고 커밋과 마찬가지로 -m 옵션으로 변경사항에 메세지를 붙일 수 있다.
예시를 보면 브랜치이름 다음에 커밋 메세지가 쓰여있는 걸 확인할 수 있다!
$ git stash -m "article nation 수정"
Saved working directory and index state On fix/profile-상세조회-image-오류-#131: article nation 수정
git stash list
git stash list 명령어로 현재 저장소에 임시저장된 전체 목록을 확인할 수 있다.
여기서 stash@{0}이 해당 임시 변경사항의 이름이 되고, {0} 이 부분이 인덱스가 된다.
$ git stash list
stash@{0}: On fix/profile-상세조회-image-오류-#131: article nation 수정
여기서 새로운 내용을 추가로 stash하면, 새로 추가한 내용이 가장 위로 올라가고 인덱스가 {0}이 된다.
기존에 있던 내용들의 인덱스가 점점 뒤로 밀리는 형태이다.
$ git stash list # 초기 상태
stash@{0}: WIP on fix/#21-cors-error: 02f04e7 [Fix] cors 에러
$ git stash # 새로 추가
Saved working directory and index state WIP on feat/#27-get-preaList-API: a32b159 [Fix] 충돌 해결
$ git stash list
stash@{0}: WIP on feat/#27-get-preaList-API: a32b159 [Fix] 충돌 해결
stash@{1}: WIP on fix/#21-cors-error: 02f04e7 [Fix] cors 에러
git stash show
git stash show 명령어를 사용해 해당 임시 변경사항의 내용을 확인할 수 있다.
$ git stash show stash@{0}
wingle/src/main/java/kr/co/wingle/community/article/ArticleMapper.java | 1 +
.../src/main/java/kr/co/wingle/community/article/ArticleResponseDto.java | 1 +
2 files changed, 2 insertions(+)
git stash pop
git stash pop 명령어를 사용하면 stash된 내용을 꺼내올 수 있다.
자세히 말하면, stash@{0}인 변경사항(=가장 최근 stash)에 대해 다음 2가지 명령어를 수행하는 것과 같다.
- stash@{0}을 꺼냄 (git stash apply)
- stash@{0}을 삭제함 (git stash drop)
$ git stash pop
On branch refactor/댓글-테스트코드-작성-#99
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: wingle/src/test/java/kr/co/wingle/community/comment/CommentControllerTest.java
new file: wingle/src/test/java/kr/co/wingle/community/comment/CommentServiceTest.java
Dropped refs/stash@{0} (c2ebf948a410a7059eea550d091090119f151602)
여기서 특정 변경사항을 pop하고 싶다면 뒤에 stash 이름을 붙여주면 된다.
$ git stash pop stash@{1} # 예시
git stash pop은 stage 상태까지 복원되지는 않는다. (모두 unstaged로 복원된다.)
만약 stage 상태까지 복원하고 싶다면 --index 옵션을 사용하면 된다.
$ git stash pop --index
git stash apply
git stash apply 명령어는 변경사항을 꺼내오기만 한다. 즉, 스택에 삭제되지 않고 계속 남아있는다.
stash한 내용을 pop하기에는 불안할 때 사용하면 된다.
pop과 마찬가지로 stash 이름을 주거나 --index 옵션을 줄 수 있다.
$ git stash apply [stash 이름] [--index]
git stash apply로 변경사항을 꺼냈는데, 다시 되돌리고 싶을 때가 있다.
그럴 때는 아래 명령어를 사용하면 된다.
$ git stash show -p [stash 이름] | git apply --reverse # or
$ git stash show -p [stash 이름] | git apply -R
자세히 설명하자면, 가장 최근 (or 주어진 stash)를 사용해 패치를 만들고 이를 거꾸로 적용하는 과정이다.
git stash drop
git stash drop 명령어는 변경사항을 스택에서 삭제하기만 한다.
꺼내오지 않으니 주의하기 바란다.
$ git stash drop [stash 이름]
git stash clear
git stash clear 명령어는 stash 스택에 저장된 모든 변경사항을 한번에 삭제한다.
$ git stash clear
git stash branch
git stash branch 명령어는 변경사항을 반영한 새로운 브랜치를 만든다.
새로운 브랜치를 만들고 switch한 다음, stash된 내용을 pop한다.
$ git stash branch [branch 이름]