git/git 연습

git stash, cherry-pick

backend dev 2024. 3. 22.

git stash

자신이 어떤 작업을 하던 중에 다른 요청이 들어와 하던 작업을 멈추고 잠시 브랜치를 변경해야 할 일이 있다고 하자. 이때, 아직 완료하지 않은 일을 commit하는 것은 껄끄럽다. 

 

그때 git stash를 사용한다.
아직 마무리하지 않은 작업을 스택에 잠시 저장할 수 있도록 하는 명령어이다. 

이를 통해 아직 완료하지 않은 일을 commit하지 않고 나중에 다시 꺼내와 마무리할 수 있다.

 

  • git stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일들만 저장한다.
  • stash란 아래에 해당하는 파일들을 보관해두는 장소 이다.
    • Modified이면서 Tracked 상태인 파일
      • Tracked 상태인 파일을 수정한 경우
      • Tracked: 과거에 이미 commit하여 스냅샷에 넣어진 관리 대상 상태의 파일
    • Staging Area에 있는 파일(Staged 상태의 파일)
      • git add 명령을 실행한 경우
      • Staged 상태로 만들려면 git add 명령을 실행해야 한다.
      • git add는 파일을 새로 추적할 때도 사용하고 수정한 파일을 Staged 상태로 만들 때도 사용한다.

 

git stash - 하던 작업 임시로 저장하기

 

위의 명령어를 통해 새로운 stash를 스택에 만들어 하던 작업을 임시로 저장한다.

 

연습해보기

 

main.txt : Staging Area에 있는 파일(Staged 상태의 파일)
memo.txt: Modified이면서 Tracked 상태인 파일

파일 2개를 수정하고 그 중 하나는 Staging Area에 추가한다. 

아직 작업 중인 2개의 파일은 commit할 게 아니기 때문에 모두 stash에 넣는다.

git stash
git stash save
git stash -m "메시지를남길수있다."

 

git stash 나 git stash save 를 실행하면 스택에 새로운 stash가 만들어진다. 

이 과정을 통해 working directory는 깨끗해진다.

 

 

stash 목록 확인하기

git stash list

여러 번 stash를 했다면 위의 명령어를 통해 저장한 stash 목록을 확인할 수 있다.

 

 

 

stash 적용하기(했던 작업을 다시 가져오기)

// 가장 최근의 stash를 가져와 적용한다.
$ git stash apply
// stash 이름(ex. stash@{2})에 해당하는 stash를 적용한다.
$ git stash apply [stash 이름]

 

위의 명령어로는 Staged 상태였던 파일을 자동으로 다시 Staged 상태로 만들어 주지 않는다. 

–index 옵션을 주어야 Staged 상태까지 복원한다. 

이를 통해 원래 작업하던 파일의 상태로 돌아올 수 있다.

// Staged 상태까지 저장
$ git stash apply --index

 

새로운 branch에 stash 적용하기

git stash branch "브랜치명"

새로운 브랜치를 만들어서 pop(적용 및 삭제)를 진행합니다.
기존 작업 내용과 stash한 내용이 충돌 할 가능성을 염두해 두고 새로운 branch를 만들어서
테스트해 볼 수 있습니다.

 

stash 제거하기

git stash drop
apply 옵션은 단순히 stash를 적용하는 것으로, 해당 stash는 스택에 여전히 남아있다. 

스택에 남아 있는 stash는 위의 명령어을 사용하여 제거할 수 있다.

// 가장 최근의 stash를 제거한다.
$ git stash drop
// stash 이름(ex. stash@{2})에 해당하는 stash를 제거한다.
$ git stash drop [stash 이름]

 

만약 적용과 동시에 스택에서 해당 stash를 제거하고 싶으면 git stash pop 명령을 사용하면 된다.

// apply + drop의 형태
$ git stash pop

 

 

stash 되돌리기

git stash show -p | git apply -R
실수로 잘못 stash 적용한 것을 되돌리고 싶으면 위의 명령어를 이용한다.

// 가장 최근의 stash를 사용하여 패치를 만들고 그것을 거꾸로 적용한다.
$ git stash show -p | git apply -R
// stash 이름(ex. stash@{2})에 해당하는 stash를 이용하여 거꾸로 적용한다.
$ git stash show -p [stash 이름] | git apply -R

 

 

stash-unapply라는 명령어를 등록하여 간단하게 사용할 수 있다

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
$ git stash apply
$ #... work work work
// alias로 등록한 stash 되돌리기 명령어
$ git stash-unapply

 

 

 

stash-unapply라는 명령어를 등록하여 간단하게 사용할 수 있다
https://gmlwjd9405.github.io/2018/05/18/git-stash.html

 

 


원하는 commit 가져오기

 

git을 이용해 코드 관리를 하다보면 커밋을 다른 브랜치에 잘못 하거나, 

요구사항이 바뀌어 필요 없는 커밋이 생기거나, 

코드 의존성(dependency) 때문에 다른 사람의 커밋 중 일부를 가져와야 하는 경우가 종종 생긴다.
이때 사용할수 있는 명령어가 cherry-pick 이다.

 

git cherry-pick 

git cherry-pick 명령어는 특정한 commit 하나만 콕 찝어서 현재 HEAD가 가리키는 branch에 추가할 수 있게 해준다.
쉽게 말해서 다른 branch에 있는 여러개의 commit들 중, 

원하는 commit을 지금 내 branch에 가져와서 commit 할 수 있는 것이다.

cherry pick이란, 체리 한 바구니에서 제일 좋은 체리만 고르는 것에서 유래한 표현이라고 한다.
일반적으로는 제일 좋은 걸 선별한다는 뜻으로 쓰인다. 

 

참고로 commit을 branch에서 다른 branch로 옮기는 건 아니고, 전체 history를 따지면 새로운 commit이 늘어나는 것이다.

 

💡 cherry-pick은 언제 써야 할까?

유용하긴 하지만 cherry-pick이 항상 권장되는 것은 아니라고 한다.
같은 commit이 여러 번 쌓이는 일도 발생할 수 있기 때문에 cherry-picking이 가능한 상황에서 보통은 일반적인 merge를 사용하는 걸 선호한다고 한다. 

그렇다면 cherry-pick은 어떤 상황에서 유용할까?

[팀으로 협업할 때]
만일 팀이랑 사이드 프로젝트를 진행하고 있다고 하자. 
본인는 백엔드다. 현재 내가 맡은 기능이 프론트까지 더해졌을 때 어떻게 돌아가는지 확인하고 싶은데 프론트엔드를 맡은 동료가 지금 한창 작업 중이라고 한다. 근데 아까 CSS 파일을 완성해서 commit해 뒀다고 한다. 
그럼 cherry-pick을 통해 그 commit 하나만 찾아서 내 branch에 가져오면 된다.  
CSS만 입혀볼 수 있게 되는 것이다.

[버그 수정]
본인은 며칠 전 A 기능을 완성한 개발자다. 
A가 끝나고 B 기능을 개발하는 중이었는데, 알고 보니 A 기능에 버그가 있다고 한다. 
더 많은 유저들이 이 버그로 인한 현상을 겪기 전에 빠르게 버그 패치를 해서 내 branch에 commit한다. 
방금 commit한 이 패치는 git cherry-pick을 통해 main branch에 바로 반영되었다.

[반영되지 않은 pr]
실수로 pull request를 merge하기 전에 닫아버렸다. 
당황하지 않고 git cherry-pick을 통해 해당 commit을 가져옴으로써 살릴 수 있게 됐다.

 

$ git cherry-pick <commit여섯자리번호>

 

 

예를들어, 위 처럼 현재 당신의 코드는 X 브랜치에 있고
당신은 브랜치 Y의 커밋 중 76ae30ef와 13af32cc만 골라 현재 브랜치인 X에 적용하고 싶다고 가정 하자.

# 하나씩 해도 되고
$ git cherry-pick 76ae30ef
$ git cherry-pick 13af332cc

# 인라인으로 한꺼번에 해도 된다.
$ git cherry-pick 76ae30ef 13af32cc

 

체리 픽을 하여 브랜치 X에 적용하면, 이전 커밋 수정사항이 X브랜치에 적용된다.


물론 겹치는 내용이 있으면 당연히 conflict가 일어나고, 수정 후 새로 커밋해야 한다.

76ae30ef와 13af32cc가 브랜치 X으로 복사 된 상황

 

 

 

git cherry-pick –continue / –abort

가끔 cherry-pick하려는 커밋과 내 브랜치 사이에 conflict이 발생 할 수있다.
그런 경우 두 가지 옵션이 있다. 
 
⭕ Conflict를 해결하고 cherry-pick을 진행시킨다.

Conflict을 해결하기 위해 코드를 수정한다.
git add <path> 명령어로 수정된 코드를 올린다. (커밋은 다시 할 필요 없다.)
git cherry-pick –continue 명령어를 사용하면 다시 진행이 시작 된다.

 
⭕ cherry-pick을 중단한다.

git cherry-pick –abort 명령어를 사용해 cherry-pick을 중단하면, cherry-pick을 하기 전 상태로 돌아 갈 수 있다.

 

git cherry-pick merge

만약 merge commit을 cherry-pick하고 싶다면 다음과 같은 명령어를 사용하면 된다
bash$ git cherry-pick -m 1 <merge_commit_hash>

 

 

 

 

 

 

 

 

 

 

'git > git 연습' 카테고리의 다른 글

git 롤백, git branch,pull request,fetch,rebase  (0) 2024.03.13
1 - Git 기초  (0) 2024.03.06

댓글