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 브랜치
솔루션 보기
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 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
?를 입력하여 헝크(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는 이것을 가리키도록 업데이트됩니다.
--include-untracked
옵션을 사용하면 추적되지 않은 파일의 변경 사항을 추가 커밋으로 인코딩할 수도 있습니다.
--all
옵션을 사용하면 무시된 파일에 대한 변경 사항과 동일한 커밋에서 추적되지 않은 파일의 변경 사항이 포함됩니다.
git stash pop
을 실행하면 위 커밋의 변경 사항을 사용하여 작업 복사본 및 색인을 업데이트하며, stash reflog는 셔플되어 팝된 커밋을 제거합니다. 팝된 커밋은 즉시 삭제되지는 않지만 향후 가비지 컬렉션의 후보가 됩니다.
이 문서 공유
다음 토픽
여러분께 도움을 드릴 자료를 추천합니다.
이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.