깃(git) stash 사용법, 새 파일까지 치우고 다시 꺼내 보니
깃 2.54.0에서 git stash를 직접 실행해 보면 고친 파일만 치워지고 새로 만든 파일은 그대로 남습니다. 새 파일까지 치우는 법, 급한 수정 뒤 다시 꺼내는 법, 이름을 붙여 저장하고 적용하고 지우는 법을 순서대로 정리했습니다.
Finn ·

새 저장소에서 README.md를 고치고 todo.txt를 새로 만든 채로 git stash를 실행해 보면, 고친 파일만 치워지고 ?? todo.txt는 작업 폴더에 그대로 남습니다. 깃 2.54.0에서 직접 실행해 보면 -u를 붙여야 새 파일까지 치워졌어요. 에이전트가 파일을 고치고 새로 만들던 중에 급한 수정이 끼어들었다면, 이 차이부터 알아 두는 게 좋습니다.
따라 할 순서 한눈에 보기
아래 순서를 그대로 따라 하면 됩니다. 명령과 출력은 다음 절부터 단계별로 하나씩 보여 드려요.
- 저장소를 만들고 첫 커밋을 남깁니다.
- 파일 하나를 고치고, 새 파일 하나를 만들어 작업 중인 상태를 만듭니다.
git stash로 고친 내용을 치웁니다. 새 파일은 남는 것을 확인합니다.git stash -u로 새 파일까지 치웁니다.- 다른 브랜치에서 급한 수정을 커밋하고
main에 합칩니다. git stash list로 목록을 보고git stash pop으로 다시 꺼냅니다.git stash push -u -m으로 이름을 붙여 저장하고,git stash apply로 꺼낸 뒤git stash drop으로 지웁니다.

함께 읽을 글
작업 중인 상태 만드는 방법
먼저 버전을 확인하고 연습용 저장소를 만듭니다. 작성자 이름과 메일은 --global 없이 이 저장소에만 적용했어요.
$ git --version
git version 2.54.0$ git init -q -b main && git config user.name "Finn" && git config user.email "lab@solodevnote.com" && printf '# 메모\n첫 줄\n' > README.md && git add README.md && git commit -q -m "첫 커밋" && git log --oneline
f8118dc 첫 커밋그다음 커밋된 파일에 줄을 하나 더하고, 새 파일도 만듭니다. git status --short에서 M은 추적 중인 파일이 바뀌었다는 뜻이고, ??는 아직 추적하지 않는 파일이라는 뜻입니다.
$ printf '고치던 줄\n' >> README.md && printf '할 일 1\n' > todo.txt && git status --short
M README.md
?? todo.txt그냥 치우면 새 파일은 왜 남나요?
이제 아무 옵션 없이 치워 봅니다. 인자 없는 git stash는 git stash push와 같습니다.
$ git stash && git status --short && git stash list
Saved working directory and index state WIP on main: f8118dc 첫 커밋
?? todo.txt
stash@{0}: WIP on main: f8118dc 첫 커밋README.md에 추가했던 줄은 치워지고 파일은 마지막 커밋 상태로 돌아왔지만, todo.txt는 그대로 남았죠. Git 공식 책 한국어판 7.3은 기본 git stash가 추적 중인 파일만 저장한다고 설명합니다. 그래서 아직 git add하지 않은 새 파일은 브랜치를 옮겨도 따라다닙니다. 에이전트가 새 모듈이나 테스트 파일을 만들어 둔 상태라면, 치운 뒤 git status --short로 남은 파일이 없는지 꼭 봐야 하는 이유예요.
새 파일까지 함께 치우는 방법
이럴 때는 -u(--include-untracked)를 붙입니다. git-stash 설명서에 따르면 추적하지 않는 파일까지 저장한 뒤 작업 폴더에서 정리합니다.
$ git stash -u && git status --short && git stash list
Saved working directory and index state WIP on main: f8118dc 첫 커밋
stash@{0}: WIP on main: f8118dc 첫 커밋
stash@{1}: WIP on main: f8118dc 첫 커밋git status --short가 아무것도 출력하지 않으니 작업 폴더가 깨끗해졌습니다. 그런데 목록을 보면 두 항목의 설명이 똑같습니다. 가장 최근 것이 stash@{0}, 그 전 것이 stash@{1}이라는 번호만 다르죠. 무엇이 어디 들었는지 헷갈리기 쉬우니, 뒤에서 이름을 붙이는 방법을 함께 봅니다.

급한 수정을 다른 브랜치에서 처리하는 순서
작업 폴더가 깨끗해졌으니 이제 급한 수정을 할 차례입니다. hotfix 브랜치를 만들어 제목을 고치고 커밋한 뒤, main으로 돌아와 합칩니다.
$ git switch -q -c hotfix && printf '# 메모 (급한 수정)\n첫 줄\n' > README.md && git commit -q -am "제목 급히 수정" && git switch -q main && git merge -q hotfix && git log --oneline
ffec0f7 제목 급히 수정
f8118dc 첫 커밋설명서의 '끊긴 작업 흐름' 예시도 같은 흐름입니다. 임시 브랜치에 WIP 커밋을 만들었다가 되돌리는 대신, 치우고 고치고 다시 꺼내는 세 동작으로 줄이는 거예요.
치워 둔 작업을 다시 꺼내는 방법
그럼 git stash pop은 정확히 무엇을 할까요? 목록에서 항목 하나를 빼서 지금 작업 폴더 위에 적용합니다. 이름을 주지 않으면 가장 최근 항목인 stash@{0}을 꺼내요. 여기서는 두 번 연달아 꺼냅니다.
$ git stash pop && git stash pop && git status --short && cat README.md && git stash list
이미 업데이트 상태입니다.
현재 브랜치 main
추적하지 않는 파일:
(커밋할 사항에 포함하려면 "git add <파일>..."을 사용하십시오)
todo.txt
커밋할 사항을 추가하지 않았지만 추적하지 않는 파일이 있습니다 (추적하려면 "git
add"를 사용하십시오)
Dropped refs/stash@{0} (11c3f4b19dfcda5333ebe40008b82c970efd949e)
자동 병합: README.md
현재 브랜치 main
커밋하도록 정하지 않은 변경 사항:
(무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
(use "git restore <file>..." to discard changes in working directory)
수정함: README.md
추적하지 않는 파일:
(커밋할 사항에 포함하려면 "git add <파일>..."을 사용하십시오)
todo.txt
커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)
Dropped refs/stash@{0} (bc3265c68026400d360ca4f93fa3e79730fb9a22)
M README.md
?? todo.txt
# 메모 (급한 수정)
첫 줄
고치던 줄첫 번째 꺼내기에서는 -u로 치운 항목이 나와 todo.txt만 돌아왔습니다. 두 번째에서는 자동 병합: README.md가 찍히고, 급한 수정의 제목 아래에 고치던 줄이 붙었어요. 마지막 git stash list는 아무것도 출력하지 않았으니 목록도 비었습니다.
| 시점 | 목록 | 작업 폴더 |
|---|---|---|
| 기본 stash 뒤 | stash@{0} | todo.txt만 남음 |
-u 뒤 | stash@{0}, stash@{1} | 깨끗함 |
| 두 번 꺼낸 뒤 | 비어 있음 | README.md 수정, todo.txt |

꺼낼 때 충돌이 나면 어떻게 되나요?
이번 실행에서는 자동 병합으로 끝났지만, 늘 그렇지는 않습니다. 설명서에 따르면 적용이 충돌로 실패하면 그 항목은 목록에서 지워지지 않습니다. 그래서 충돌을 손으로 해결한 뒤 git stash drop을 직접 실행해야 해요. 이때 apply, pop, branch는 종료 코드 1을 돌려줍니다.
치워 둔 뒤 브랜치가 많이 달라져 충돌이 난다면 git stash branch <브랜치>도 있습니다. 치울 당시의 커밋에서 새 브랜치를 만들어 적용하고, 성공하면 그 항목을 지워 줍니다. 에이전트에게 꺼내기를 맡긴다면, 종료 코드가 1인지부터 확인하게 하는 편이 안전합니다.
이름 붙여 저장하고 지우는 방법
설명이 똑같아 헷갈리던 문제는 -m으로 풉니다. 이번에는 apply로 꺼낸 다음 목록을 다시 보고, drop으로 지웠어요.
$ git stash push -u -m "할 일 정리 중" && git stash list && git stash apply stash@{0} && git stash list && git stash drop && git stash list && git status --short
Saved working directory and index state On main: 할 일 정리 중
stash@{0}: On main: 할 일 정리 중
현재 브랜치 main
커밋하도록 정하지 않은 변경 사항:
(무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
(use "git restore <file>..." to discard changes in working directory)
수정함: README.md
추적하지 않는 파일:
(커밋할 사항에 포함하려면 "git add <파일>..."을 사용하십시오)
todo.txt
커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)
stash@{0}: On main: 할 일 정리 중
Dropped refs/stash@{0} (84abb9c89c33b401b375c90bc4f503245277dba9)
M README.md
?? todo.txt목록 설명이 WIP on main 대신 On main: 할 일 정리 중으로 바뀌었습니다. 그리고 apply 뒤에도 항목이 그대로 남아 있다가, drop을 하고 나서야 사라졌죠. 두 명령의 차이를 표로 보면 이렇습니다.
| 명령 | 하는 일 | 목록에서 지워지나 |
|---|---|---|
git stash pop | 꺼내서 적용 | 성공하면 지움, 충돌하면 남김 |
git stash apply | 적용만 함 | 남김 |
git stash drop | 항목 하나를 지움 | 지움 |
또 하나, 꺼낼 때 스테이징 상태는 자동으로 돌아오지 않습니다. 원래대로 되돌리려면 --index를 붙이라고 공식 책은 설명합니다.
자주 하는 실수
- 옵션 없이 치우고 끝내기: 새 파일이 남아 다른 브랜치 커밋에 섞일 수 있습니다.
-u를 붙이세요. - 이름 없이 여러 번 치우기: 목록 설명이 똑같아져 번호로만 구별해야 합니다.
apply뒤에 지우지 않기: 같은 항목이 목록에 계속 쌓입니다.- 충돌 뒤 사라졌다고 착각하기: 충돌이 나면 항목은 남아 있으니, 해결한 뒤 직접 지워야 합니다.
git stash clear를 가볍게 쓰기: 모든 항목이 지워지고 복구가 불가능할 수 있습니다.- 계속
git stash save쓰기: 설명서는 이 명령을git stash push로 대체된 것(deprecated)으로 적고 있습니다.
마지막 점검 목록
- 치운 뒤
git status --short출력이 비었나요? git stash list에서 각 항목에 알아볼 만한 이름이 붙어 있나요?- 꺼낸 뒤 종료 코드가 0인가요? 1이면 충돌입니다.
apply로 꺼냈다면 확인 후git stash drop을 했나요?
측정 조건과 한계
이 기록은 맥 한 대(darwin arm64)의 깃 2.54.0에서 원격 저장소 없이 새 로컬 저장소 하나로 한 번씩 실행한 결과입니다. 깃 메시지는 맥의 한국어 설정대로 나왔어요. 단계마다 걸린 시간은 0.0초에서 0.1초였고, 종료 코드는 모두 0이었습니다.
그래서 충돌이 나는 경우, 스테이징한 변경을 --index로 되살리는 경우, 다른 운영체제는 직접 확인하지 않았습니다. 충돌 때의 동작은 설명서 내용을 옮긴 것이니, 중요한 작업이라면 연습용 저장소에서 같은 상황을 먼저 만들어 보세요. 설명서는 2.56.0에서 마지막으로 바뀌었으니 버전이 다르다면 git-stash 설명서를 함께 보는 편이 좋습니다.
참고 자료
- ... hack hack hack ... git-scm.com
- 7.3 Git 도구 - Stashing과 Cleaning git-scm.com