🗜️ Git Squash - 지저분한 커밋 로그, 한 방에 정리하는 법
O--O--O--O (Before)
|
▼
O----------O (After)
작업하다 보면 "WIP", "fix: 사소한 수정", "임시 저장" 같은 커밋들이 쌓여 git log
가 지저분해진 경험, 다들 한 번쯤 있으시죠? 나중에 히스토리를 다시 볼 때 어떤 변경사항이 왜 일어났는지 파악하기 어려워집니다. 이 지저분한 커밋들을 하나의 의미 있는 단위로 깔끔하게 합칠 수는 없을까요?
이 글을 읽으면 Git의 Squash 기능을 사용해 여러 커밋을 하나로 병합하여, 누가 봐도 이해하기 쉬운 커밋 히스토리를 만드는 세 가지 방법을 익히게 됩니다.
⚡ TL;DR
- Git Squash는 여러 개의 커밋을 하나의 의미 있는 커밋으로 합치는 기능입니다[1].
- 주로
git rebase -i
명령어를 사용하며, 상황에 따라merge --squash
나reset --soft
도 유용합니다[4][6].
목차
- 배경: Git Squash, 왜 필요할까요?
- 핵심 개념: Squash는 '짓누르기'
- 실전! Git Squash 사용법 (3가지)
- 상황별 모범 사례
- 마치며 & 참고자료
1. 배경: Git Squash, 왜 필요할까요?
기능 하나를 개발하더라도 여러 번에 걸쳐 커밋하게 됩니다. 이 과정에서 생긴 자잘한 커밋들이 모두 히스토리에 남으면 로그가 복잡해지고 가독성이 떨어집니다[1]. Squash는 이렇게 분산된 커밋들을 하나의 완성된 기능 단위로 묶어주어, 동료 개발자들이 코드 리뷰를 하거나 미래의 내가 히스토리를 추적할 때 훨씬 수월하게 만들어 줍니다.
✅ 관련 용어 정리
- Squash: '짓누르다', '으깨다'라는 뜻으로, Git에서는 여러 커밋을 하나로 합치는 작업을 의미합니다[3][5].
- Commit: 코드 변경 사항을 저장하는 특정 시점의 스냅샷입니다.
- HEAD: 현재 작업 중인 브랜치의 가장 마지막 커밋을 가리키는 포인터입니다.
- Rebase: 커밋들의 기준점(base)을 다른 커밋으로 옮겨 히스토리를 재정렬하는 작업입니다[5]. Squash는 이 Rebase의 대화형(interactive) 옵션을 통해 주로 수행됩니다[2][5].
2. 핵심 개념: Squash는 '짓누르기'
Git Squash는 여러 개의 분산된 커밋을 하나의 의미 있는 커밋으로 압축하여 커밋 히스토리를 깔끔하게 관리하는 기법입니다[1][3][7].
엄밀히 말해 git squash
라는 단독 명령어는 없습니다[2][5]. 대신 git rebase
명령어에 -i
(interactive) 옵션을 붙여 커밋 목록을 직접 편집하는 방식으로 사용합니다[5][6].
# HEAD(최신 커밋)로부터 이전 3개의 커밋을 합치고 싶을 때
$ git rebase -i HEAD~3
위 명령을 실행하면 아래와 같이 텍스트 편집기가 열리며, 여기서 각 커밋에 대한 작업을 지정할 수 있습니다[5].
pick 7c65355 기능 A의 첫 번째 부분
pick 2639543 기능 A의 두 번째 부분
pick d442427 기능 A의 마지막 수정
# Commands:
# p, pick = use commit
# s, squash = use commit, but meld into previous commit
# ...
3. 실전! Git Squash 사용법 (3가지)
① 가장 일반적인 방법: git rebase -i
가장 보편적이고 세밀한 제어가 가능한 방법입니다[6].
- 합칠 커밋 확인:
git log --oneline
명령으로 합치고 싶은 커밋들을 확인합니다. - 대화형 Rebase 실행: 합치고 싶은 커밋의 개수를 지정하여 명령어를 실행합니다. 예를 들어 최근 3개를 합치려면
git rebase -i HEAD~3
을 입력합니다[6]. - Squash 대상 지정: 편집기가 열리면, 합쳐질 커밋(두 번째, 세 번째) 앞의
pick
을s
또는squash
로 변경하고 저장합니다[5][6]. 맨 위의 커밋은 기준이 되므로pick
으로 그대로 둡니다[5]. pick 7c65355 기능 A의 첫 번째 부분 s 2639543 기능 A의 두 번째 부분 s d442427 기능 A의 마지막 수정
- 커밋 메시지 수정: 저장하면 새로운 편집기가 열리며, 합쳐진 커밋들의 메시지가 모두 표시됩니다[5]. 이 내용을 바탕으로 하나의 명확한 최종 커밋 메시지를 작성하고 저장합니다.
- 결과 확인:
git log --oneline
으로 커밋들이 하나로 합쳐졌는지 확인합니다. - (주의) 원격 저장소에 Push: 만약 이미 원격 저장소에 Push했던 커밋들이라면, 히스토리가 변경되었으므로 강제 푸시(
git push origin +브랜치명
또는git push --force
)가 필요합니다[5]. 협업 중인 브랜치에서는 팀원과 반드시 상의 후 진행해야 합니다.
② 브랜치 병합 시 유용한: git merge --squash
피처(feature) 브랜치의 모든 커밋을 메인 브랜치에 단 하나의 커밋으로 합치고 싶을 때 유용합니다[6].
- 메인 브랜치로 이동:
git checkout main
- Squash Merge 실행:
git merge --squash feature-branch
를 실행합니다[6]. 이 명령은feature-branch
의 모든 변경사항을main
브랜치의 Staging Area로 가져오지만, 자동으로 커밋하지는 않습니다. - 커밋 생성:
git commit -m "신규 로그인 기능 구현"
과 같이 하나의 커밋 메시지를 작성하여 커밋합니다[6].
③ 가장 간단한 방법: git reset --soft
최신 커밋 몇 개를 빠르고 간단하게 합치고 싶을 때 사용하는 방법입니다[4].
- Soft Reset 실행:
git reset --soft HEAD~3
명령을 실행하면, HEAD 포인터는 3개 커밋 이전으로 돌아가지만, 그동안의 모든 변경사항은 Staging Area(커밋 직전 단계)에 그대로 보존됩니다[4]. - 새로운 커밋 생성:
git commit -m "3개 커밋을 하나로 합친 새 커밋"
명령으로 Staging Area의 모든 변경사항을 하나의 커밋으로 만듭니다[4].
4. 상황별 모범 사례
방법 | 장점 | 주의점 |
---|---|---|
rebase -i |
커밋을 선별적으로 합치거나 순서를 바꾸는 등 세밀한 제어가 가능합니다[6]. | 히스토리를 직접 재작성하므로 충돌이 발생할 수 있으며, 초보자에게는 과정이 다소 복잡하게 느껴질 수 있습니다. |
merge --squash |
브랜치의 모든 작업을 대상 브랜치에 하나의 깔끔한 커밋으로 통합할 때 매우 유용하고 직관적입니다[6]. | 피처 브랜치의 세부적인 커밋 히스토리가 남지 않으며, 개별 커밋에 대한 제어가 불가능합니다[6]. |
reset --soft |
가장 빠르고 직관적인 방법으로, 최근 N개의 커밋을 합치는 단순한 시나리오에 최적화되어 있습니다[4]. | 커밋 메시지를 새로 작성해야 하며, 복잡한 히스토리 정리에는 적합하지 않습니다. |
5. 마치며
- Git Squash는 지저분한 커밋 히스토리를 깔끔하게 만드는 강력하고 필수적인 도구입니다.
- 가장 많이 쓰이는
rebase -i
외에도merge --squash
,reset --soft
등 상황에 맞는 다양한 방법이 존재합니다. - 이미 원격 저장소에 공유된 히스토리를 수정할 때는 반드시
force push
의 위험성을 인지하고 팀원과 소통해야 합니다[5].
💡 실제 프로젝트 적용 팁: Pull Request(PR)를 올리기 전, 로컬 브랜치의 자잘한 커밋들을 기능 단위로 Squash하여 리뷰어가 변경 사항을 한눈에 파악하기 쉽게 만들어주세요.
도움이 되셨다면 ❤️와 댓글 부탁드려요! 궁금한 점은 언제든 질문해주세요.
참고자료
- Stack Overflow: How do I squash my last N commits together [4]
- DataCamp: Git Squash Commits: A Guide With Examples [6]
- velog: Git Squash: 커밋 기록 깔끔하게 관리하기 [1]
- DevOcean: Git Squash - 여러 개의 Commit들을 합쳐보자 [3]
[1] Git Squash: 커밋 기록 깔끔하게 관리하기 - velog https://velog.io/@lgs03042/Git-Squash-%EC%BB%A4%EB%B0%8B-%EA%B8%B0%EB%A1%9D-%EA%B9%94%EB%81%94%ED%95%98%EA%B2%8C-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0
[2] git squash - 여러개의 커밋로그를 하나로 묶기 https://meetup.nhncloud.com/posts/39
[3] Git Squash - 여러 개의 Commit들을 합쳐보자 - DevOcean https://devocean.sk.com/blog/techBoardDetail.do?ID=166576&boardType=techBlog
[4] How do I squash my last N commits together? - Stack Overflow https://stackoverflow.com/questions/5189560/how-do-i-squash-my-last-n-commits-together
[5] [Git] squash commits already pushed - 여러 커밋 하나로 만들기 https://syntaxsugar.tistory.com/entry/Git-squash-commits-already-pushed
[6] Git Squash Commits: A Guide With Examples - DataCamp https://www.datacamp.com/tutorial/git-squash-commits
[7] How to Squash Commits in Git | Learn Version Control with Git https://www.git-tower.com/learn/git/faq/git-squash
[8] [Git] Git rebase, Git squash로 커밋 정리하기 - 빠르고 꾸준하게 https://resilient-923.tistory.com/358
[9] Git squash로 여러 커밋을 하나로 만들기 - Deku https://deku.posstree.com/ko/git/git-squash/
[10] How to Squash commits with Git Bash - Emily Lahren https://emilylahren.com/2024/11/how-to-squash-commits-with-git-bash/