Git은 기록(커밋)을 변경하는 도구를 제공하진 않지만, rebase를 이용하는 방법은 제시하고 있다.
rebase의 주목적은 커밋 기록을 선형으로 만들기 위함.
6개(C1~C6) 커밋이 있고, C4 커밋을 수정하는 과정은 아래와 같다.
, C6
)예제를 위한 선행 커밋 상태
(예제 github: https://github.com/owljoa/git-study)
순서 | commit hash | 기본값 |
---|---|---|
1 | f90bb27 | add file1.txt |
2 | 0640343 | add file2.txt |
3 | 8180ad4 | add file3.txt |
4 | f2cb8d1e | modify file1.txt |
5 | 5de25f75 | modify file2.txt, file3.txt |
6 | 41420152 | modify file2.txt |
4번 커밋 수정사항
# 4번 커밋 이전 file1.txt
[빈 파일]
# 4번 커밋 이후 file1.txt
I'm file1.txt!
- 목표: file1.txt를 수정한 4번 커밋 기록 지우기
베이스 커밋을 4번 커밋의 바로 이전 커밋인 3번 커밋으로 지정하여 interactive 모드로 rebase 시작
git rebase -i 8180ad4
or
git rebase --interactive 8180ad4
지정한 베이스 커밋 이후 커밋들에 어떤 타입의 작업을 할지 명령어(command)를 지정하는 vi 에디터가 열림
# 베이스 커밋 이후에 쌓여있던 커밋들에 대해 실행할 명령어 결정 (명령어가 작업 종류를 결정함)
# pick f2cb8d1 modify file1.txt -> **drop** f2cb8d1 modify file1.txt
drop f2cb8d1 modify file1.txt
pick 5de25f7 modify file2.txt, file3.txt
pick 4142015 modify file2.txt again
# Rebase 8180ad4..4142015 onto 8180ad4 (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
# vi 에디터에서 저장 후 종료했을 때 성공 시 출력되는 문구
Successfully rebased and updated refs/heads/rebase_delete_commit.
# git log 명령으로
git log
commit 3109b93b097d214b42f7fddafa3f3546d19ffbc3 (HEAD -> rebase_delete_commit)
Author: owljoa <needshield@gmail.com>
Date: Wed Apr 7 21:04:12 2021 +0900
modify file2.txt again
commit e97f2ac91a391618e550d2714858f5667d636868
Author: owljoa <needshield@gmail.com>
Date: Wed Apr 7 21:03:37 2021 +0900
modify file2.txt, file3.txt
~~commit f2cb8d1ea78784c8796aebfe6953d0d8ce72a21d
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 21:03:05 2021 +0900
modify file1.txt~~
commit 8180ad4499153ce949bcbe6f13276e1a320f1b6f
Author: owljoa <needshield@gmail.com>
Date: Wed Apr 7 21:00:47 2021 +0900
add file3.txt
commit 064034361e01095b88026ff1a1cf887e6c8dcfeb
Author: owljoa <needshield@gmail.com>
Date: Wed Apr 7 21:00:06 2021 +0900
add file2.txt
commit f90bb2717944fecf39bd4f4597625f402620e0f0
Author: owljoa <needshield@gmail.com>
Date: Wed Apr 7 20:57:00 2021 +0900
add file1.txt
- 목표: 4번 커밋에서 추가된 텍스트를 "Hello World"로 변경
베이스 커밋을 4번 바로 이전 커밋인 3번 커밋으로 지정하여 interactive 모드로 rebase 시작
git rebase -i 8180ad4
or
git rebase --interactive 8180ad4
지정한 베이스 커밋 이후 커밋들에 어떤 작업을 할지 명령어를 지정하는 vi 에디터가 열림
# 베이스 커밋 이후에 쌓여있던 커밋들에 대해 실행할 명령어 결정 (명령어가 작업 종류를 결정함)
# pick f2cb8d1 modify file1.txt -> edit f2cb8d1 modify file1.txt
edit f2cb8d1 modify file1.txt
pick 5de25f7 modify file2.txt, file3.txt
pick 4142015 modify file2.txt again
# Rebase 8180ad4..4142015 onto 8180ad4 (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
edit를 설정한 커밋 이후의 시점에 멈춘 상태 확인
➜ git-study (rebase_edit_commit) ✔ git rebase -i 8180ad4
Stopped at f2cb8d1... modify file1.txt
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
이전 커밋(4번 커밋) 되돌리기
# 커밋 되돌리기
git reset HEAD~
# 확인 (4번 커밋의 변경사항은 비어있던 file1.txt 파일에 I'm file1.txt! 라는 내용을 추가한 것)
git diff {file1.txt가 속한 디렉토리}/file1.txt
==== git diff {file1.txt가 속한 디렉토리}/file1.txt 명령 결과 ====
diff --git a/file1.txt b/file1.txt
index e69de29..9c888c6 100644
--- a/file1.txt
+++ b/file1.txt
@@ -0,0 +1 @@
+I'm file1.txt!
\ No newline at end of file
원하는 작업(4번 커밋에서 추가된 텍스트를 "Hello World"로 변경)을 한 이후 다시 커밋
# file1.txt의 내용을 I'm file1.txt! -> Hello World로 변경
git add {file1.txt가 속한 디렉토리}/file1.txt
git commit -m "modify file1.txt"
rebase 마무리 및 결과 확인
# rebase를 이어서 진행 (interactive에서 pick이 아닌 다른 타입의 작업을 지정하지 않았고,
# 새로운 커밋 생성 중 conflict 발생하지 않는다면 rebase가 마무리됨
➜ git-study (e88f496) ✔ git rebase --continue
Successfully rebased and updated refs/heads/rebase_edit_commit.
git log
============= git log 결과 ===============
commit **07116c5d88a08a508350e2931913c029f5bc568e** (HEAD -> rebase_edit_commit)
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 21:04:12 2021 +0900
modify file2.txt again
commit **4cbf4586492cf6a03224faefe29a481146fe7d7f**
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 21:03:37 2021 +0900
modify file2.txt, file3.txt
commit **e88f496c4c50a9ac6e9928d22d7447f57d1b6397**
Author: Kim Dong In <needshield@airi.kr>
Date: Tue Apr 13 21:53:16 2021 +0900
modify file1.txt
commit 8180ad4499153ce949bcbe6f13276e1a320f1b6f
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 21:00:47 2021 +0900
add file3.txt
commit 064034361e01095b88026ff1a1cf887e6c8dcfeb
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 21:00:06 2021 +0900
add file2.txt
commit f90bb2717944fecf39bd4f4597625f402620e0f0
Author: Kim Dong In <needshield@airi.kr>
Date: Wed Apr 7 20:57:00 2021 +0900
add file1.txt
https://git-scm.com/book/ko/v2/Git-브랜치-Rebase-하기
https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase
https://milooy.wordpress.com/2018/10/25/git-rebase-or-merge-commit/