반응형

만약 당신이 어떤 프로젝트에서 한 부분을 담당하고 있어 작업하던 중 다른 요청이 들어와서 잠시 브랜치를 변경해야 할 일이 생겼다고 가정해보겠습니다. 그런데 이런 상황에서 아직 완료하지 않은 일을 커밋한느 것이 껄끄럽다는 것이 문제입니다. 커밋하지 않고 나중에 다시 돌아와 작업을 다시 하고 싶을 겁니다. 이 문제는 git stash 라는 명령으로 해결할 수 있습니다.


1. Stash 하기

Stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일들만 저장합니다. Stash는 Modified 이면서 Tracked 상태인 파일과 Staging Area 에 있는 파일들을 보관해두는 장소입니다. 아직 끝내지 않은 수정사항을 스택에 잠시 저장했다가 나중에 다시 적용할 수 있습니다.(브랜치가 달라져도 가능합니다.)

하던 일을 Stash 하기

예제 프로젝트를 하나 살펴보겠습니다. 파일을 두 개 수정하고 그 중 하나는 Staging Area 에 추가합니다.
그리고 git status 명령을 실행하면 아래와 같은 결과를 볼 수 있습니다.

$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   lib/simplegit.rb

이제 브랜치를 변경해보겠습니다. 아직 작업 중인 파일은 커밋할 게 아니라서 모두 Stash 합니다.


git stashgit stash push 를 실행하면 스택에 새로운 Stash 가 만들어집니다.

$ git stash
Saved working directory and index state \
  "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")

대신 워킹 디렉토리는 깨끗해졌습니다.

$ git status
# On branch master
nothing to commit, working directory clean

이제 아무 브랜치나 골라서 쉽게 바꿀 수 있습니다. 수정하던 것을 스택에 저장했습니다.


아래와 같이 git stash list 를 사용하여 저장한 Stash 를 확인합니다.

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log

Stash 두 개는 원래 있었다고 하면, 아까 Stash 했기 때문에 이제 3 개의 Stash 를 사용할 수 있습니다.

 

이제 git stash apply 를 사용하여 Stash 를 다시 적용할 수 있습니다. git stash 명령을 실행하면 Stash 를 다시 적용하는 방법도 알려줘서 편리합니다. git stash apply stash@{2} 처럼 Stash 이름을 입력하면 골라서 적용할 수 있습니다. 이름이 없으면 Git 은 가장 최근의 Stash 를 적용합니다.

$ git stash apply
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   index.html
  modified:   lib/simplegit.rb

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

Git은 Stash에 저장할 때 수정했던 파일들을 복원해줍니다.

복원할 때의 워킹 디렉토리는 Stash 할 때의 그 브랜치이고 워킹 디렉토리도 깨끗한 상태였습니다. 하지만 꼭 깨끗한 워킹 디렉토리나 Stash 할 때와 같은 브랜치에 적용해야 하는 것은 아닙니다. 어떤 브랜치에서 Stash 하고 다른 브랜치로 옮기고서 거기에 Stash를 복원할 수 있습니다.

 

그리고 꼭 워킹 디렉토리가 깨끗한 상태일 필요도 없습니다. 워킹 디렉토리에 수정하고 커밋하지 않은 파일들이 있을 때도 Stash를 적용할 수 있습니다. 만약 충돌이 있으면 알려줍니다.

 

Git은 Stash를 적용할 때 Staged 상태였던 파일을 자동으로 다시 Staged 상태로 만들어 주지 않습니다. 그래서 git stash apply 명령을 실행할 때 --index 옵션을 주어 Staged 상태까지 적용합니다. 그래야 원래 작업하던 상태로 돌아올 수 있습니다.

apply 옵션은 단순히 Stash를 적용하는 것뿐입니다. Stash는 여전히 스택에 남아 있습니다.


git stash drop 명령을 사용하여 해당 Stash를 제거합니다.
git stash pop 이라는 명령도 있는데 이 명령은 Stash를 적용하고 나서 바로 스택에서 제거해줍니다.

 

Stash를 적용한 브랜치 만들기

보통 Stash 에 저장하면 한동안 그대로 유지한 채로 그 브랜치에서 계속 새로운 일을 합니다. 그러면 이제 저장한 Stash를 적용하는 것이 문제가 됩니다. 수정한 파일에 Stash를 적용하면 충돌이 일어날 수도 있고 그러면 또 충돌을 해결해야 합니다. 필요한 것은 Stash 한 것을 쉽게 다시 테스트하는 것입니다.

 

git stash branch <branch> 명령을 실행하면 Stash 할 당시의 커밋을 Checkout 한 후 새로운 브랜치를 만들고 여기에 적용합니다. 이 모든 것이 성공하면 Stash를 삭제합니다.

 

2. Clean Working Directory

작업하고 있던 파일을 Stash 하지 않고 단순히 그 파일들을 치워버리고 싶을 때가 있습니다.
git clean 명령이 그 일을 합니다. 보통은 Merge 나 외부 도구가 만들어낸 파일을 지우거나 이전 빌드 작업으로 생성된 각종 파일을 지우는 데 필요합니다.

 

이 명령을 사용할 때는 신중해야 합니다. 이 명령을 사용하면 워킹 디렉토리 안의 추적하고 있지 않은 모든 파일이 지워지기 때문입니다. 명령을 실행하고 나서 후회해도 소용 없습니다.

 

워킹 디렉토리의 불필요한 파일들을 전부 지우려면 git clean 을 사용합니다. 추적 중이지 않은 모든 정보를 워킹 디렉토리에서 지우고 싶다면 git clean -f -d 명령을 사용하면 됩니다. 이 명령은 하위 디렉토리까지 모두 지워버립니다.

 

이 명령을 실행했을 때 어떤 일이 일어날지 미리 보고 싶다면 -n 옵션을 사용합니다.

-n 옵션은 "가상으로 실행해보고 어떤 파일들이 지워지는지 알려달라" 는 의미입니다.

$ git clean -d -n
Would remove test.o
Would remove tmp/

git clean 명령은 추적 중이지 않은 파일만 지우는게 기본 동작입니다.
.gitignore 에 명시했거나 해서 무시되는 파일은 지우지 않습니다. 무시된 파일까지 함께 지우려면 -x 옵션이 필요합니다.

 


출처 - 저서 ProGit

반응형
반응형