Study/기타

[Git] 터미널을 이용한 Git squash 작업 (rebase)

hyjang 2025. 4. 10. 10:21
728x90

들어가며

회사 프로젝트 내 dev 브랜치와 stage 브랜치의 싱크로율이 달라, stage 브랜치 기준으로 작업건을 체리픽하여 배포하는 작업이 필요했다.

하여 아래처럼 한 브랜치에서 여러번 커밋 + 머지를 한 경우, 하나의 커밋으로 스쿼시하여 체리픽하면 운영 배포 관리에 유용할 수 있어 Git squash에 대해 알아봤다.

💡 중요한 커밋들이 있는 브랜치라면 rebase전에 백업 브랜치를 생성하는 것을 추천

 


 

🍀 git 명령어

- develop 브랜치에 머지하지 않은 브랜치 스쿼시(해당 브랜치 커밋만 스쿼시해줌)

git rebase -i develop

- 이미 develop 브랜치에 머지한 브랜치 스쿼시

git rebase -i Head~합칠 커밋 갯수
  • 3개의 커밋을 합치고 싶다면 git rebase -i Head~3 으로 진행한다.
  • Head는 현재 checkout 되어있는 브랜치의 가장 최근 커밋을 가리킨다.
git rebase -i 커밋 해시
  • 브랜치를 생성한 기준으로 커밋 해시를 작성합니다.

A 부분의 커밋 해시를 작성하면 B 커밋 기준으로 스쿼시 시작
첫 커밋 = B 커밋

 

p 또는 pick 해당 커밋 그대로 사용 (기본값)
s 또는 squash 현재 커밋을 이전 커밋과 합치고 커밋 메시지도 합침
d 또는 drop 해당 커밋 제거
r 또는 reword 커밋 메시지를 수정
e 또는 edit 해당 커밋에서 멈추고 수정 기회 제공
f 또는 fixup 현재 커밋을 이전 커밋과 합치지만 메시지는 버림

 

예시

💡 브랜치에 남기고 싶지 않은 커밋은 drop 으로 제거할 수 있다.
    결과물은 pick 으로 작성한 커밋만 남은 브랜치가 만들어진다.

 

 

🍀 vim 명령어

  • esc와  i 로 vim 명령어 입력 상태를 바꿀 수 있다.
i 입력 모드 시작(insert mode)
esc 입력 끝내기 (vim 명령어 입력 모드 시작)
:wq 또는 zz 저장 + 종료 = 리베이스 계속 진행
:q 변경 없이 나가기 (변경이 있으면 안 나가짐)
:q! 강제 종료 (변경 무시하고 나가기)
dd 한 줄 잘라내기 (cut)
yy 한 줄 복사
p 아래쪽에 붙여넣기
P 위쪽에 붙여넣기
u 행동 취소(undo)
Ctrl + r 다시 실행(undo를 취소)
💡 dd 를 사용하여 squash 하고 싶은 커밋을 잘라내고, 합치고 싶은 커밋 아래에 붙여넣을 수 있다.

esc -> :wq 입력 후 엔터

 

 

🍀 커밋 메시지 정리

  • :wq + 엔터로 넘어왔다면, 다시  i 를 눌러 입력 모드(insert mode)로 전환한다.
💡 커밋 메시지 앞에 ‘#’ 을 기재해주면 메시지를 주석처리 할 수 있다.

 

💡  커밋 메시지를 새로 적고 싶다면 맨 윗줄에 작성한다. (주석들은 지워도 된다.)

완성 후 esc -> :wq -> 엔터
결과

 

🍀 강제 푸시

💡  스쿼시를 완료하면 기존 커밋은 없어지고, 스쿼시한 커밋만 남지만
     git reflog를 이용해 HEAD 기록에 있는 기존 브랜치로 되돌릴 수 있다. (맨 처음에 백업 추천)

Pull 받지 않고 강제 푸시를 진행하면 스쿼시한 커밋만 남게 된다.

 

 

🍀 그 외

- 스쿼시는 언제 쓰는가?

  • PR 또는 푸시 전에 히스토리를 깔끔하게 정리하고 싶을 때
  • 기능 하나의 관련된 작업들을 하나의 커밋으로 만들고 싶을 때
  • 커밋이 너무 잘게 쪼게졌을 때

(내 경우에는 이미 merge를 진행한 커밋들을 하나로 만들어 배포 브랜치에 체리픽 하기 위해 스쿼시를 진행했다.)

 

- 스쿼시 후에 어디에도 속하지 않은 브랜치가 단독으로 생성됐는데, 기존 브랜치와 같은 브랜치인 것인가?

  • 히스토리가 바뀐 다른 브랜치다.
  • 스쿼시 후엔 커밋 해시도 달라지고, Git 입장에서는 새로운 브랜치로 인식되기 때문에 이전 커밋들은 해당 브랜치에 존재하지 않는다.

- 브랜치 이름이 같을 수 있나?

  • 이름은 같게 유지될 수 있다.(위치만 바뀜)

- 기존 브랜치로 돌아갈 수 있나?

  • git reflog를 이용해 Head에 기록되어 있는 기존 브랜치로 돌아갈 수 있지만, 맨 처음에 백업하는 것을 추천한다.
    ( git reflog 해보려다 실패함..)

- 요약표

상황 기존 브랜치 상태
브랜치 위에서 리베이스 기존 커밋 히스토리는 없어짐 (reflog에만 존재)
새 브랜치에서 리베이스 (백업) 기존 브랜치 그대로 유지됨
기존 브랜치에 강제 덮어쓰기 (reset) 기존 히스토리 완전 날아감