rebase / commit --amend / merge --squash (스쿼시 머지)
정도로 볼 수 있다. 물론 때에 적절한 reset은 당연하다. 위 사항에 대해 rebase를 중점적으로 시작해 살펴보자. commit
을 정리하는 것은 우리가 언제든지 쉽게 rollback
할 수 있는 포인트를 만드는 것과 같다. 그리고 commit
이 난잡하면 코드 트레이싱을 하는 것 또한 굉장히 난해해 진다.commit
을 나만 알아보게 하면 된다. 하지만 여러명에서 다 같이, diff
를 살펴보고, 어떤 기능이 추가 되었는지, 또 에러가 발생할 경우 추적이 용이하게 하려면 이쁜 commit
을 만드는 것은 너무나 당연하다. 우린 그 부분을 체크해 볼 것 이다. 아직 와닿지 않는다면, (4)는 뛰어 넘고 우선 '원격 저장소' 까지 다 파악하고, 브랜치 몇개씩 파 보고, 작업 다양하게 해 본 뒤에, 다시 돌아오자!
git rebase target-branch
git rebase --continue
를 통해서 다음 commit 지점으로 병합을 계속 진행할 수 있다. git rebase --abort
로 rebase진행을 취소하고 제대로 체크한 뒤 다시 진행하자. (물론 무지성 continue후 revert(or reset)을 통해 되돌릴 수 있다.) --abort 옵션은 merge에서도 사용가능하다. squash
는 말 그대로 여러 커밋을 한 덩어리로 뭉쳐주는 방식이다. 작업 브랜치에서 여러 개의 커밋을 만들었지만, 최종적으로는 하나의 커밋으로 병합하고 싶을 때 유용하다.
특히 기능 단위 개발 후 main
또는 dev
브랜치로 병합할 때, 너무 많은 커밋이 남지 않도록 정리하는 데 자주 사용된다. (하나로 뭉치기 때문에 merge commit 기반으로 찾기도 주관적으로, 너무 편하다!)
git checkout main
git merge --squash feature/my-feature
--squash
옵션을 사용하면, feature/my-feature
브랜치의 변경 내용이 main 브랜치에 적용되지만, 커밋은 자동으로 생성되지 않는다. 이어서 아래 명령어로 최종 커밋을 만들어줘야 한다.git commit -m "feat: 기능 A 개발 완료 (squash)"
예! 다릅니다. https://git-scm.com/docs/merge-options/2.22.1 를 체크 해볼까요?!
일단 git merge --squash <대상 브랜치>
는 대상 브랜치의 변경 사항을 현재 브랜치에 적용하지만, 자동으로 커밋을 생성하지 않는다. 사용자는 변경 사항을 검토하고, git commit 명령어를 사용하여 수동으로 커밋을 생성해야 한다.
HEAD는 변경되지 않고, 병합 이력도 남지 않는다!! (non-merge commit).
항목 | git merge --squash (로컬 명령어) | GitHub의 "Squash and merge" (PR 버튼) |
---|---|---|
커밋 병합 방식 | 여러 커밋을 스쿼시해서 하나로 만들고 직접 커밋해야 함 | 여러 커밋을 스쿼시해서 하나로 만든 상태로 자동 커밋됨 |
브랜치 그래프 | 기존 브랜치 이력은 남지 않음 (단일 커밋으로 처리) | 마찬가지로 브랜치 이력이 단일 커밋으로 합쳐짐 |
사용 시점 | 로컬에서 직접 병합하기 전 | PR을 GitHub에서 머지할 때 |
커밋 작성 | 사용자가 직접 작성 | GitHub에서 자동 생성 또는 수정 가능 |
git commit --amend
실행하면 이전 커밋 메시지를 수정할 수 있는 편집창이 뜬다. 메시지만 바꾸거나, 혹은 변경된 파일이 있으면 그것까지 포함하여 커밋을 수정할 수 있다.
예를 들어 커밋 후 아래처럼 오타가 보였다고 하자.
git add .
git commit -m "fix: bux fix in login page" # 오타!
git commit --amend -m "fix: bug fix in login page" # 메시지 수정
git push --force
가 필요하므로, 공동 작업 브랜치에서는 주의해야 한다!!실수하지 않는 개발자는 없다. 중요한 건 실수했을 때 되돌릴 수 있는 능력이다. Git은 그걸 가능하게 해주는 강력한 도구다. 여기선
revert
,reset
,restore
를 중심으로, 언제 어떤 도구를 써야 하는지 살펴보자.
revert
는 이미 커밋된 내용을 되돌리는 방법 이다. 하지만 reset
처럼 커밋 자체를 없애는 게 아니라, "되돌리는 새 커밋을 만든다." (이게 정말 핵심이다.)
실수로 main
브랜치에 잘못된 커밋을 푸시했을 때, 공동 작업자가 많은 상황이라면 revert
가 안전한 선택이다.
git revert <commit-hash>
# 위 명령은 해당 커밋의 변경사항을 취소하는 커밋을 새로 만든다.
reset
은 커밋 자체를 삭제하거나, HEAD 포인터를 이전 상태로 되돌리는 방식이다.명령어 | 설명 |
---|---|
git reset --soft <commit> | 해당 커밋 시점으로 이동, 이후 커밋은 스테이징 상태로 보존 |
git reset --mixed <commit> | 기본 옵션. 커밋은 삭제하고 작업 파일은 유지 |
git reset --hard <commit> | 커밋도 삭제, 작업 파일도 해당 시점으로 완전 초기화 |
git reset --hard HEAD~2 # 마지막 두 커밋 제거 + 파일 상태도 되돌림
checkout
에서 분리된 명령어다.)git restore <파일명> # 작업 파일을 마지막 커밋 기준으로 되돌림
git restore --staged <파일명> # 스테이징 상태를 해제 (unstage)
# ex)
git restore hello.py # hello.py를 마지막 커밋 상태로 롤백
git checkout <file>
로 사용헀었다!