git의 요술 책갈피, Stash 기능 소개

Posted by in Tech

git에는 기본적인 커밋 & 푸시 등의 기능 외에도 수많은 기능들이 있습니다.
그중 매우 유용한 요술 책갈피인 Stash에 대한 소개입니다.

사전적 의미


Stash [stӕʃ] 1. (안전한 곳에) 넣어 두다
2. 챙겨 둔 양

Situations


현업에서 코드를 열심히 개발하다 보면 이런 상황이 왕왕 발생합니다.

상황 1.

신규 프로젝트인 “LetItGo” 프로젝트가 시작됐습니다.
저장소 세팅을 하고 일단 init 커밋 & 푸시를 쏩니다.
“이런 이런 기능을 개발 해야 되는데. 번뜩이는 영감으로 빠르게 프로토타이핑 한번 해봐야지”
불타오르는 손으로 열심히 코딩합니다.
그런데 이게 왠 걸? 몰랐네요. 개발 브랜치에서 개발해야 되는데 마스터 브랜치에 열심히 개발해 버렸네요. (실제로 전 자주 그렇습니다ㅎㅎ)
마스터 브랜치에 작업한걸 개발 브랜치로 넘겨야 됩니다.

어떡하죠?

상황 2.

이번 “LetItGo” 프로젝트를 위해 동료와 함께 개발을 시작했습니다.
포크를 따서 개인 저장소를 세팅하고, 뚝딱뚝딱 개발을 합니다.
한참 코딩을 하던 중, 동료가 최신 상태의 코드가 이상하다고 체크를 한번 해달라고 합니다.
그렇다고 개발중인 브랜치에 커밋을 하고 싶진 않습니다.
열심히 개발 하던 코드는 커밋하기에는 너무 날림 코드입니다.
코드를 버릴 순 없는데..? 워킹 디렉토리는 HEAD로 돌려야 합니다.

어떡하죠?

상황 3.

어찌 어찌 하여 “LetItGo” 프로젝트를 열심히 마치고 리얼 배포를 나갔습니다.
추가 개발이 있어 열심히 개발을 다시 시작합니다.
그런데 이게 왠 걸? 개발한 코드에 문제가 있어 장애가 발생했습니다.
땀이 줄줄 가슴은 철렁, 빨리 수정을 해야 합니다.
그런데 지금까지 개발한 코드를 버리긴 아깝네요. 얼른 워킹 디렉토리를 HEAD로 돌려야 하는데..
세가지의 상황 모두 개발중에 쉽게 발생할 수 있는 상황들입니다.

어떻게 하는 것이 좋을까요?

그래서 Stash


커밋 하기는 애매하고, 그렇다고 코드를 날릴 수도 없고.
리비전은 돌아가야 되는 상황.

위와 같은 상황에서 좋은 해법을 가진 기능이 바로 Stash 입니다.
Stash는 워킹 디렉토리에 unstaged 파일들을 백업하고, 워킹 디렉토리를 깨끗한 상태, 즉 HEAD의 상태로 만드는 기능입니다.
마치 스냅샷을 찍어 어딘가에 잠깐 저장해 놨다가 작업 하던 것들을 그대로 다시 불러온다고 생각하면 이해가 쉽습니다.
좋은 기능은 써봐야지 그 진가를 안다고 합니다ㅎ 한번 써봐야죠.

“”Step By Step 필요 없고, 커맨드만 보여주시죠!” 하시는 분은 맨 아래로 스크롤바를 내리시면 좋겠습니다^^

하던 일을 넣어두기 (Stash)


그럼 하던 일을 넣기 위해 예제 프로젝트를 생성해 보겠습니다.

예제 프로젝트 생성

  1. 프로젝트를 세팅하고,
    git init
  2. 파일을 수정하거나 생성합니다.
    touch README
  3. git add 와 git commit을 하여 init 커밋을 합니다.
    git add .
    git commit -m “init”
  4. 현재 상태는 git 저장소가 세팅되고 README 파일이 커밋된 상태 입니다.
  5. git 상태를 보면 변화된 것이 아무것도 없다고 나옵니다.
    git status

이제 Stash를 시험해볼 준비가 끝났거 같네요.
그럼 새로 파일을 한번 생성해 보겠습니다.

작업내용 담기 (stash)

  1. 빈 파일을 생성합니다.
    touch new_file
  2. 상태를 보니 방금 추가한 파일이 보이네요.
    git status
  3. git add를 통해 git에 파일을 등록해 보겠습니다.
    git add new_file
  4. 파일을 추가한 후 git status로 상태를 보니 신규 파일이 추가되었다고 나옵니다.
    git status
  5. 이제 드디어 git stash를 이용하여 작업한 내용을 갈무리하고,
    마지막 커밋상태(init)로 돌아가 보겠습니다.
    git stash
  6. 만약 특정 이름을 부여하고 싶다면, git stash save를 이용합니다.
    git stash save MY_STASH_NAME
  7. 이제 디렉토리 상태를 확인해 보겠습니다. Working Directory가 깨끗해졌네요.
    제가 원하는 결과대로 돌아왔습니다.
    git status
  8. Stash에 잘 들어갔는지 한번 확인 해 볼까요?
    git stash list
  9. 잘 들어간거 같네요.
    이제 원하는 작업을 할 수 있게 되었습니다. (FIN.)

하던 일을 다시 불러오기 (Unstash)


좀전에 작업 내용을 책갈피(Stash Area)에 담아두었습니다.
넣어 둔 것을 다시 꺼내올(Unstash) 차례네요. 하던 일을 불러오는 방법은 2가지가 있습니다.
하나씩 살펴 보도록 하겠습니다.

Pop
마지막 작업본 가져오기

  1. stash한 리스트를 출력해 보니, 아까 Stash한 MyStash가 있네요.
    git stash list
  2. 그러면 pop을 이용해 stash를 가져와 보겠습니다.
    pop을 이용하면, 마지막으로 Stash한 것을 불러올 수 있습니다.
    git stash pop
  3. 아까 추가한 그 파일이 다시 돌아왔네요. 반갑네요 ㅋㅋ
    그리고 pop을 수행하면, 그 의미처럼 Stash 리스트에서는 빠지게 됩니다.
  4. 다시 리스트 출력을 해보면? 아까의 Stash가 사라졌습니다.
    git stash list
  5. 잘 돌아온거 같네요.
    이제 다시 하던 작업을 할 수 있게 되었습니다.


Apply

특정 작업본 가져오기

  1. Pop을 통해 가져온 작업본을 다시 Stash 해 보겠습니다.
    git stash save “MyStash”
  2. 리스트 출력을 해보면? MyStash가 다시 들어왔네요.
    git stash list
  3. 특정 Stash를 불러오기 위해선 apply를 이용합니다.
    apply를 이용하면 stash리스트에서 사라지지 않고 불러오기만 수행할 수 있습니다.
    git stash apply stash@{0}
  4. pop과는 다르게 stash 리스트에서 사라지지 않습니다.
    자 이제 하던 작업을 계속 진행하면 되겠네요. (FIN.)
    git stash list

상황 해결


이 단순한 Stash / UnStash 만으로, 처음에 소개한 3가지 시나리오를 모두 해결할 수 있었습니다.

복잡한 기능은 아님에도 꽤나 유용하게 사용이 되었네요.

상황 1.
로컬 마스터에 열심히 개발한 건 stash해서 워킹 디렉토리를 HEAD로 돌리고,
새로 브랜치를 만들어 그곳에서 Unstash를 하였습니다.

상황 2.
열심히 프로토타이핑 하던 코드는 Stash하여 잠깐 넣어두고,
워킹 디렉토리를 HEAD로 돌아가서 문제가 있던 코드 부분을 점검했습니다.

상황 3.
갑자기 생긴 장애 상황에도 당황하지 않고,
작업하던 디렉토리를 Stash하여 넣어두고 워킹 디렉토리를 HEAD로 돌려서 버그를 찾아냈습니다.

추가적인 사용 방법들


git stash save
현재 작업을 저장해두고 branch를 head로 돌린다.(git reset –hard)

git stash list
저장되어 있는 stash들 보기

git stash pop
stash들은 stack에 저장된다. 따라서 가장 최근에 save한 stash가 현재 branch에 적용된다.

git stash apply
git stash pop 과 비슷한 명령어지만 stash list에서 삭제하지 않는다는 점이 다르다.

git stash drop
필요 없는 stash를 삭제

git stash clear
전체 stash list를 삭제

git 더보기


git 에는 Stash외에도 여러 유용한 도구들이 있습니다.
처음부터 한번에 공부해서 쓸 수는 없지만 이런 기능들이 있다라고 알아두면 찾아가면서 쓸 수 있게 되는거 같습니다.
언젠가 비슷한 상황에서도 당황하지 않고 Stash 를 이용하여 브랜치 넘나들며 개발할 수 있게끔 조금이나마 도움이 되길 바랍니다.