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 Rebase 오리진/브랜치 대 Git Rebase 오리진 브랜치
- Git의 특정 커밋으로 리베이스
- 명령줄에서 Git Rebase 사용
- Git의 원격 리포지토리 브랜치에서 변경 사항을 가져올 때 로컬 브랜치 리베이스
- 리베이스 Git 브랜치