본문 바로가기
Git

Git] Command Line으로 실수를 되돌리는 17가지 방법![3] - rebase, fixup

by Fastlane 2022. 6. 22.
728x90
반응형

목차

  • 오래된 commit의 메시지 수정하기 (원격저장소로 push된 경우 사용하지 않는다!)
  • 오래된 commit 삭제 (원격저장소로 push된 경우 사용하지 않는다!)
  • 여러개의 commit을 한개로 합치자 (원격저장소로 push된 경우 사용하지 않는다!)
  • 오래된 commit을 수정하기 (원격저장소로 push된 경우 사용하지 않는다!)
  • 오래된 하나의 commit을 여러개의 commit으로 나누기 (원격저장소로 push된 경우 사용하지 않는다!)

13. 오래된 commit의 메시지 수정하기 

$ git rebase -i HEAD~3

...then use "reword" option

C2 commit의 메시지를 수정해보자. 

얼마나 돌아가야 하는지, base commit이 무엇인지 판단한다. C2를 수정하기 위해서는 적어도 C2이전의 commit으로 돌아가야 한다. 그럼 C1으로 돌아가보자. 

C4 -> C3 -> C2 -> C1 으로 3번의 commit을 역으로 돌아가야 한다. 

$ git log
commit 53a881c28cc27f7395f675a618d34b89b43283fc (HEAD -> main)
Date:   Fri May 27 15:53:15 2022 +0900

    Updated Azure Pipelinew to package build

commit 6814d57147e11aa7b5aeda88937ac814fe4ae42f
Date:   Fri May 27 14:53:59 2022 +0900

    Broken Unit test :(

commit 38990932782115c8481a289a08643f6c4cda6cc5
Date:   Fri May 27 14:37:01 2022 +0900

    Updated YAML file to run tests

commit 75a78ab7d4f4bc19af0d4973ca7a1ae84a0a6ca5
Date:   Fri May 27 14:35:21 2022 +0900

    Updated YAML file to run tests
$ git rebase -i HEAD~3

아래와 같이 오래된 순서로 commit history가 나온다. 

첫번째 line의 pick을 reword로 수정하고 save 한다. 

pick 3899093 Updated YAML file to run tests
pick 6814d57 Broken Unit test :(
pick 53a881c Updated Azure Pipelinew to package build

# Rebase 75a78ab..53a881c onto 75a78ab (3 commands)
reword 3899093 Updated YAML file to run tests
pick 6814d57 Broken Unit test :(
pick 53a881c Updated Azure Pipelinew to package build

# Rebase 75a78ab..53a881c onto 75a78ab (3 commands)

해당 3899093 commit message를 수정할 수 있는 창이 뜬다. 수정하고 저장한다. 

Updated YAML file to run tests

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri May 27 14:37:01 2022 +0900
#
# interactive rebase in progress; onto 75a78ab
# Last command done (1 command done):
#    reword 3899093 Updated YAML file to run tests
# Next commands to do (2 remaining commands):
#    pick 6814d57 Broken Unit test :(
#    pick 53a881c Updated Azure Pipelinew to package build
# You are currently editing a commit while rebasing branch 'main' on '75a78ab'.
#
# Changes to be committed:
#       modified:   azure-pipelines.yml

메시지가 수정된 것을 확인할 수 있다. 

[detached HEAD e4f5e59] Updated YAML file to run tests -> changed after
 Date: Fri May 27 14:37:01 2022 +0900
 1 file changed, 2 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/main.


$ git log
commit 8b0596130a1f1aaf1c551779fcb058985cd1dd16 (HEAD -> main)
Date:   Fri May 27 15:53:15 2022 +0900

    Updated Azure Pipelinew to package build

commit 00680e1e25238d451b37d8dde09570e4247cc0ef
Date:   Fri May 27 14:53:59 2022 +0900

    Broken Unit test :(

commit e4f5e59ecdcb7f07d8cdc326540d9218a632336b
Date:   Fri May 27 14:37:01 2022 +0900

    Updated YAML file to run tests -> changed after

commit 75a78ab7d4f4bc19af0d4973ca7a1ae84a0a6ca5
Date:   Fri May 27 14:35:21 2022 +0900

    Updated YAML file to run tests

14. 오래된 commit 삭제

$ git rebase -i HEAD~3

...and remove lines for unwanted commits

$ git log
commit ec3c1f42f4b1154c1f565cec7e962fdd380f21c0 (HEAD -> main)
Date:   Tue Jun 21 17:19:38 2022 +0900

    add service

commit 6de7fd0893914308d033249c91ea435804c772bc
Date:   Tue Jun 21 17:18:34 2022 +0900

    page change

commit 8b0596130a1f1aaf1c551779fcb058985cd1dd16
Date:   Fri May 27 15:53:15 2022 +0900

    Updated Azure Pipelinew to package build

page change commit을 삭제해보자. 

$ git rebase -i HEAD~2
pick 6de7fd0 page change
pick ec3c1f4 add service

# Rebase 8b05961..ec3c1f4 onto 8b05961 (2 commands)

삭제하려는 commit의 pick을 drop으로 변경하고 저장한다. 

drop 6de7fd0 page change
pick ec3c1f4 add service

# Rebase 8b05961..ec3c1f4 onto 8b05961 (2 commands)

git log로 삭제된 것을 확인할 수 있다. 

Successfully rebased and updated refs/heads/main.

$ git log
commit fafc9b700f039f7a04c40ad23e4246dc298ad891 (HEAD -> main)
Date:   Tue Jun 21 17:19:38 2022 +0900

    add service

commit 8b0596130a1f1aaf1c551779fcb058985cd1dd16
Date:   Fri May 27 15:53:15 2022 +0900

    Updated Azure Pipelinew to package build

15. 여러개의 commit을 한개로 합치자

$ git rebase -i HEAD~3

...then use "squash" option

git은 가능한 commit을 작은 수정단위로 자주 하는 것이 바람직하지만, 과도하게 많이 commit을 한경우 여러개를 하나로 합치는 것도 가능하다. 

$ git log
commit d61936fe985c83e2752a6c559e1fa4ed0a336cf1 (HEAD -> main)
Date:   Tue Jun 21 17:28:18 2022 +0900

    change appsetting

commit dda4e5cc7ef8e52645d860b23a4ca68112fd7f50
Date:   Tue Jun 21 17:27:27 2022 +0900

    add another service 2

commit 933b630d68ff4d7da4bb1df664a44fb24853127a
Date:   Tue Jun 21 17:26:40 2022 +0900

    add another service

commit fafc9b700f039f7a04c40ad23e4246dc298ad891
Date:   Tue Jun 21 17:19:38 2022 +0900

    add service

commit 8b0596130a1f1aaf1c551779fcb058985cd1dd16
Date:   Fri May 27 15:53:15 2022 +0900

    Updated Azure Pipelinew to package build

add service commits을 하나의 commit으로 합쳐보자. 

$ git rebase -i HEAD~4
pick fafc9b7 add service
pick 933b630 add another service
pick dda4e5c add another service 2
pick d61936f change appsetting

# Rebase 8b05961..d61936f onto 8b05961 (4 commands)

위에서부터 3개를 합쳐보자. 

pick fafc9b7 add service
sqhash 933b630 add another service
squash dda4e5c add another service 2
pick d61936f change appsetting

# Rebase 8b05961..d61936f onto 8b05961 (4 commands)

2번째, 3번째 commit이 1번째 commit으로 합쳐진다. 

아래 창에서 commit message를 입력한다. 

Combine 3 into 1
# This is a combination of 3 commits.
# This is the 1st commit message:

add service

# This is the commit message #2:

add another service

# This is the commit message #3:

add another service 2

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Jun 21 17:19:38 2022 +0900
#
# interactive rebase in progress; onto 8b05961
# Last commands done (3 commands done):
#    squash 933b630 add another service
#    squash dda4e5c add another service 2
# Next command to do (1 remaining command):
#    pick d61936f change appsetting
# You are currently rebasing branch 'main' on '8b05961'.
#
# Changes to be committed:
#       modified:   src/SimpleAPI/Program.cs
#

git log로 합쳐진 것을 확인해보자. 

[detached HEAD 3b77141] Combine 3 into 1
 Date: Tue Jun 21 17:19:38 2022 +0900
 1 file changed, 6 insertions(+)
Successfully rebased and updated refs/heads/main.

$ git log
commit 2b1cd346bb24bcf33aa845100be9e5be77b6be12 (HEAD -> main)
Date:   Tue Jun 21 17:28:18 2022 +0900

    change appsetting

commit 3b771418a8eb9cee06d5ffb09f421a138a1e634c
Date:   Tue Jun 21 17:19:38 2022 +0900

    Combine 3 into 1

    add service

    add another service

    add another service 2

16. 오래된 commit을 수정하기

$ git commit --fixup <target commit hash>

$ git rebase -i --autosquash HEAD~3

C2를 수정하는 과정은 아래와 같다. 

1) C2 commit에 실수가 있다.  

2) --fixup으로 C2의 수정사항이 포함된 새로운 commit C4를 추가한다. 

3) 수정사항이 C2에 반영되고, C4는 사라진다. (불필요한 commit이 사라진다!)

 

update program.cs commit을 수정해보자

$ git log
commit aec503e5f537e85d341283d33bd074806aa4e809 (HEAD -> main)
Date:   Wed Jun 22 09:44:33 2022 +0900

    update appsettings.json

commit 44fe4b4960cab7794d1f8c591d3cf5f85fb7029a
Date:   Wed Jun 22 09:41:22 2022 +0900

    update program.cs

수정사항을 add한 후 --fixup으로 commit한다. 

$ git add .
$ git commit --fixup 44fe4b4960cab7794d1f8c591d3cf5f85fb7029a
[main 5ead23e] fixup! update program.cs
 1 file changed, 3 insertions(+)
$ git log
commit 5ead23e9d23f81bc3ca654d3baba7f99c5e8bc2e (HEAD -> main)
Date:   Wed Jun 22 09:47:25 2022 +0900

    fixup! update program.cs

commit aec503e5f537e85d341283d33bd074806aa4e809
Date:   Wed Jun 22 09:44:33 2022 +0900

    update appsettings.json

commit 44fe4b4960cab7794d1f8c591d3cf5f85fb7029a
Date:   Wed Jun 22 09:41:22 2022 +0900

    update program.cs

rebase하여 target commit과 fixup commit을 squash 해보자

$ git rebase -i HEAD~3 --autosquash
pick 44fe4b4 update program.cs
fixup 5ead23e fixup! update program.cs
pick aec503e update appsettings.json

# Rebase 20ec6fe..5ead23e onto 20ec6fe (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 [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor

5ead23e commit은 순서상 맨 아래줄에 있어야 하지만(base commit기준으로 오래된 순으로 보임), fixup이기 때문에 자동으로 수정해야 하는 target commit 바로 아래에 위치하여 squash할 수 있도록 한다. 

 

fixup command자체가 바로 위 commit에 squash한다는 것이므로 수정할 것 없이 이 상태로 저장한다. 

Successfully rebased and updated refs/heads/main.

$ git log
commit c9e3de73bec665701c79fe0442d6d5b848c7ce77 (HEAD -> main)
Date:   Wed Jun 22 09:44:33 2022 +0900

    update appsettings.json

commit 1890eff0931922d9b131966342812ab903e198c7
Date:   Wed Jun 22 09:41:22 2022 +0900

    update program.cs

17. 오래된 하나의 commit을 여러개의 commit으로 나누기

$ git rebase -i HEAD~2

...then use "edit" option

$ git reset HEAD~1

make multiple commits

$ git rebase --continue

update program.cs commit에는 수정파일이 2개가 포함되어 있다.

하나의 파일씩 commit하여 2개의 commit으로 나누어보자. 

$ git log
commit c9e3de73bec665701c79fe0442d6d5b848c7ce77 (HEAD -> main)
Date:   Wed Jun 22 09:44:33 2022 +0900

    update appsettings.json

commit 1890eff0931922d9b131966342812ab903e198c7
Date:   Wed Jun 22 09:41:22 2022 +0900

    update program.cs

돌아가야 할 commit수를 확인한다, 2개만큼 rebase한다. 

$ git rebase -i HEAD~2

나누고 싶은 commit을 찾아 edit으로 수정하고 저장한다. 

pick 1890eff update program.cs
pick c9e3de7 update appsettings.json

# Rebase 20ec6fe..c9e3de7 onto 20ec6fe (2 commands)
edit 1890eff update program.cs
pick c9e3de7 update appsettings.json

# Rebase 20ec6fe..c9e3de7 onto 20ec6fe (2 commands)

reset을 사용하여 이전 commit으로 돌아간다. 

$ git reset HEAD~1
Unstaged changes after reset:
M       src/SimpleAPI/Controllers/WeatherForecastController.cs
M       src/SimpleAPI/Program.cs

하나의 파일씩 commit한다. 

$ git add Program.cs

$ git commit
[detached HEAD 240ff3d] commit only Program.cs
 1 file changed, 2 insertions(+)

$ git add .

$ git commit
[detached HEAD 7ae7795] commit only Controller.cs
 1 file changed, 3 insertions(+)

rebase를 종료한다. 

$ git rebase --continue
Successfully rebased and updated refs/heads/main.

나누어진 것을 확인한다. 

$ git log
commit bd6b42d2dce7bc19fbe1ea47514ac6e5b3974c82 (HEAD -> main)
Date:   Wed Jun 22 09:44:33 2022 +0900

    update appsettings.json

commit 7ae7795991ab980e7f32853a0c9283da32dd9ef9
Date:   Wed Jun 22 10:42:43 2022 +0900

    commit only Controller.cs

commit 240ff3d7167500bd48f361ef7734f5db3b3fc74b
Date:   Wed Jun 22 10:41:59 2022 +0900

    commit only Program.cs

 

728x90
반응형

댓글