概要
git rebase
は今いるブランチのベースを変更するが、-i
(intaractive)オプションを付けることで、複数コミットを統合することができる。
interactiveという通り、その過程で何度かエディターが起動して操作内容が表示され、コミット統合に必要な内容に書き換えていく。
準備
以下のように、sample.txt
に1行ずつ追加するコミットを含むリポジトリーを準備する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
[vagrant@localhost example]$ git log -p commit 0d042cb782946614fe5457dfe0f86f127d763fe9 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:20:18 2021 +0900 main-3 diff --git a/sample.txt b/sample.txt index 6f3e91e..9812172 100644 --- a/sample.txt +++ b/sample.txt @@ -1,2 +1,3 @@ main-1で新規作成 main-2で2行目追加 +main-3で3行目追加 commit 454e22d8a0ec0330811686801e9bb04a1c5eb391 Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:19:39 2021 +0900 main-2 diff --git a/sample.txt b/sample.txt index f704a42..6f3e91e 100644 --- a/sample.txt +++ b/sample.txt @@ -1 +1,2 @@ main-1で新規作成 +main-2で2行目追加 commit f9dd6a932cbd4017c151c2d5b7bfaeb596b95193 Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:19:08 2021 +0900 main-1 diff --git a/sample.txt b/sample.txt new file mode 100644 index 0000000..f704a42 --- /dev/null +++ b/sample.txt @@ -0,0 +1 @@ +main-1で新規作成 commit 7fe38cd822113861b9e2062902fea7881f10de45 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 11:43:19 2021 +0900 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6fba08 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# example \ No newline at end of file |
2つのコミットの統合
rebaseコマンド
main-2
とmain-3
のコミットを統合するため、その直前=main-1
のコミット直後を指定してrebaseする。このとき-i
オプションを付けることで、リベースの過程での操作を指定できる。
1 |
[vagrant@localhost example]$ git rebase -i f9dd6a9 |
各コミットへの対応記述
rebaseを実行するとエディターが起動して以下のように表示される。
- この段階では、ベースとなる
main-1
より後のmain-2
とmain-3
の2つのコミットについて、そのまま適用されることになる - つまり、
main-1
コミットの後にmain-2
とmain-3
がそのまま連なることになり、何も変わらない - これを、
main-2
とmain-3
をまとめた上でmain-1
の後に来るようにしたい
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
pick 454e22d main-2 pick 0d042cb main-3 # Rebase f9dd6a9..0d042cb onto f9dd6a9 (2 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 ~ ~ ~ ..... |
Commands:
のところを見ると、以下のように読める。
p, pick
はそのコミットをそのまま使うs, squash
はそのコミットを使うが、1つ前のコミットに統合(融合?)させる
そこで、後の方のコミットmain-3
をpick
からsquash
に変更する。こうすれば、main-2コミットはそのまま使われ、そこにmain-3コミットも統合されるはず。
1 2 3 4 5 |
pick 454e22d main-2 squash 0d042cb main-3 # Rebase f9dd6a9..0d042cb onto f9dd6a9 (2 commands) ..... |
コミットメッセージの編集
上記の内容で保存・終了すると、さらにエディターが起動して以下のように表示される。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# This is a combination of 2 commits. # This is the 1st commit message: main-2 # This is the commit message #2: main-3 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Sat Aug 14 15:19:39 2021 +0900 # # interactive rebase in progress; onto f9dd6a9 # Last commands done (2 commands done): # pick 454e22d main-2 # squash 0d042cb main-3 # No commands remaining. # You are currently rebasing branch 'main' on 'f9dd6a9'. # # Changes to be committed: # modified: sample.txt # ~ ~ ~ ..... |
2つのコミットを1つにするので、コミットメッセージを1つだけにして、終了の空行を入れる。
1 2 3 4 5 |
main-2 and 3 gathered # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. ..... |
処理結果
上記の内容を保存・終了すると、rebaseの処理内容が以下のように表示される。
1 2 3 4 5 |
[vagrant@localhost example]$ git rebase -i f9dd6a9 [detached HEAD 7a2abb7] main-2 and 3 gathered Date: Sat Aug 14 15:19:39 2021 +0900 1 file changed, 2 insertions(+) Successfully rebased and updated refs/heads/main. |
ログで確認すると、main-2
とmain-3
が1つにまとめられ、指定したコミットメッセージになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[vagrant@localhost example]$ git log commit 7a2abb787d1fa93e8c8ccaec08e6b3fdff5e4a23 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:19:39 2021 +0900 main-2 and 3 gathered commit f9dd6a932cbd4017c151c2d5b7bfaeb596b95193 Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:19:08 2021 +0900 main-1 commit 7fe38cd822113861b9e2062902fea7881f10de45 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 11:43:19 2021 +0900 Initial commit |
コミットをまとめただけなので、sample.txt
の内容は変化しない。
1 2 3 4 |
[vagrant@localhost example]$ cat sample.txt main-1で新規作成 main-2で2行目追加 main-3で3行目追加 |
3つ以上のコミットの統合
main-1
~3
の3つの連続するコミットをまとめるため、その直前のコミットを指定してrebase。
1 |
[vagrant@localhost example]$ git rebase -i origin/main |
エディターが起動。
1 2 3 4 5 6 |
pick f9dd6a9 main-1 pick 454e22d main-2 pick 0d042cb main-3 # Rebase 7fe38cd..0d042cb onto 7fe38cd (3 commands) ..... |
以下のようにpick
→squash
に変更して保存。これにより、main-2
はmain-1
に統合され、そこにmain-3
も統合される。
1 2 3 4 5 6 |
pick f9dd6a9 main-1 squash 454e22d main-2 squash 0d042cb main-3 # Rebase 7fe38cd..0d042cb onto 7fe38cd (3 commands) ..... |
再度エディターが起動。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# This is a combination of 3 commits. # This is the 1st commit message: main-1 # This is the commit message #2: main-2 # This is the commit message #3: main-3 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. ..... |
統合後のコミットメッセージを編集して保存・終了。
1 2 3 4 5 |
main-1 to 3 commits gathered # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. ..... |
実行結果。
1 2 3 4 5 6 |
[vagrant@localhost example]$ git rebase -i origin/main [detached HEAD e62e8e2] main-1 to 3 commits gathered Date: Sat Aug 14 15:19:08 2021 +0900 1 file changed, 3 insertions(+) create mode 100644 sample.txt Successfully rebased and updated refs/heads/main. |
3つのコミットが1つにまとめられた。
1 2 3 4 5 6 7 8 9 10 11 12 |
[vagrant@localhost example]$ git log commit e62e8e2753af9aec3c6b48554a6d71ed2508261f (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Sat Aug 14 15:19:08 2021 +0900 main-1 to 3 commits gathered commit 7fe38cd822113861b9e2062902fea7881f10de45 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sat Aug 14 11:43:19 2021 +0900 Initial commit |
イニシャルコミットとの統合
一番最初のコミットと統合するには、以下のコマンドを使う。
git rabase -i --root
以下の例では、README.md
を修正した2つ目のコミットを1つ目のInitial commit
に統合している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[vagrant@localhost codecamp]$ git log commit 735a9faec64339055621b415c698f4eb7fdf02eb (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Sun Aug 15 22:18:55 2021 +0900 README.md modified commit 73c1bc8e633b3aa9299549c25ea618fc8d2466f3 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 15 20:27:10 2021 +0900 Initial commit [vagrant@localhost codecamp]$ git rebase -i --root [detached HEAD f642840] Initial commit Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 15 20:27:10 2021 +0900 1 file changed, 1 insertion(+) create mode 100644 README.md Successfully rebased and updated refs/heads/main. [vagrant@localhost codecamp]$ git log commit f6428405e52dffed607fda510ae22aa10fa137cd (HEAD -> main) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 15 20:27:10 2021 +0900 Initial commit |
リモートへの反映
リモートからpull
したリポジトリーの場合、そのままではpush
できない。
ローカルでのrebase
の結果をリモートにそのまま反映するには、push -f
で強制的に上書きする。
ただし他のローカルでその内容を反映させるには、改めてclone
する必要がある。