Git squash
squash
다수의 커밋을 하나로 만들기
squash 옵션은 여러 개의 커밋을 하나의 커밋 이력으로 묶어주는 역할을 수행합니다.
우선 엄밀히 말하여 git squash
라는 명령어는 존재하지 않으며,
squash는 git rebase -i
(interactive rebase)명령어에서 제공하는 옵션을 의미합니다.
다음과 같이 login이라는 작업에 대해 3개의 커밋이 별도로 존재할 때
squash는 이것을 하나의 커밋 이력으로 만들어주는 역할을 합니다.
$ git log --oneline
b142b67 (HEAD -> feature/sample_logic) login function 1-3
86e7823 login function 1-2
bf3b110 login function 1-1
e6eb535 (origin/master, origin/develop, origin/HEAD, develop) init commit
현재 커밋 로그를 그래프로 나타내면 다음과 같습니다.
graph LR;
A["e6eb535 (init commit)"] -->B["bf3b110 (login function 1-1)"];
B["bf3b110 (login function 1-1)"] -->C["86e7823 (login function 1-2)"];
C["86e7823 (login function 1-2)"] -->D["b142b67 (login function 1-3)"];
squash를 이용하여 3개의 커밋을 하나의 새로운 커밋으로 만들 것이며, 이 과정을 마치고 나면 최종적으로 하나의 커밋 이력만 나타나게 됩니다.
graph LR;
A["e6eb535 (init commit)"] -->B["commit_hash (login function (3/3))"];
squash 적용해보기
local repository의 HEAD
가 가리키는 부분(login function 1-3
)을 포함하여 이전의 3개의 커밋에 대해 rebase를 수행할 것입니다.
$ git rebase -i HEAD~3
위 명령어를 입력하면 아래와 같은 화면이 나타납니다.
pick bf3b110 login function 1-1
pick 86e7823 login function 1-2
pick b142b67 login function 1-3
# Rebase e6eb535..b142b67 onto e6eb535 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# 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
squash를 수행하기 위해 pick
태그를 s
또는 squash
로 변경하고 저장 후 나가기(:wq)를 수행합니다.
pick bf3b110 login function 1-1
squash 86e7823 login function 1-2
squash b142b67 login function 1-3
...
새로운 vi 화면이 나타나게 되고 커밋 메시지를 수정할 수 있습니다.
# This is a combination of 3 commits.
# This is the 1st commit message:
login function (3/3)
# This is the commit message #2:
login function 1-2
# This is the commit message #3:
login function 1-3
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Aug 2 16:33:15 2020 +0900
#
# interactive rebase in progress; onto e6eb535
# Last commands done (3 commands done):
# squash 86e7823 login function 1-2
# squash b142b67 login function 1-3
# No commands remaining.
# You are currently rebasing branch 'feature/sample_logic' on 'e6eb535'.
#
# Changes to be committed:
# new file: login.cpp
#
커밋 메시지 수정하고 저장 후 나가기(:wq)를 수행하면 rebase가 수행되었다는 메시지가 출력됩니다.
$ git rebase -i HEAD~3
[detached HEAD e22cf33] login function (3/3)
Date: Sun Aug 2 16:33:15 2020 +0900
1 file changed, 4 insertions(+)
create mode 100644 login.cpp
Successfully rebased and updated refs/heads/feature/sample_logic.
git log
명령어를 통해 확인하면 하나의 커밋으로 만들어진 것을 확인할 수 있습니다.
$ git log --oneline
e22cf33 (HEAD -> feature/sample_logic) login function (3/3)
e6eb535 (origin/master, origin/develop, origin/HEAD, develop) init commit
graph LR;
A["e6eb535 (init commit)"] -->B["e22cf33 (login function (3/3))"];