Git 스쿼시 커밋

Azhar Bashir Khan 2023년1월30일
  1. 대화형 git rebase 도구를 사용하여 Git 커밋 스쿼시
  2. git merge -squash를 사용하여 Git 커밋 스쿼시
Git 스쿼시 커밋

이 튜토리얼에서 Git 스쿼싱을 배울 것입니다. 기본 아이디어는 여러 개의 연속 커밋을 가져와 하나로 묶는 것입니다.

주요 의도는 많은 커밋을 몇 가지 관련 커밋으로 압축하는 것입니다. 따라서 이렇게 하면 git 기록이 간결하고 명확해집니다.

그것을 보는 또 다른 방법은 우리가 어떤 작업과 관련된 여러 커밋을 수행한다는 것입니다. 잠시 후 만족스러운 상태에 도달하면 많은 커밋 메시지가 git 기록을 어지럽힙니다.

이 시점에서 git 기록이 명확하게 보이고 완료된 작업을 가장 잘 반영하도록 다른 커밋을 하나로 결합할 수 있습니다.

또 다른 사용 사례는 분기 병합을 수행하는 동안 스쿼싱을 수행하는 것입니다. 일반적으로 일부 기능 개발을 위해 기본 분기에서 기능 분기를 만듭니다.

기능 완료 후 기능 분기를 메인 분기에 병합합니다. 여기에서도 메인 브랜치에 병합할 때 기능 브랜치에서 수행된 다양한 커밋 메시지를 하나로 스쿼시할 수 있습니다.

git squash 명령은 없습니다.

Git 스쿼싱을 달성하는 두 가지 방법이 있습니다.

  • 커밋을 스쿼시하는 데 사용되는 대화형 도구인 git rebase -i
  • 병합하는 동안 -squash 옵션을 사용하여 git merge -squash

대화형 git rebase 도구를 사용하여 Git 커밋 스쿼시

우리가 스쿼싱에 관심이 있는 HEAD의 마지막 4개 커밋을 보여주는 다음 git 로그 발췌문을 고려하십시오.

25c38c4 remove .class files
da66e6a Delete version.ini
f4e3f09 Delete .log
b0e6655 Delete .lock
da66e6a github git notes

로그에서 관련 없는 다른 파일을 삭제하는 작업을 나타내는 처음 4개의 커밋 메시지를 볼 수 있습니다. 이제 이 4개의 커밋을 하나로 묶을 것입니다.

다음은 대화형 리베이스 도구를 사용하여 마지막 X 커밋을 스쿼시하는 명령 구문입니다.

git rebase -i HEAD~[X]

따라서 4개의 커밋을 스쿼시하려면 아래와 같이 합니다.

$ git rebase -i HEAD~4

이 명령을 실행한 후 Git은 아래와 같이 squash에 대한 커밋 세부 정보와 함께 기본 편집기를 호출합니다.

pick b0e6655 Delete .lock
pick f4e3f09 Delete .log 
pick da66e6a Delete version.ini
pick 25c38c4 remove .class files

# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

편집기는 pick 명령으로 다양한 커밋을 보여줍니다. 또한 사용 가능한 명령에 대한 정보도 표시합니다. squash(또는 s) 명령을 사용할 것입니다.

아래와 같이 pick 명령으로 첫 번째 커밋을 유지하고 나머지 세 커밋에 대해 pick에서 s(스쿼시용) 명령으로 변경합니다.

pick b0e6655 Delete .lock
s f4e3f09 Delete .log 
s da66e6a Delete version.ini
s 25c38c4 remove .class files

# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
...

squash(또는 s)로 표시된 커밋은 기본 커밋 비주얼리제이션에 병합됩니다. pick으로 표시된 것.

이제 편집기에서 변경 사항을 저장하고 종료합니다. 그런 다음 rebase -i 도구는 다음과 같이 커밋 메시지를 입력하기 위해 다른 편집기를 엽니다.

# This is a combination of 4 commits. The first commit's message is:

Delete .lock

# This is the 2nd commit message:

Delete .log 

# This is the 3rd commit message:

Delete version.ini

# This is the 4th commit message:

remove .class files

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Jan 3 16:39:23 2021 +0530
#
# interactive rebase in progress; onto 652d2fe
# Last commands done (4 commands done):
#    pick b0e6655 Delete .lock
#    s f4e3f09 Delete .log 
#    s da66e6a Delete version.ini
#    s 25c38c4 remove .class files
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on '652d2fe'.
#
# Changes to be committed:
#       new file:   github-git-notes.txt
#

이제 첫 번째 커밋 메시지 맨 위에 새 커밋 메시지를 추가합니다.

Deleted irrelevant files

# This is a combination of 4 commits. The first commit's message is:

Delete .lock

# This is the 2nd commit message:

Delete .log
...

저장하고 편집기를 종료한 후 rebase -i 도구는 다음 메시지를 인쇄합니다.

HEAD~2
Rebasing (2/2)


[detached HEAD caab6e8] Deleted irrelevant files
 Date: Sun Jan 3 16:39:23 2021 +0530
 1 file changed, 54 insertions(+)
 create mode 100644 github-git-notes.txt
Successfully rebased and updated refs/heads/master.

이제 git log를 확인하고 4개의 커밋 메시지 대신 squashed 커밋(즉) 단일 커밋 메시지를 확인합니다.

$ git log --oneline
25c38c4 Deleted irrelevant files
da66e6a github git notes
...

git merge -squash를 사용하여 Git 커밋 스쿼시

다음은 현재 분기(보통 main)와 분기를 병합하고 소스 분기의 커밋을 스쿼시하는 명령 구문입니다.

git merge --squash <source_branch_name_to_squash>

이제 기능 브랜치를 병합합니다. main 분기로 스쿼싱하는 feature1.

먼저 main 브랜치로 checkout합니다.

$ git checkout main
Switched to branch 'main'

그런 다음 다음과 같이 squash 옵션을 사용하여 git merge를 수행합니다.

$ git merge --squash feature1
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

--squash 옵션을 사용하여 merge를 수행하면 Git은 일반 병합에서와 같이 대상 분기에 병합 커밋을 생성하지 않습니다. 대신 Git은 소스 브랜치의 모든 변경 사항을 가져옵니다. feature1을 만들고 대상 분기 즉, 작업 복사본의 로컬 변경 사항으로 넣습니다. “기본”.

아래를 참조하십시오.

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   config.ini

여기에서 config.ini 파일에는 feature1 분기에서 수행된 변경 사항이 있습니다.

이제 아래와 같이 main 브랜치에 변경 사항을 커밋하는 일만 남았습니다.

$ git commit -am 'Merged and squashed the feature1 branch changes'
[main 573b923] Squashed and merged the feature1 branch
 1 file changed, 4 insertions(+)

따라서 이제 feature1 분기의 변경 사항을 main 분기로 병합하고 feature1 분기의 커밋 메시지를 스쿼싱합니다. 이제 main 브랜치에는 하나의 커밋 메시지만 있습니다.

관련 문장 - Git Rebase

관련 문장 - Git Merge