Close

Git 스태시

git stash는 작업 복사본에 적용한 변경 사항을 일시적으로 저장(또는 스태시)하여 다른 작업을 하다가 다시 돌아와서 나중에 변경 사항을 다시 적용할 수 있도록 합니다. 스태시는 컨텍스트를 빠르게 전환하고 다른 작업을 수행해야 하지만, 코드 변경을 진행하고 있고 커밋할 준비는 되지 않은 경우 편리합니다.


작업 스태시


git stash 명령은 커밋하지 않은 변경 사항(스테이지된 사항 및 스테이지되지 않은 사항 모두)을 가져와서 나중에 사용할 수 있도록 저장한 다음 작업 복사본에서 되돌립니다. 예를 들면 다음과 같습니다.

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
nothing to commit, working tree clean
Git 브랜치
관련 자료

Git 브랜치

Bitbucket 로고
솔루션 보기

Bitbucket Cloud에서 Git에 대해 알아보기

이 시점에서 자유롭게 변경하고, 새 커밋을 만들고, 브랜치를 전환하며, 다른 Git 작업을 수행할 수 있습니다. 그런 다음 준비가 되면 돌아와서 스태시를 다시 적용할 수 있습니다.

스태시는 Git 리포지토리에게 로컬입니다. 푸시할 때 스태시는 서버로 푸시되지 않습니다.

스태시된 변경 사항 다시 적용


다음과 같이 git stash pop을 사용하여 이전에 스태시한 변경 사항을 다시 적용할 수 있습니다.

$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)

스태시를 (popping)하면 스태시의 변경 사항이 제거되고 작업 복사본에 다시 적용됩니다.

또는 작업 복사본에 변경 사항을 다시 적용하고 동시에 git stash apply를 사용하여 스태시에 보관할 수 있습니다.

$ git stash apply
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

이 옵션은 스태시된 동일한 변경 사항을 여러 브랜치에 적용하려는 경우에 유용합니다.

스태시의 기본 사항을 살펴봤으며 git stash와 관련하여 주의해야 할 점이 한 가지 있습니다. 기본적으로 Git은 추적되지 않거나 무시된 파일에 적용된 변경 사항을 스태시하지 않습니다.

추적되지 않거나 무시된 파일 스태시


기본적으로 git stash를 실행하면 다음이 스태시됩니다.

  • 색인에 추가된 변경 사항(스테이지된 변경 사항)
  • Git에서 현재 추적하는 파일의 변경 사항(스테이지 취소된 변경 사항)

하지만 다음은 스태시되지 않습니다.

  • 작업 복사본에서 아직 스테이지되지 않은 새 파일
  • 무시된 파일

따라서 위 예제에 세 번째 파일을 추가하지만 스테이지하지 않으면(예: git add를 실행하지 않음) git stash는 파일을 스태시하지 않습니다.

$ script.js

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Untracked files:

    script.js

$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
Untracked files:

    script.js

다음과 같이 -u 옵션(또는 --include-untracked)을 추가하면 git stash가 추적되지 않은 파일도 스태시하도록 합니다.

$ git status
On branch main
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Untracked files:

    script.js

$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
nothing to commit, working tree clean

git stash를 실행할 때 -a 옵션(또는 --all)을 전달하여 무시된 파일에 변경 사항을 포함할 수도 있습니다.

Git 스태시 옵션

여러 개의 스태시 관리


한 개의 스태시에로 제한되지 않습니다. git stash를 여러 번 실행하여 여러 스태시를 만든 다음 git stash list를 사용하여 볼 수 있습니다. 기본적으로, 스태시는 "WIP"(진행 중인 작업)로 식별되며, 사용자가 스태시를 만든 브랜치 또는 커밋의 상단에 있습니다. 시간이 지나면 각 스태시에 포함된 내용을 기억하기 어려울 수 있습니다.

$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage

좀 더 많은 컨텍스트를 제공하려면 git stash save "message"를 사용하여 스태시에 설명을 추가하는 것이 좋습니다.

$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage

$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage

기본적으로 git stash pop은 가장 최근에 만들어진 다음 스태시 stash@{0}를 다시 적용합니다.

식별자를 마지막 인수로 전달하여 다시 적용할 스태시를 선택할 수 있습니다. 예를 들면 다음과 같습니다.

$ git stash pop stash@{2}

스태시 diff 보기


다음과 같이 git stash show를 사용하여 스태시 요약을 볼 수 있습니다.

$ git stash show
 index.html | 1 +
 style.css | 3 +++
 2 files changed, 4 insertions(+)

또는 다음과 같이 -p 옵션(또는 --patch)을 전달하여 스태시의 전체 diff를 볼 수 있습니다.

$ git stash show -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+  text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>

부분 스태시


단일 파일, 파일 컬렉션 또는 파일 내의 개별 변경 사항만 스태시하도록 선택할 수도 있습니다. -p 옵션(또는 --patch)을 git stash로 전달하면, 작업 복사본에서 변경된 각 헝크(hunk)를 반복하며 스태시할 것인지 묻습니다.

$ git stash -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+  text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? n
Git Stash -p

?를 입력하여 헝크(hunk) 명령의 전체 목록을 볼 수 있습니다. 일반적으로 유용한 명령은 다음과 같습니다.

명령

설명

/

설명

정규식으로 헝크(hunk) 검색

?

설명

무엇이든 물어보세요!

n

설명

이 헝크(hunk) 스태시하지 않기

q

설명

종료(이미 선택한 모든 헝크(hunk) 스태시)

s

설명

이 헝크(hunk)를 작은 헝크로 분할

y

설명

이 헝크(hunk) 스태시

명시적인 "중단" 명령은 없지만 CTRL-C(SIGINT)를 누르면 스태시 프로세스가 중단됩니다.

스태시에서 브랜치 만들기


브랜치의 변경 사항이 스태시의 변경 사항과 다른 경우 스태시를 팝하거나 적용할 때 충돌이 발생할 수 있습니다. 대신 다음과 같이 git stash branch를 사용하여 새 브랜치를 만들고 스태시한 변경 사항을 적용할 수 있습니다.

$ git stash branch add-stylesheet stash@{1}
Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:

    new file:   style.css

Changes not staged for commit:

    modified:   index.html

Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)

이렇게 하면 스태시를 만든 커밋을 기반으로 새 브랜치가 체크아웃되고, 스태시한 변경 사항이 그 브랜치에 팝됩니다.

스태시 정리


특정 스태시가 더 이상 필요하지 않다고 결정하면 다음과 같이 git stash drop을 사용하여 삭제할 수 있습니다.

$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)

또는 다음을 사용하여 모든 스태시를 삭제할 수도 있습니다.

$ git stash clear

git stash 작동 방식


git stash를 사용하는 방법을 알고 싶다면 여기까지만 읽으셔도 좋습니다. 하지만 Git(및 git stash)의 작동 방식이 궁금하다면 계속 읽어보시기 바랍니다.

스태시는 실제로 리포지토리에서 커밋 개체로 인코딩됩니다. .git/refs/stash의 특별한 ref는 가장 최근에 만들어진 스태시를 가리키며, 이전에 만들어진 스태시는 stash ref의 참조 로그에 의해 참조됩니다. 이것이 스태시를 stash@{n}:으로 참조하는 이유입니다. 실제로 stash ref에 대한 n번째 참조 로그 항목을 참조한다는 의미입니다. 스태시는 단지 커밋일 뿐이므로 다음과 같이 git log로 검사할 수 있습니다.

스태시한 내용에 따라 단일 git stash 작업을 통해 두 개 또는 세 개의 새 커밋을 만듭니다. 위 다이어그램의 커밋은 다음과 같습니다.

  • git stash를 실행할 때 작업 복사본에 있던 추적된 파일을 저장하는 새 커밋인 stash@{0}
  • git stash를 실행할 때 HEAD에 있던 stash@{0}의 첫 번째 상위 기존 커밋
  • git stash를 실행할 때 색인을 나타내는 stash@{0}의 두 번째 상위 새 커밋
  • git stash를 실행할 때 작업 복사본에 있던 추적되지 않은 파일을 나타내는 stash@{0}의 세 번째 상위 새 커밋. 세 번째 상위 커밋은 다음과 같은 경우에만 만들어집니다.
    • 작업 복사본에 추적되지 않은 파일이 실제로 포함된 경우
    • git stash를 호출할 때 --include-untrackedl 또는 --all 옵션을 지정한 경우

git stash가 작업 트리 및 색인을 커밋으로 인코딩하는 방법은 다음과 같습니다.

  • 스태시 전에 작업 트리에 추적된 파일, 추적되지 않은 파일 및 무시된 파일에 대한 변경 사항이 포함될 수 있습니다. 변경 사항 중 일부는 색인에 스테이지될 수도 있습니다.
스태시 전
  • git stash 명령을 호출하면 추적된 파일의 변경 사항이 DAG에서 두 개의 새 커밋으로 인코딩됩니다. 하나는 스테이지되지 않은 변경 사항에 대한 커밋이고, 다른 하나는 색인에 스테이지된 변경 사항에 대한 커밋입니다. 특수 refs/stash ref는 이것을 가리키도록 업데이트됩니다.
Git 스태시
  • --include-untracked 옵션을 사용하면 추적되지 않은 파일의 변경 사항을 추가 커밋으로 인코딩할 수도 있습니다.
Git stash --include-untracked
  • --all 옵션을 사용하면 무시된 파일에 대한 변경 사항과 동일한 커밋에서 추적되지 않은 파일의 변경 사항이 포함됩니다.
Git Stash --all

git stash pop을 실행하면 위 커밋의 변경 사항을 사용하여 작업 복사본 및 색인을 업데이트하며, stash reflog는 셔플되어 팝된 커밋을 제거합니다. 팝된 커밋은 즉시 삭제되지는 않지만 향후 가비지 컬렉션의 후보가 됩니다.


이 문서 공유
다음 토픽

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

도구로 가득한 벽을 사용하여 협업하는 사람들

Bitbucket 블로그

DevOps 일러스트레이션

DevOps 학습 경로

Atlassian 전문가와 함께 하는 Demo Den 기능 데모

Bitbucket Cloud가 Atlassian Open DevOps와 작동하는 방법

DevOps 뉴스레터 신청

Thank you for signing up