git stash 명령어 사용하기

Jongyeon Kim·2023년 12월 23일
0

stash의 사전적 의미

※ 출처 - 네이버 사전

  • stash를 사전에서 찾아봤을 때 ‘무언가를 안전한 곳에 넣어둔다’라는 의미를 갖고 있다.
  • git의 명령어 git stash 도 위의 사전적 의미와 같은 기능을 하고 있다. 과연 git에서의 stash는 어떤 것을 넣어두는 건지 알아보도록 한다.

Git에서 stash의 역할과 스택의 정의

  • Git에서 stash는 어떻게 동작하고 있을까?
    • git-scm 사이트를 살펴보면 “뭔가 작업하던 일이 있고 다른 요청이 들어와 잠시 브랜치를 변경해야 할 일이 생겼을 때” git stash 라는 명령으로 해결할 수 있다.” 라고 설명하고 있다.
    • git stash 명령을 사용하게 되면 스택으로 새로운 보관장소 stash가 추가되고 현재 Working directory에서 작업중이었던 파일들을 추가된 stash에 보관한다.
      한마디로 “stash는 현재 작업상황을 임시적으로 보관하는 대피소” 역할을 한다고 할 수 있다.
  • 스택(stack)이란?
    • 스택은 일반적으로 데이터를 저장하고 검색하는데 사용되는 자료구조로 사용되는 단어로 후입선출(Last In, First Out, 이하 LIFO)의 방식을 따른다.
    • 이 스택이라는 자료구조는, Git에서도 stash를 쌓는 의미로 사용되어 stash 스택이라고 부른다.

stash 스택의 구조

  • stash 스택은 LIFO 방식을 따르므로 마지막에 추가된 stash가 먼저 나가게 된다.
  • stash의 순서를 명확히 구분짓기 위해 stash@{id} 라는 명칭을 사용한다.
  • 마지막에 추가된 stash는 stash@{0} , 그 전에 추가된 stash는 stash@{1} , 또 그 전에 추가된 stash는 stash@{2} 같은 패턴으로 id를 넘버링 한다.

※ 마지막에 추가된 stash의 id는 0번이다.

stash에 작업파일 보관

※ LIFO 방식에 따라 stash 스택에 새롭게 추가된 stash는 0번 id를 갖는다.

  • stash에 수정중인 작업파일 보관
    git stash   => 모든 작업 파일 보관
    git stash push / git stash push [파일명]   => 모든 작업 파일 또는 특정 파일만 보관
    공통 옵션 -m "메세지"   => 메세지 남김
    • git stash 명령어를 사용하여 현재 수정중인 작업파일들을 stash에 보관 할 수 있다.
    • git stash 명령어를 입력하면 현재 인덱스(Staging area) 및 작업 디렉토리(Working Directory)에 존재하는 추적 가능하고 수정된 모든 파일이 stash에 보관된다.
      여기서 눈여겨볼점은 ‘추적 가능, 수정된’이란 키워드다.
    • 기본적으로 stash에 보관되기 위한 조건은 추적가능하면서 수정된(Tracked & Modified) 파일이어야 한다.
      한번이라도 커밋내역이 있고 수정한 흔적이 있는 파일만 보관이 가능하다는 말과 같다.
    • 그렇다고 추적 불가능한(Untracked)파일은 stash에 보관이 불가능한건 아니다.
      인덱스에 추가(Staging)하여 Git이 추적을 시작하면 stash에 보관이 가능해진다.
    • git stash push [파일명] 명령어를 사용하여 특정 파일만 stash에 보관할 수도 있다.
    • 공통 옵션으로는 -m "메세지" 가 있으며 메세지를 남길 수 있다.

stash 보관 이후 작업 디렉토리의 상황

  • stash에 수정중이던 작업파일을 보관하게되면 이후 작업 디렉토리는 어떻게 변해있을까?
    • 먼저 stash에서는 현재 수정중이던 작업파일의 변경사항이 보관된다.
    • 그리고 작업 디렉토리에 있던 현재 수정한 내용이 최근 커밋시점의 내용으로 리셋된다.
    • 만약 추적되지 않는파일을 stash에 보관했었다면, Git은 그 파일의 최근 커밋 내용을 확인할 수 없으니 작업 디렉토리에서 파일이 사라져버리게 된다.

stash 내용 가져오기

※ LIFO 방식에 따라 마지막에 추가되었던 stash의 내용을 먼저 가져온다.
그리고 git stash pop을 사용했으므로 해당 stash는 삭제되고, 밑에 있던 stash가 0번 id를 갖는다.
가져온 모든 내용은 작업 디렉토리로 돌아가게 된다.

  • stash 스택에서 stash 내용 가져오기
    git stash apply   => 마지막에 추가된 stash 내용을 가져옴
    git stash apply stash@{id}   =>  특정 stash 내용을 가져옴
    ---------------------------------------------------------------------------
    git stash pop   => 마지막에 추가된 stash 내용을 가져오고 해당 stash 제거
    git stash pop stash@{id}   => 특정 stash 내용을 가져오고 해당 stash 제거
    • git stash apply 명령어는 stash 스택에서 마지막에 추가된 stash의 내용, 그러니까 stash@{0}을 가져온다.
      만약 명령어 뒤에 가져오고 싶은 stash 즉 stash@{id}를 입력한다면 특정 stash의 내용을 가져올 수도 있다.
      이 명령어의 특징은 stash를 가져와도 그 stash는 그대로 stash 스택에 남아 있다.
    • git stash pop 명령어는 stash의 내용을 가져오고 그 stash를 stash스택에서 제거까지 해주는 동작을 한다.
      이 명령어도 마찬가지로 뒤에 stash@{id} 를 붙이면 특정 stash의 내용을 가져오고 제거까지 하게 된다.

가져온 stash 내용의 도착지

  • stash에서 보관하던 파일 변경 사항을 작업 디렉토리로 가져오게 된다면 어떻게 될까?
    • stash에 있던 파일의 변경 사항이 이전의 작업 디렉토리/staging area 위치 및 브랜치에 상관없이 현재 브랜치의 작업 디렉토리로 돌아가게 된다. stash에 보관 당시 인덱스에 있었던 파일도 다시 현재 브랜치의 작업 디렉토리로 돌아간다는 뜻이다. 작업 디렉토리로 돌아간 변경사항은 원래 있었던 파일과 병합(merge)를 시도한다.
    • 쉽게 상황을 예로 들어 설명해보겠다.
      1. *a라는 브랜치에서 one.txt파일을 수정 및 저장
      2. staging area에 추가
      3. stash에 수정사항을 보관
      4. b라는 브랜치로 이동하여 stash의 내용을 가져옴
      5. a가 아닌 현재 b 브랜치, 그리고 staging area가 아닌 작업디렉토리로 one.txt파일의 수정사항이 불러와짐*
    • 직접 여러가지 케이스를 테스트하면서 병합 중 발생하는 여러가지 상황들을 발견하였다.
      • 보관 이후에 해당 파일을 가만히 냅두었다면?
        (파일 내용에 변화가 없을 경우)
        → stash에 보관하고 있던 변경사항이 정상적으로 파일에 적용된다.
      • 보관 이후에 해당 파일을 또 수정하고 저장해서 local change를 발생시켰다면?
        (커밋은 하지 않고 로컬에서만 파일 내용에 변화가 있을 경우)
        → 로컬에 변경사항이 있어서 병합을 할 수 없다는 오류문구가 출력된다.
        해결방안 : 현재 로컬 변경사항을 stash에 보관하거나 스테이징 또는 커밋한다.
        위의 해결방안은 현재 발생한 변경사항을 보호하는데에 목적이 있다.
      • 보관 이후 해당 파일에 새로운 커밋이 생겼다면?
        → 병합하려는 파일과 현재 파일간의 충돌(conflict)오류가 발생하여 충돌을 해결하는 작업이 시작된다.
        작업 완료 후 충돌을 해결하고 병합 커밋을 남긴다.

stash 스택 및 stash 내용 조회

git stash list   => 현재 stash 스택에 저장된 stash목록을 조회
---------------------------------------------------------------------------
git stash show   => 가장 최근에 추가된 stash에 저장된 파일명을 확인
git stash show stash@{id}    => 특정 stash에 저장된 파일명을 확인
공통옵션 -p    => 내용 변경사항까지 확인

stash 제거

git stash drop    => 가장 최근에 추가된 stash 제거
git stash drop stash@{id}    => 특정 stash 제거
---------------------------------------------------------------------------
git stash clear    => 모든 stash 제거
  • stash 제거는 주의해서 사용해야할 부분이다. 만약 stash에서 작업 디렉토리로 가져오지 않았는데도 제거해버린다면 stash 복구를 위해 귀찮은 과정을 거쳐야 한다.
    무조건 복구가 된다는 가정은 없으니, stash 제거는 신중을 가해야 한다.

결론

  1. stash는 현재 수정 중인 파일들을 임시적으로 보관하는 장소다.
  2. 생성된 stash는 stash 스택이라는 곳에 쌓이고, LIFO에 따라 마지막에 쌓인 stash가 먼저 나간다.
  3. 가져온 stash 안의 내용들은 작업 디렉토리 영역에 병합된다.
  4. 다른 브랜치에서 stash를 가져올 경우 상황에 따라 다양한 오류가 발생할 수 있다.

Reference

  1. git-scm 페이지 - Git 도구 - Stashing과 Cleaning
    (https://git-scm.com/book/ko/v2/Git-도구-Stashing과-Cleaning)
  2. 나만의 기록들 blog
    [GIT] 깃(Git) 스태시(stash) 사용하기 - 변경된 내용 임시 저장하기
    (https://mine-it-record.tistory.com/651)
    [GIT] 실수로 날려버린 Stash 복구하기
    (https://mine-it-record.tistory.com/685)
profile
안녕하세요.

0개의 댓글

관련 채용 정보