본문 바로가기
버전관리/GIT_HUB

GIT Stash, commit하지 않고 변경이력 임시 저장하기!

by joa-yo 2023. 12. 4.
반응형

stash는 '숨김', '은닉'이라는 의미를 갖고 있습니다. 현재의 변경사항을 숨겨두고 나중에 필요할 때 다시 꺼내와서 적용할 수 있습니다. 일반적으로 브랜치를 변경할 때 작업이력을 저장해두는 용도로 사용합니다.

 

Commit과 stash 사용이유

Commit 사용이유

버전 관리

commit은 버전 관리 시스템에서 변경사항의 스냅샷을 기록합니다.

각 커밋은 프로젝트의 특정 시점의 상태를 나타내며, 이를 통해 과거로 되돌아가거나 특정 버전으로 이동할 수 있습니다.

작업 기록

개발자가 수행한 작업을 기록하여 누가 어떤 변경을 만들었는지 추적할 수 있습니다.

커밋 메시지를 통해 변경 내용에 대한 정보를 기록할 수 있어 코드 리뷰나 협업 시에도 도움이 됩니다.

브랜치 관리

브랜치 간의 변경사항을 합치기 위해 commit을 사용합니다.

브랜치를 생성하고 합치면서 변경사항을 추적하고, 이력을 관리할 수 있습니다.

Stash 사용 이유

임시 저장

현재 작업 중인데 갑자기 다른 브랜치로 전환해야 할 경우, 혹은 변경사항을 저장하고 싶지만 커밋하기엔 아직 이르다고 판단될 때 사용합니다.

stash를 사용하여 변경사항을 일시적으로 저장하고 나중에 다시 적용할 수 있습니다.

브랜치 전환

브랜치를 전환할 때 현재 작업 중인 변경사항이 스테이징되지 않은 상태라면 stash를 사용하여 변경사항을 저장하고 다른 브랜치로 이동합니다.

작업 공간 정리

임시적으로 작업 디렉터리를 깨끗하게 만들고 싶을 때 사용합니다.

현재 변경사항을 스태시하면 작업 디렉터리가 깨끗한 상태로 전환됩니다.

결론적으로, commit은 영구적인 변경사항을 기록하고 버전 관리에 사용되며, stash는 임시로 변경사항을 저장하고 나중에 불러와서 사용하는 데 주로 활용됩니다.

 

 

stash의 저장 영역

git의 저장영역은 working directory, staging, local repository, remote repository로 구분합니다. stash는 이중 어디에 저장될까요? 정답은 working directory 하위에 .git이라는 git의 메타데이터를 저장하고 있는 폴더가 있는데요, 그곳에 저장된다고 합니다. 그리고 브랜치에 상관 없이 임시 저장했다가 소스를 받는게 가능하다는 점은 참고로 알아두세요!

 

공식적으로나 다른 블로그에선 stash영역을 별도로 표시하고 있지는 않지만, 별도의 영역으로 간주해도 괜찮지 않을까 생각하여... 도표를 그려봅니다! 공식적인 것은 아니며 공부할 때 참고용으로만 사용해주세요!

 


알고가기

git status

$ git status
On branch master
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:   README.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git status -s
 M README.txt

위에서 보시는 것처럼 git status 명령어를 사용할 때 -s옵션을 사용하면, 현재 로컬의 변경사항을 간단하게 확인할 수 있습니다.

 

M : modified

?? : added

 


Stash

stash가 가능한 상태 준비

stash는 첫번째 커밋을 한 이후로 사용 가능한 명령어 이므로 한번이라도 커밋이 있는 상태를 준비해주세요. local repository가 없다면 repository를 생성하는 아래의 스크립트를 따라해보세요.

## git localre repository 준비
$ mkdir stash
$ cd stash
$ git init
Initialized empty Git repository in D:/git/repositories/stash/.git/

## 임의 파일(README.txt) 생성 및 커밋
$ touch README.txt
$ git add README.txt
warning: in the working copy of 'README.txt', LF will be replaced by CRLF the next time Git touches it
$ git commit -m "initCommit"
[master (root-commit) 8557128] first
 1 file changed, 1 insertion(+)
 create mode 100644 README.txt

## 결과
$ git log --all --oneline --graph
* 8557128 (HEAD -> master) initCommit

## 현재 상태 확인
$ git status -s

$ git stash list

$ git stash show
No stash entries found.

$ cat README.txt

 

 

 

stash 명령어로 커밋 없이 소스 임시 저장하기

아래의 명령어를 숙지하고 stash 명령어 실행 전과 후를 비교해보세요.

명령어

명령어 설명
git status -s 로컬스토리지의 변경 이력을 보여줍니다.
git stash list commit하지 않고, stash한 리스트를 보여줍니다.
git statsh show stash list를 상세하게 보여줍니다.

 

stash 수행 및 수행 전 후 비교

commit 이후 소스 수정

## README.txt에 새로운 라인 추가
$ echo "first line" >> README.txt

## stash 전 마지막으로 상태 확인
$ cat README.txt
first line

$ git stash list

$ git stash show
No stash entries found.

$ cat README.txt
first line

 

 

stash 명령어로 임시저장

## statsh
$ git stash
warning: in the working copy of 'README.txt', LF will be replaced by CRLF the next time Git touches it
Saved working directory and index state WIP on master: 2ed32d1 first

 

 

stash 수행 후 결과

## stash 후 결과
$ git status -s

$ git stash list
stash@{0}: WIP on master: 8557128 initCommit

$ git stash show
 README.txt | 1 +
 1 file changed, 1 insertion(+)

$ cat README.txt

 

commit 이후 README.txt파일을 수정하고 stash 명령어를 수행했더니, READEME.txt파일의 "first line" 텍스트가 사라졌습니다. 이를 통해 stash명령어가 워킹 디렉토리의 변경사항을 커밋상태로 복구시켜주면서, 현재까지의 수정이력을 임시저장해준다는 것을 알 수 있습니다.

 

그런데 stash는 모든 파일을 다 임시저장할까요?

 

stash되는 파일 확인 준비

# 신규파일 추가
$ echo "MAIN TEXT" >> main.html
$ echo "HELLO WORLD" >> index.html
$ git add index.html
warning: in the working copy of 'index.html', LF will be replaced by CRLF the next time Git touches it

## stash 실행 전 상태
$ git status -s
 M README.txt
A  index.html
?? main.html

 

main.html은 생성만 해두고, index.html은 add해보겠습니다.

 

 

stash되는 파일 확인

## stash 수행
$ git stash 

## stash 수행 결과
$ git status -s
?? main.html

$ git stash list
stash@{0}: On master: write stash push message
stash@{1}: WIP on master: 8557128 initCommit

$ git stash show
 README.txt | 1 +
 index.html | 1 +
 2 files changed, 2 insertions(+)

 

main.html은 반영되지 않은 모습이네요. 신규파일은 add해주지 않으면, stash영역에 반영되지 않습니다.

 

$ git status -k

 

만약에 임시저장하면서 현재 워킹 디렉토리의 소스를 그대로 유지하고싶다면 -k옵션을 사용해주세요

 

 

 

stash apply 명령어로 임시 저장된 소스로 복구하기

그럼 다시 stash된 소스들을 다시 워킹 디렉토리로 가져와보겠습니다.

 

apply 명령어로 stash된 소스내역으로 복구

## 복구명령어 실행
$ git stash apply
On branch master
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:   README.txt

no changes added to commit (use "git add" and/or "git commit -a")

 

복구된 상태확인

$ git status -s
 M README.txt

$ git stash list
stash@{0}: WIP on master: 8557128 initCommit

$ git stash show
 README.txt | 1 +
 1 file changed, 1 insertion(+)

$ cat README.txt
first line

 

stash 명령어 실행 전에 REAME.txt파일에 추가한 "first line"이 다시 적용되었습니다. 하지만 stash 목록은 그대로 유지되어 있습니다. 다시 말해, stash apply 명령어는 가장 최근에 만들어진 stash를 적용하는 명령어입니다. staged 상태의 파일까지도 함께 적용됩니다.

 

 

 

stash 항목 삭제

명령어 설명
git stash drop 가장 최근 항목을 삭제한다.
git stash drop stash@{n} 스태시 목록에서 지정된 항목을 삭제한다.
git stash clear 스태시에 저장된 항목을 모두 삭제한다.
git stash pop 스태시 리스트의 최신항목을 적용하고 스태시 목록에서 제거한다.
git stash pop stash@{n} 지정한 스태시 목록을 적용하고 스태시 목록에서 제거한다.

위의 명령어들을 통해서 stash 항목을 삭제할 수 있습니다.이는 간단하므로 예시를 넘어가도록 하겠습니다.

반응형

댓글