Git으로 프로젝트를 진행하다 보면, 커밋하기엔 아직 이르지만 지금까지 작업한 내용을 잠시 저장해 두고 싶은 순간이 찾아옵니다. 이럴 때 유용하게 쓸 수 있는 것이 바로 git stash 명령어입니다. 스태시(stash)를 활용하면 현재 작업 브랜치의 코드를 나중을 위해 안전하게 저장해 둘 수 있습니다. 이 글에서는 예제와 함께 Git 스태시의 기본 개념과 git stash 명령어의 다양한 사용법을 살펴보겠습니다.
Git 스태시(Stash)란 무엇인가?
스태시는 작업 디렉터리와 인덱스에 있는 변경 사항을 나중을 위해 저장하는 기능입니다. 코드를 작성하다 보면 지금까지 만든 변경 내용은 보관하고 싶지만, 아직 저장소에 커밋하고 싶지 않은 경우가 종종 생깁니다.
대표적인 예가 버그 수정 상황입니다. 새로운 기능을 개발하던 중에 버그 리포트가 접수되었다고 가정해 보겠습니다. 이때 기능 개발 코드를 먼저 스태시에 저장해 둔 뒤 버그 수정에 집중할 수 있습니다.
버그 수정이 대개 진행 중인 기능보다 우선순위가 높기 때문입니다. 기능 관련 코드를 커밋하기 전에 버그를 먼저 해결하는 것이 좋으며, 버그 수정과 기능 개발이 하나의 커밋에 섞이는 것은 피해야 합니다. 커밋이 크고 복잡할수록 다른 개발자가 저장소 히스토리를 파악하기 어려워지기 때문입니다.
즉, 스태시를 활용하면 기존 코드를 버리거나 억지로 커밋하지 않고도 다른 작업에 집중할 수 있습니다.
스태시는 파일에 가한 변경 사항을 '잠시 치워두는' 기능이라고 생각하면 됩니다. 파일을 스태시하면 다른 작업을 자유롭게 진행할 수 있고, 나중에 돌아와서 저장해 둔 변경 사항을 다시 코드에 적용할 수도 있습니다.
또한 스태시를 실행하면 현재 작업 디렉터리가 마지막 커밋 상태로 되돌아갑니다. 덕분에 깨끗한 작업 환경에서 코드를 수정할 수 있으며, 병합 충돌을 걱정하거나 커밋 간 변경 사항을 분류하는 번거로움 없이 작업에 몰입할 수 있습니다.
Git에서 변경 사항 스태시하는 방법
git stash 명령어는 코드를 나중을 위해 임시 저장할 때 사용합니다. 이 명령을 실행하면 현재 작업 디렉터리에서 아직 커밋되지 않은 변경 사항이 모두 저장됩니다. 여기에는 스테이징 영역에 추가된 변경 사항(git add로 등록한 것)과 스테이징되지 않은 변경 사항이 모두 포함됩니다.
명령어 문법은 다음과 같습니다:
git stash
예를 들어 웹사이트를 개발 중이고 코드가 Git 저장소에 관리되고 있다고 가정해 보겠습니다. index.html과 index.js 파일을 수정했고, 디자인 버그를 고치는 동안 이 변경 사항들을 잠시 저장해 두고 싶은 상황입니다.
먼저 git status 명령어로 현재 변경 사항을 확인해 보겠습니다:
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
new file: index.js
Changes not staged for commit:
modified: index.html
새 파일(index.js)을 생성했고, 기존 파일(index.html)을 수정했다는 것을 확인할 수 있습니다. 이제 다른 작업을 하기 위해 git stash 명령어로 변경 사항을 저장합니다:
git stash
실행 결과는 다음과 같습니다:
Saved working directory and index state WIP on master: 3b16026 feat: Launch new homepage
변경 사항이 성공적으로 저장되었습니다. 이후 git status를 다시 실행하면 커밋할 내용이 없다는 것을 확인할 수 있습니다:
On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean
코드가 스태시되면 저장소는 변경 사항이 없던 이전 커밋 상태로 되돌아갑니다. 작업했던 변경 사항은 사라진 것이 아니라 나중을 위해 저장된 것이며, 준비가 되면 git stash pop 명령어로 언제든 다시 적용할 수 있습니다.
추적되지 않는 파일 스태시하기
git stash 명령어는 기본적으로 이미 Git이 추적 중인 파일의 스테이징된 변경 사항과 스테이징되지 않은 변경 사항만 저장합니다. 즉, 한 번도 커밋된 적 없는 새 파일(untracked file)은 기본 설정으로는 스태시에 포함되지 않습니다.
추적되지 않는 새 파일이나 .gitignore로 무시되는 파일까지 함께 저장하려면 옵션 플래그를 사용해야 합니다. 추적되지 않는 파일을 포함하려면 -u 플래그를 사용합니다:
git stash -u
무시된(ignored) 파일까지 모두 포함하려면 -a 플래그를 사용합니다:
git stash -a
-a 플래그를 사용하면 .gitignore 파일에 정의된 파일들의 변경 사항까지 스태시에 포함됩니다.
git stash pop으로 저장된 변경 사항 적용하기
git stash pop 명령어는 스태시에 저장된 변경 사항을 저장소에 다시 적용할 때 사용합니다. 앞선 예제에서 저장해 둔 변경 사항을 적용하고 싶다면 다음 명령어를 실행하면 됩니다:
git stash pop
실행 결과는 다음과 같습니다:
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
new file: index.js
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (48afd55381cf43f2332f771349c7233fb99f80a6)
git stash pop을 실행하면 스태시에 있던 변경 사항이 로컬 작업 복사본에 적용됩니다. pop 명령어는 스태시의 코드를 저장소에 적용한 뒤 해당 스태시를 삭제합니다. 또한 적용된 변경 사항 목록도 함께 출력해 주므로, 어떤 내용이 스태시에 있었는지 쉽게 확인할 수 있습니다.
반면 스태시를 삭제하지 않고 변경 사항만 적용하고 싶다면 git stash apply 명령어를 사용하세요:
git stash apply
실행 결과는 다음과 같습니다:
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
new file: index.js
Changes not staged for commit:
modified: index.html
여러 브랜치에 걸쳐 변경 사항 적용하기
동일한 스태시 내용을 여러 브랜치에 적용하는 것도 스태시 명령어의 좋은 활용 사례입니다. 예를 들어 한 브랜치에 스태시를 적용한 뒤, 다른 브랜치로 이동하여 같은 스태시를 다시 적용할 수 있습니다. apply는 스태시를 삭제하지 않으므로 이런 반복 적용이 가능합니다.
여러 개의 스태시 관리하기
Git에서는 여러 개의 스태시를 만들 수 있습니다. 한 파일의 변경 사항을 스태시해 둔 상태에서, 다른 파일의 변경 사항을 별도의 스태시로 또 저장하는 식입니다.
스태시 목록 확인하기
저장소에 있는 스태시 목록을 조회하려면 다음 명령어를 실행합니다:
git stash list
지금까지 만든 모든 스태시를 조회하면 다음과 같은 결과가 출력됩니다:
stash@{0}: WIP on master: 3b16026 feat: Launch new homepage
stash@{1}: WIP on master: 3b16026 feat: Launch new homepage
그런데 위 결과처럼 스태시마다 기본 메시지만 표시되면, 어떤 스태시에 어떤 변경 사항이 들어 있는지 구분하기 어렵습니다. 이 문제는 스태시를 만들 때 직접 설명을 지정하면 해결할 수 있습니다:
git stash save "add new change to website"
실행 결과는 다음과 같습니다:
Saved working directory and index state On master: add new change to website
이제 스태시는 마지막 커밋 메시지 대신 우리가 지정한 고유한 설명을 갖게 됩니다.
특정 스태시 적용하기
git stash pop은 기본적으로 가장 최근의 스태시(stash@{0})를 적용합니다. 하지만 스태시가 여러 개일 때는 특정 스태시를 골라서 적용해야 할 때가 있습니다. 이때는 스태시의 고유 ID를 지정하면 됩니다.
예를 들어 stash@{1}에 저장된 변경 사항을 적용하고 싶다면 다음과 같이 실행합니다:
git stash pop stash@{1}
이 명령은 stash@{1}에 저장된 변경 사항을 저장소에 적용한 뒤 해당 스태시를 삭제합니다.
스태시로 새 브랜치 만들기
스태시는 다른 작업을 하는 동안 변경 사항을 편리하게 보관하는 방법입니다. 하지만 경우에 따라서는 스태시를 유지하는 대신, 해당 코드를 별도의 브랜치로 옮기고 싶을 수도 있습니다.
예를 들어 병합 시 충돌이 발생했거나, 코드베이스에 대한 변경 규모가 커서 독립적인 브랜치에서 작업하는 것이 좋다고 판단될 때 그렇습니다. 이럴 때 git stash branch 명령어를 사용하면 됩니다.
git stash branch는 새 브랜치를 생성하고, 스태시의 변경 사항을 그 브랜치에 적용합니다. 문법은 다음과 같습니다:
git stash branch <new-branch> <stash-id>
'new-branch'는 새로 생성할 브랜치 이름이고, 'stash-id'는 적용할 스태시의 ID입니다. 예를 들어 stash@{2}의 변경 사항을 'update-site'라는 새 브랜치에 적용하고 싶다면 다음과 같이 실행합니다:
git stash branch update-site stash@{2}
실행 결과는 다음과 같습니다:
Switched to a new branch 'update-site'
On branch update-site
Changes to be committed:
new file: index.js
Changes not staged for commit:
modified: index.html
Dropped stash@{2} (9a15b9cd20f8988937134d1267fafbea4c6a8647)
이 명령은 먼저 스태시된 변경 사항을 담을 새 브랜치를 생성하고, 변경 사항을 그 브랜치에 적용한 뒤 해당 브랜치로 전환합니다. 마지막으로 스태시된 코드가 자체 브랜치에 저장되었으므로 원래 스태시는 삭제됩니다.
Git 스태시 삭제하기
스태시의 코드를 더 이상 사용할 필요가 없다면 git stash drop 명령어로 삭제할 수 있습니다. 문법은 다음과 같습니다:
git stash drop <stash>
예를 들어 stash@{2}를 삭제하고 싶다면 다음과 같이 실행합니다:
git stash drop stash@{2}
실행 결과는 다음과 같습니다:
Dropped stash@{2} (82079798c950b053fac0efb7b1d5693864dc96e7)
저장소의 모든 스태시를 한 번에 삭제하고 싶다면 git stash clear 명령어를 사용하세요:
git stash clear
이 명령은 저장소에 있는 모든 스태시를 삭제합니다.
특정 파일만 스태시하기
git stash는 기본적으로 현재 작업 디렉터리의 추적 중인 모든 파일을 대상으로 동작합니다. 하지만 특정 파일 하나나 일부 파일만 스태시하고 싶은 경우도 있습니다.
이럴 때는 git stash push 명령어를 사용합니다. 문법은 다음과 같습니다:
git stash push -m "<message>" <file>
'message'는 스태시에 붙일 설명이고, 'file'은 스태시할 파일 이름입니다. 예를 들어 index.html 파일의 변경 사항만 스태시하고 싶다면 다음과 같이 실행합니다:
git stash push -m "feat: changed index.html file" index.html
실행 결과는 다음과 같습니다:
Saved working directory and index state On master: feat: changed index.html file
이 명령은 index.html 파일만 'feat: changed index.html file'이라는 메시지와 함께 스태시에 저장하며, 나머지 변경 사항은 그대로 작업 디렉터리에 남겨둡니다.
스태시 간 차이점 비교하기
스태시를 사용하다 보면, 저장해 둔 코드로 돌아오기 전에 여러 커밋을 거치며 코드베이스가 많이 바뀌는 경우가 많습니다.
예를 들어 코드를 스태시해 둔 채 버그를 수정하러 갔다면, 스태시로 돌아오기 전에 버그 수정 커밋을 여러 개 푸시했을 수 있습니다. 이때 스태시와 가장 최근 커밋 사이의 차이를 요약해서 확인하면, 스태시 이후 코드가 어떻게 변했는지 파악하는 데 큰 도움이 됩니다.
스태시와 최근 커밋의 차이를 확인하려면 git stash show 명령어를 사용합니다. 문법은 다음과 같습니다:
git stash show <stash-id>
예를 들어 stash@{1}의 내용을 현재 코드 상태와 비교하고 싶다면 다음과 같이 실행합니다:
git stash show stash@{1}
실행 결과는 다음과 같습니다:
index.html | 2 +- index.js | 0 2 files changed, 1 insertion(+), 1 deletion(-)
이 출력은 두 파일에 변경이 있었고, 한 줄이 추가되고 한 줄이 삭제되었음을 알려줍니다. 파일별 상세한 차이를 보고 싶다면 -p 플래그를 사용하세요:
git stash show -p stash@{1}
실행 결과는 다음과 같습니다:
diff --git a/index.html b/index.html index 4dd1ef7..e859c68 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -</div> +</html> diff --git a/index.js b/index.js new file mode 100644 index 0000000..e69de29
이 출력을 통해 스태시의 코드와 브랜치의 최근 커밋을 전체적으로 비교할 수 있습니다. 위 예제에서는 index.html 파일에서 </div> 줄이 삭제되고(- 기호) </html> 줄이 추가되었다(+ 기호)는 것을 확인할 수 있습니다.
마무리
git stash 명령어는 코드베이스에 가한 변경 사항을 임시로 저장해 주는 강력한 도구입니다. 작업이 끝난 뒤 언제든 돌아와서 저장해 둔 변경 사항을 다시 적용할 수 있습니다.
이 글에서는 Git 스태시의 기본 개념과 git stash 명령어의 핵심 사용법을 살펴보았습니다. 이제 여러분도 스태시를 자유자재로 활용하며 Git 전문가답게 코드를 관리할 준비가 되었습니다!