라즈베리파이반

라즈베리파이 등 컴퓨터계열 게시판입니다.

제목Git 튜토리얼 (3) - 리베이스 / 체리픽 / 리셋 / 리버트 / 스태쉬2022-09-26 07:27
작성자user icon Level 4

88x31.png


1. 리베이스(rebase)


리베이스(rebase)는 이름 그대로 커밋이 분기되는 base를 수정하는 작업입니다. 공통된 커밋으로부터 수정하려는 base 커밋까지의 차이점을 패치(patch)라는 공간에 임시로 저장하고 참조 커밋을 수정한 후 패치(patch)를 순차적으로 적용합니다.


저번 글에서 병합한 작업을 다음 상태로 되돌려 베이스가 수정되는 과정을 보겠습니다.


img27 


커밋은 다음 명령어를 통해 되돌릴 수 있습니다.

$ git reset --hard HEAD~2

$ git switch issue1

$ git reset --hard HEAD~2


우선 issue2 브랜치로 이동하여 rebase 명령어로 메인 브랜치를 base로 만듭니다.

$ git switch issue2

$ git rebase main


저번 상황과 마찬가지로 issue1과 issue2에서 동시에 같은 파일을 수정했기 때문에 패치를 만드는 과정에서 병합충돌이 발생했습니다.

img33


병합과 마찬가지로 test.txt 파일을 수정합니다.

임의의 내용 작성 1

내용 추가

브랜치 병합 테스트

issue1 내용 추가

issue2 내용 추가


스테이징 한 후 병합과는 달리 커밋을 하지 않고 rebase 명령어에 --continue 옵션을 주어 리베이스를 계속 진행하도록 합니다.

$ git add test.txt

$ git rebase --continue


그러면 커밋 메시지를 입력하는 에디터가 뜹니다. :wq를 입력하여 커밋을 생성합니다.

img34 


이제 메인 브랜치로 이동하여 fast-forward merge를 합니다. 병합과 비교해보면 issue2 브랜치에 있던 커밋이 main 브랜치로 베이스가 옮겨졌음을 확인할 수 있습니다.


병합의 경우

img30


리베이스의 경우

img35 


중간에 리베이스를 취소하려면 –continue 옵션 대신에 –-abort 옵션을 넣습니다.

$ git rebase --abort 


리베이스를 사용하면 커밋 히스토리가 한줄로 깔끔해지지만 이미 공개된 저장소에 push한 커밋을 리베이스하면 히스토리가 꼬일 수 있으므로 주의해야합니다.



2. 체리픽(cherry-pick)


체리픽(cherry-pick)은 리베이스와 유사하게 베이스를 변경하는 작업인데, 원하는 커밋만 pick해서 브랜치에 적용시키는 작업입니다.


issue1 브랜치로 이동하여 커밋을 2번 합니다.

$ git switch issue1

$ git merge main

$ git echo "issue1 체리픽1" >> test.txt

$ git commit -am "issue1 체리픽1"

$ git echo "issue1 체리픽2" >> test.txt

$ git commit -am "issue1 체리픽2"


로그를 통해 체리픽1 커밋의 해시를 확인합니다.

$ git log --oneline


img37


메인 브랜치로 이동하여 cherry-pick 명령어를 통해 체리픽 작업을 합니다.

$ git switch main

$ git cherry-pick [커밋 해시]


마찬가지로 패치(patch) 과정에서 충돌이 발생합니다.

img36 


test.txt 파일을 충돌나지 않도록 수정합니다.

임의의 내용 작성 1

내용 추가

브랜치 병합 테스트

issue1 내용 추가

issue2 내용 추가

issue1 체리픽1


저장하고 스테이징 후 --continue 옵션으로 체리픽을 계속 진행해주세요.

$ git add .

$ git cherry-pick --continue


다음과 같이 원하는 커밋만 브랜치에 가져왔습니다. 커밋을 새로 생성했기 때문에 커밋 해시가 다르다는 것을 볼 수 있습니다.

img38


중간에 체리픽을 취소하려면 --continue 옵션 대신에 --abort 옵션을 넣으면 됩니다.

$ git cherry-pick --abort

                                                                                                                                                                                                                                                                                                                                                   

3. 스쿼시(squash) 병합


체리픽과 유사한 작업이 병합의 --squash 옵션입니다. 스쿼시 옵션은 리베이스처럼 브랜치 베이스의 참조를 변경하지만, 리베이스가 베이스 이후로 브랜치 전체 커밋을 반영하는 것과 달리 스쿼시 병합은 브랜치의 커밋을 하나로 합쳐 체리픽처럼 새로운 하나의 커밋을 생성합니다.

$ git reset --hard HEAD~$ git merge --squash issue1 

$ git merge --squash issue1 


역시 충돌문제를 해결후 커밋을 해주면 병합이 진행됩니다.


충돌문제 해결

임의의 내용 작성 1

내용 추가

브랜치 병합 테스트

issue1 내용 추가

issue2 내용 추가

issue1 체리픽1

issue1 체리픽2


$ git commit -am "스쿼시 병합" 



4. 커밋 이력 되돌리기


커밋 상태를 과거로 되돌리는 명령어에는 reset revert가 있습니다.


reset은 헤드 자체를 과거로 옮겨 특정 커밋으로 되돌리는 작업을 하며, revert는 과거로 되돌린다는 이력을 남기고서 특정 커밋을 없던 것으로 하는 작업을 합니다.


reset의 옵션에는 --soft, --mixed, --hard가 있습니다.

--soft : 커밋을 하기 전단계인 스테이징 상태로 돌려놓습니다.

--mixed : 기본값으로 적용되며, 파일을 스테이징 이전단계로 돌려놓습니다.(파일이 작업 트리에 존재)

--hard : 추적 상태인 파일을 작업 트리에서 제거합니다. 즉, 파일을 수정하기 전으로 돌려놓습니다.


커밋 해시 대신에 헤드의 상대적인 수치로도 reset을 수행할 수 있습니다. 틸트(~숫자)의 경우 틸트로부터 숫자만큼 reset을 수행하며, 캐럿(^)의 경우 헤드로부터 한단계 아래 커밋으로 reset을 수행합니다.


예를 들어 아래 코드의 경우 2칸 이전의 커밋을 파일 수정 이전으로 되돌립니다.

$ git reset --hard HEAD~2 


revert는 하나의 커밋 상태로 되돌리며, 상태를 되돌릴때마다 revert 상태를 남기는 커밋을 생성합니다. 다음과 같이 여러 커밋에 대하여 revert 작업이 가능합니다.

$ git revert HEAD^ HEAD^^ 


깔끔한 이력을 원한다면 reset을, 커밋 수정 이력까지 남기고 싶다면 revert를 사용하시면 됩니다.



5. 스태쉬(stash)


스태쉬(stash)는 추적 상태에 있거나 스테이징 상태에 있는 파일을 임시로 저장하는 작업입니다. 추적 상태에 있거나 스테이징 상태인 파일이 있다면 다른 브랜치로 이동하지 못합니다. 이때 스태쉬를 통해 파일을 저장하고 다른 브랜치로 이동할 수 있습니다.


다음 명령어를 통해 새로운 스태쉬를 생성할 수 있습니다.

$ git stash


또는


$ git stash save


스태쉬 스택의 확인은 다음 명령어를 통해 확인할 수 있습니다. 리스트에서 스태쉬 이름을 확인할 수 있습니다.

$ git stash list


스태쉬의 적용은 apply 명령어를 통해 적용할 수 있습니다. 스태쉬를 생성한 브랜치 뿐만 아니라 다른 브랜치에도 적용가능합니다.

$ git switch issue2

$ git stash apply stash@{0}


옵션 없이 적용하면 스테이징 상태에 있던 파일도 추적 상태로 적용되지만, --index 옵션을 준다면 스테이징 상태에 있던 파일은 스테이징 상태 그대로 적용됩니다.


drop 명령을 사용하면 스태쉬를 스택에서 삭제하며, pop 명령을 사용하면 스태쉬를 적용하고 스택에서 삭제합니다.

$ git stash drop stash@{0} 

#git# rebase# cherry-pick# squash merge# reset# revert# stash
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)