스태시

스태시 stash 의 개념

마지막 커밋 이후 변경된 작업 영역과 스테이지 영역을 임시 저장하는 기능이다. 예를 들어 마지막 커밋 이후에 작업 도중 (커밋을 하기엔 불충분한 상태) 급하게 다른 브랜치로 작업 브랜치를 바꿔야 하는 경우에 사용한다.

git stash 명령을 사용하여, 작업 영역의 수정됨(modified) 상태의 파일과 스테이지에 올라옴(staged) 상태의 파일을 스택 구조의 임시 저장소인 stash 에 저장한다.

스태시 stash 명령어를 사용할 수 있는 전제조건

반드시 커밋 이력이 한 번 이상 있어야 하며, 마지막 커밋 이후 작업 디렉터리에 수정된 파일이나 스테이지 영역에 올라온 상태의 파일이 있어야 한다.

스태지 stash 의 동작

(1) 마지막 커밋 이후 작업 디렉터리 및 스테이지 영역에 수정사항이 있었다.
(2) 스태시 명령어를 실행한다.
(3) 1번에 있던 커밋 미적용 작업 내용들이 스택 구조의 임시 저장소인 스태시에 저장된다.
(4) 스태시 실행 후 작업 영역과 스테이지 영역은 마지막 커밋과 동일한 깨끗한 상태(working tree clean)이 된다.

stash 저장 명령어

명령어 설명

마지막 커밋 이후 변경된 작업 영역과 스테이지 영역을 임시 저장하는 기능이다.

기본 사용법 - 스태시 저장

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 현재 작업 영역과 스테이지 영역의 상태를 스태시에 보관
git stash [-m <message>]
git stash push [-m <message>]
git stash save [-m <message>]

# 스테이지 영역을 유지하고, 스태시에 저장하지 않음
git stash --keep-index (or -k)
git stash save --keep-index (or -k)

# git stash 목록 확인
git stash list              # 스태시에 저장된 항목의 목록 출력
git stash show [stash@{n}]  # 최종 커밋과 스태시에 저장된 항목 비교해 출력

# 작업 영역의 복원 (스태시 항목 복원)
git stash apply

옵션 - 스태시 저장

옵션 full name 설명
없음   - git stash push 를 실행하며, --include-untracked 플래그를 포함하지 않는다.
즉, 추적되지 않은 파일을 스태시 영역에 저장하지 않는다.
-m <message> message 스태시 항목에 메시지(식별용)을 추가.
push   - git 2.13 이후로 도입된 명령어이다.
git stash의 더 구체적인 형태로, 추가적인 옵션을 지원한다.
- 사용 가능한 옵션은 --include-untracked 혹은 --all 등으로, 추적되지 않은 파일도 저장할 수 있다.
save   - 권장되지 않는 명령어 - 2.16 이전 버전에서 주로 사용됨
git stash push로 대체가 가능하다.
-k --keep-index 스태시를 만들 때 인덱스(스테이지 영역)에 추가된 파일은 제외하는 옵션
작업 디렉터리의 변경 사항만을 저장한다.
list   저장된 스태시 항목의 목록을 확인
show   특정 스태시 항목의 내용을 확인.
최종 커밋과 스태시에 저장된 항목 비교해 출력
-u include-untracked 추적되지 않은 파일까지도 스태시에 저장

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 파일을 만들고 스테이지 영역에 추가
echo p > main.md
git add main.md

# 스태시 시도
git stash
>> You do not have the initial commit yet # 작업 내용이 없어서 스태시 불가

# 커밋
git commit -m M1
>> [main (root-commit) b1da560] M1
>>  1 file changed, 1 insertion(+)
>>  create mode 100644 main.md

# 저장소 상태 확인
git status
>> On branch main
>> nothing to commit, working tree clean

# 스태시 시도
git stash
>> No local changes to save # 마지막 커밋 이후 변경사항이 없어서 스태시 불가

# 추가 수정
echo q >> main.md
>> git status
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 스태시 영역에 작업 디렉터리 수정 내용 저장
git stash
>> Saved working directory and index state WIP on main: b1da560 M1

# 상태 확인 -> 깨끗함
git status
>> On branch main
>> nothing to commit, working tree clean

# 파일 확인 -> 최근 커밋 내용으로 바뀜
cat main.md
>> p

# 스태시 목록 확인 -> 존재
git stash list
>> stash@{0}: WIP on main: b1da560 M1

# 스태시 영역과의 차이 확인
git stash show
>>  main.md | 1 +
>>  1 file changed, 1 insertion(+)

stash 복원 명령어

명령어 설명

스태시에 저장된 작업 내용을 현재 작업 디렉터리에 적용하는 명령어이다.

기본 사용법 - 복원

1
git stash apply [option]

-기본적으로 작업 영역만 복원되며, 스테이지 영역까지 복원하려면 --index 옵션을 사용
-적용 후에도 지정 항목은 스태시에서 삭제되지 않고 유지된다.

옵션 - 복원

옵션 full name 설명
없음   최근 항목(stash@{0})이 복원 대상으로 지정된다.
[stash@{n}]   해당 스태시 항목을 복원한다. 작업 영역만을 복원하며, 스테이지 영역은 복원하지 않는다.
스태시에서 해당 항목을 삭제하지는 않는다.
--index [stash@{n}]   작업 영역과 스테이지 영역까지 복원한다.
스태시에서 해당 항목을 삭제하지는 않는다.

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# stash 영역에 저장된 내용을 불러옴
git stash apply
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 스태시에 저장된 목록 불러옴
>> git stash list
>> stash@{0}: WIP on main: b1da560 M1

# 파일 확인 -> 스태시에 저장되었던 이전 작업중인 내용이 출력됨을 확인
cat main.md
>> p
>> q

# 추적되지 않은 파일 만들기
echo login > feat.md
git status
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 추적되지 않은 파일까지 스태시 영역에 저장
git stash -u
>> Saved working directory and index state WIP on main: b1da560 M1

# 상태 확인 -> 깨끗함
git status
>> On branch main
>> nothing to commit, working tree clean

# 스태시에 저장된 내용 적용
git stash apply
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 스태시 목록 확인
git stash list
>> stash@{0}: WIP on main: b1da560 M1
>> stash@{1}: WIP on main: b1da560 M1

# git add
>> git add main.md
>> git status
>> On branch main
>> Changes to be committed:
>>   (use "git restore --staged <file>..." to unstage)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md

# save 명령어로 저장 (따옴표 안쪽은 메시지)
git stash save 'verify option --index'
>> Saved working directory and index state On main: verify option --index

# 상태 확인 -> untracked 파일은 스태시에 저장되지 않았음
git status
>> On branch main
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> nothing added to commit but untracked files present (use "git add" to track)

# 스태시 리스트 확인
git stash list
>> stash@{0}: On main: verify option --index
>> stash@{1}: WIP on main: b1da560 M1
>> stash@{2}: WIP on main: b1da560 M1

# 복원하면서 스테이지 영역까지 복원
git stash apply --index
>> On branch main
>> Changes to be committed:
>>   (use "git restore --staged <file>..." to unstage)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md

# 상태 확인
git status
>> On branch main
>> Changes to be committed:
>>   (use "git restore --staged <file>..." to unstage)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md

stash 삭제 명령어

명령어 설명

스태시에 저장된 내용을 삭제하는 명령어이다.

기본 사용법

1
2
3
git stash drop [stash@{n}]  # 스태시 목록에서 지정 항목 삭제 / 미지정시 최근 스태시 항목
git stash pop [stash@{n}]   # 지정한 스태시 저장 항목을 작업 디렉터리에 저장하고, 스태시 저장 목록에서 제거
git stash clear             # 스태시에 저장된 모든 항목을 삭제

옵션

옵션 full name 설명
``    
``    

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 스태시에 저장
git stash
>> Saved working directory and index state WIP on main: b1da560 M1

# 스태시 목록 확인
git stash list
>> stash@{0}: WIP on main: b1da560 M1
>> stash@{1}: On main: verify option --index
>> stash@{2}: WIP on main: b1da560 M1
>> stash@{3}: WIP on main: b1da560 M1

# 최근 스태시 항목 삭제
git stash drop
>> Dropped refs/stash@{0} (1eaca31251b4d53a676e0d6b4d9bea8ab2fd3c0a)

# 스태시 목록 확인
git stash list
>> stash@{0}: On main: verify option --index
>> stash@{1}: WIP on main: b1da560 M1
>> stash@{2}: WIP on main: b1da560 M1

# 작업 영역 상태 확인
git status
>> On branch main
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> nothing added to commit but untracked files present (use "git add" to track)

# 스태시에 저장된 최근 저장항목 적용
git stash apply
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 수정사항을 스테이지 영역에 등록
git add main.md

# 미 커밋 내용을 스태시에 저장
git stash
>> Saved working directory and index state WIP on main: b1da560 M1

# 스테이지 영역에 있는 내용을 제외하고 스태시 영역에 저장
git stash -k
>> No local changes to save

# 작업 영역 상태 확인
git status
>> On branch main
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> nothing added to commit but untracked files present (use "git add" to track)

# 스태시 목록 확인
git stash list
>> stash@{0}: WIP on main: b1da560 M1
>> stash@{1}: On main: verify option --index
>> stash@{2}: WIP on main: b1da560 M1
>> stash@{3}: WIP on main: b1da560 M1

# 스태시에 저장된 최근 항목을 적용하고, 적용된 항목을 스태시 목록에서 제거
git stash pop
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md

stash branch 스태시와 브랜치

명령어 설명

새로운 브랜치를 만들고 스태시를 적용하는 명령어이다.

기본 사용법

1
git stash branch <branch name> [stash@{n}]

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 작업 디렉터리에 있는 파일 수정
echo r >> main.md
cat main.md
>> p
>> q
>> r

# 작업 영역 상태 확인
git status
>> On branch main
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> no changes added to commit (use "git add" and/or "git commit -a")

# 스태시 영역에 저장
git stash
>> Saved working directory and index state WIP on main: b1da560 M1

# 작업 영역 상태 확인
git status
>> On branch main
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> nothing added to commit but untracked files present (use "git add" to track)

# 스태시에 저장된 목록 확인
git stash list
>> stash@{0}: WIP on main: b1da560 M1
>> stash@{1}: On main: verify option --index
>> stash@{2}: WIP on main: b1da560 M1
>> stash@{3}: WIP on main: b1da560 M1

# 스태시 영역에 저장된 내용을 새로운 브랜치를 생성하면서 저장
git stash branch gotfix
>> Switched to a new branch 'gotfix'
>> On branch gotfix
>> Changes not staged for commit:
>>   (use "git add <file>..." to update what will be committed)
>>   (use "git restore <file>..." to discard changes in working directory)
>>         modified:   main.md
>> Untracked files:
>>   (use "git add <file>..." to include in what will be committed)
>>         feat.md
>> no changes added to commit (use "git add" and/or "git commit -a")
>> Dropped refs/stash@{0} (c451a7e09a4fd52acc1c0f405b1d6ca89c86170d)

# 로그 확인
>> *   9c394f8 (refs/stash) On main: verify option --index
>> |\  
>> | * b9133ab index on main: b1da560 M1
>> |/  
>> * b1da560 (HEAD -> gotfix, main) M1

Reference

UNIX시스템 - 김희천,김진욱 저