Git Stash

작업 중인 변경사항을 임시 저장하고 나중에 복원하기

Git Stash를 사용하여 작업 중인 변경사항을 임시로 저장하고, 다른 작업을 수행한 후 원래 작업으로 돌아오는 방법을 설명한다. stash의 기본 사용법부터 여러 stash 관리, 브랜치 활용까지 다룬다.

Engineering
Git
DevOps
저자

Kwangmin Kim

공개

2023년 05월 10일

1 Stash란?

작업 도중 급히 다른 브랜치로 전환해야 하는 상황이 있다:

  • 긴급 버그 수정 요청이 들어왔다
  • 코드 리뷰를 위해 다른 브랜치를 확인해야 한다
  • 현재 작업은 아직 커밋할 단계가 아니다

이때 Stash를 사용하면 현재 변경사항을 임시로 저장하고, 나중에 다시 꺼내올 수 있다.

Working Directory (작업 중)
       ↓ git stash
Stash Stack (임시 저장)
       ↓ git stash pop
Working Directory (복원)

2 기본 사용법

2.1 변경사항 임시 저장

# 현재 변경사항을 stash에 저장
git stash
Saved working directory and index state WIP on feature/login: abc1234 로그인 폼 추가

WIP on <브랜치>: <해시> <마지막 커밋 메시지> 형식으로 저장됐음을 알린다.

# 메시지와 함께 저장 (나중에 구분하기 쉬움)
git stash push -m "로그인 기능 작업 중"
Saved working directory and index state On feature/login: 로그인 기능 작업 중

-m 옵션을 사용하면 WIP on ... 대신 지정한 메시지가 표시된다. 나중에 git stash list 에서 구분이 쉬워진다.

2.2 저장된 stash 확인

git stash list
stash@{0}: On feature/login: 로그인 기능 작업 중
stash@{1}: WIP on main: def5678 메인 페이지 수정 중

stash@{0} 이 가장 최근에 저장된 항목이다. 숫자가 작을수록 최신이다.

2.3 변경사항 복원

# 가장 최근 stash를 복원하고 stash 목록에서 제거
git stash pop
On branch feature/login
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
        modified:   src/login.js

Dropped stash@{0} (7d9b3a2c4f1e8b5d6c7a8f9e0b1d2c3a)

복원된 파일 목록과 함께 Dropped stash@{0} 이 출력되면 stash 목록에서 제거된 것이다.

# 가장 최근 stash를 복원하되 stash 목록에서 제거하지 않음
git stash apply
On branch feature/login
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
        modified:   src/login.js

Dropped 줄이 없으면 stash가 목록에 그대로 남아 있는 것이다. git stash list 로 확인하면 여전히 stash@{0} 이 보인다.

pop vs apply:

명령어 복원 stash 목록에서 제거
git stash pop O O
git stash apply O X (유지)

apply는 여러 브랜치에 같은 변경사항을 적용하고 싶을 때 유용하다.

2.4 stash 삭제

# 특정 stash 삭제
git stash drop stash@{0}
Dropped stash@{0} (7d9b3a2c4f1e8b5d6c7a8f9e0b1d2c3a)
# 모든 stash 삭제
git stash clear

성공 시 아무 출력도 없다.

3 Stash 고급 사용법

3.1 추적되지 않는 파일도 함께 stash

기본적으로 git stash추적 중인 파일의 변경사항만 저장한다. 새로 생성한 파일(untracked)도 함께 저장하려면:

# 추적되지 않는 파일도 포함
git stash -u
# 또는
git stash --include-untracked

# .gitignore에 포함된 파일까지 모두 저장
git stash -a
# 또는
git stash --all

3.2 stash 내용 확인

# stash에 포함된 파일 목록 확인
git stash show
 src/login.js | 12 ++++++------
 src/utils.py |  5 +++++
 2 files changed, 11 insertions(+), 6 deletions(-)
# stash에 포함된 변경사항 상세 확인 (diff)
git stash show -p
diff --git a/src/login.js b/src/login.js
index a1b2c3d..e4f5g6h 100644
--- a/src/login.js
+++ b/src/login.js
@@ -10,6 +10,12 @@ function login() {
+  const token = generateToken();
+  storeToken(token);

3.3 특정 파일만 stash

# 특정 파일만 stash
git stash push -m "특정 파일만 저장" src/app.py src/utils.py

# 특정 파일은 제외하고 stash
git stash push --keep-index
# --keep-index: staging된 파일은 stash하지 않고 유지

3.4 stash에서 브랜치 생성

stash를 적용할 때 충돌이 발생하면, 새 브랜치를 만들어서 적용하는 것이 안전하다.

# stash 내용으로 새 브랜치 생성
git stash branch new-branch-name
Switched to a new branch 'new-branch-name'
On branch new-branch-name
Changes not staged for commit:
        modified:   src/login.js

Dropped stash@{0} (7d9b3a2c4f1e8b5d6c7a8f9e0b1d2c3a)

새 브랜치로 전환되고 stash 내용이 적용된 후 자동으로 stash가 삭제된다.

4 실전 시나리오

4.1 시나리오 1: 긴급 버그 수정

# 1. 현재 feature 작업 중... 긴급 버그 수정 요청!

# 2. 현재 작업 임시 저장
git stash push -m "feature/login 작업 중"

# 3. main 브랜치로 이동
git switch main
git pull

# 4. hotfix 브랜치 생성 및 버그 수정
git switch -c hotfix/critical-bug
# ... 버그 수정 ...
git add .
git commit -m "fix: Critical bug in payment"
git push -u origin hotfix/critical-bug

# 5. 원래 브랜치로 돌아오기
git switch feature/login

# 6. 임시 저장한 작업 복원
git stash pop

4.2 시나리오 2: 작업 브랜치를 잘못 선택한 경우

# main 브랜치에서 실수로 작업을 시작했다!

# 1. 변경사항 stash
git stash

# 2. 올바른 브랜치로 이동
git switch feature/correct-branch

# 3. stash 복원
git stash pop

4.3 시나리오 3: 여러 실험을 각각 저장

# 실험 A 저장
git stash push -m "실험 A: Redis 캐시 적용"

# 실험 B 저장
git stash push -m "실험 B: Memcached 적용"

# 실험 목록 확인
git stash list
# stash@{0}: 실험 B: Memcached 적용
# stash@{1}: 실험 A: Redis 캐시 적용

# 실험 A를 적용하기로 결정
git stash pop stash@{1}

5 주의사항

경고
  • Stash는 로컬 전용이다. 원격 저장소에 push되지 않는다.

  • Stash를 오래 쌓아두면 어떤 내용인지 잊기 쉽다. 항상 -m 옵션으로 설명을 남기자.

  • git stash pop 시 충돌이 발생하면 stash가 삭제되지 않는다 (수동으로 git stash drop 필요).

    충돌 발생 시 출력:

    Auto-merging src/login.js
    CONFLICT (content): Merge conflict in src/login.js
    The stash entry is kept in case you need it again.

    충돌 파일을 수동으로 해결한 후 git stash drop stash@{0} 으로 stash를 삭제한다.

  • Stash가 많이 쌓이면 관리가 어렵다. 가능하면 빨리 복원하거나 WIP 커밋을 사용하는 것을 고려하자.

6 요약

명령어 동작
git stash 변경사항 임시 저장
git stash push -m "설명" 메시지와 함께 저장
git stash -u 새 파일 포함하여 저장
git stash list 저장 목록 확인
git stash show -p 내용 상세 확인
git stash pop 복원 + 삭제
git stash apply 복원 (삭제 안 함)
git stash drop 특정 stash 삭제
git stash clear 전체 삭제
git stash branch <name> stash로 브랜치 생성

Subscribe

Enjoy this blog? Get notified of new posts by email: