- リベースで履歴を書き換える
- コミットを並び替える、削除する
- 実際にやってみよう(コミットを並び替える)
- コミットをまとめる
- 実際にやってみよう(コミットをまとめる)
- コミットを分割する
- 実際にやってみよう(コミットを分割する)
- 参考図書
- あわせて学習したい
リベースで履歴を書き換える
今回はリベースで履歴を書き換えるやり方の続きを解説します。
前回は複数のコミットの履歴を書き換えました。
今回はコミットを並び替えたり、コミットをまとめたり、逆にコミットを分割するやり方について解説します。
コミットを並び替える、削除する
まずコミットを並び替えたり、削除する方法について解説します。
そのためにはまず「git rebase -i」コマンドを使います。
前回と同じように
$ git rebase -i HEAD~3
と指定しましょう。
すると前回と同じように3つのコミットが表示されます。
pick gh21f6d ヘッダー修正 pick 193054e ファイル追加 pick 84gha0d README修正
ちなみにこの表示の仕方は「git log」とは逆なので、注意してください。
「git log」の場合は一番先頭のものから上から順に表示されましたが、今回は逆順になります。
つまり、README修正というのが一番最近のコミットで、その親コミットが「ファイル追加」さらにその親コミットが「ヘッダー修正」となっています。
では今回はこの履歴を削除したり、並び替えたりしてみましょう。
まずコミットの削除からやってみます。
「README修正」のコミットを消したいとします。
その場合は「README修正」の行をコミットエディタ上で消してあげればOKです。
pick gh21f6d ヘッダー修正 pick 193054e ファイル追加
次に、コミットの並び替えをします。
「ヘッダー修正」と「ファイル追加」の適用の順番を変えていきましょう。
その場合もコミットエディタ上でコミットの順番を入れ替えてあげればコミットの順番を変更することができます。
pick 193054e ファイル追加 pick gh21f6d ヘッダー修正
このようにコミットを削除したい場合はそのコミットの行を消して、コミットの順番を入れ替えたい場合は単純にコミットの順番を入れ替えてあげればOKです。
実際にやってみよう(コミットを並び替える)
それではターミナル上で確かめていきましょう。
まず今のGitの状態を確かめます。
$ git log --oneline -n 3 afe8acc (HEAD -> main) third.html 5e155d7 second.htmlを追加 8d41a2e first.htmlを追加
すると前回の通りです。
3つコミットが最新のものでされていて、「third.html」「second.htmlを追加」「first.htmlを追加」となっています。
今回このログの順番を変えていこうと思います。
$ git rebase -i HEAD~3
コミットエディタが立ち上がります。
pick 8d41a2e first.htmlを追加 pick 5e155d7 second.htmlを追加 pick afe8acc third.html
ここで注目して欲しいのは「git log」とは逆の順番で表示されていると言うことです。
どのような順番で表示されているかというと、リベースを適用するコミット順に表示されています。
「git rebase -i」コマンドは基盤となるコミットがあって、そのコミット以降のコミットが書かれている、その元となるコミット以降のものを順にリベースしていくので、このような順番で表示されています。
それでは今回は「second.htmlを追加」というコミットを一番古いところに持ってきてみましょう。
pick 5e155d7 second.htmlを追加 pick 8d41a2e first.htmlを追加 pick afe8acc third.html
このように「second.htmlを追加」というのを一番古い履歴(一番上)に持ってきてみました。
これでコミットの順番を入れ替えた場合の挙動についてみてみます。
保存してテキストエディタを終了します。
ターミナルに戻ります。
$ git rebase -i HEAD~3 Successfully rebased and updated refs/heads/main.
ターミナルに戻るとリベースが成功しています。
それでは「git log」でコミットの順番が入れ替えられているか確認してみましょう。
$ git log --oneline -n 3 c89918b (HEAD -> main) third.html ce67305 first.htmlを追加 08eb2b7 second.htmlを追加
すると先ほどとは違って、git logの順番が「second.htmlを追加」が一番古い履歴になっています。
このように「git rebase -i」コマンドを使ってコミットエディタ上で順番を入れ替えることでコミットの順番を入れ替えることができました。
コミットをまとめる
次に、コミットをまとめるやり方について解説します。
まずいつも通り「git rebase -i HEAD~3」と入力します。
するとコミットエディタが立ち上がるので、そこに今回は「pick」の代わりに「squash」と入力します。
「squash」というのは押しつぶすとかぺちゃんこにするという意味です。
この「squash」をして、リベースするとそのコミットを直前のコミットと一つにしてコミットを1つにまとめることができます。
例えば、今回みたいに3つのコミットを1つにまとめたい場合でしたら、一番新しいコミットをそのまま「pick」にしておいて、残りのコミットを「squash」にしてあげればコミットを1つにまとめることができます。
実際にやってみよう(コミットをまとめる)
それではターミナルにもどって実際にやっってみましょう。
$ git rebase -i HEAD~3
と入力します。
今回はこの3つのコミットを1つにまとめてみます。
2つ目以降の「pick」という文字を「squash」と変更しましょう。
pick 08eb2b7 second.htmlを追加 squash ce67305 first.htmlを追加 squash c89918b third.html
保存してコミットエディタを終了します。
ターミナルに戻ります。
ターミナルに戻ろうとしたら、もう一度コミットエディタが立ち上がりました。
「squash」の場合コミットをまとめたよというのがコミットメッセージとして記録されます。
今回はここで表示されているコミットメッセージをそのまま保存して終了します。
ではターミナルに戻ります。
$ git rebase -i HEAD~3 [detached HEAD 70edcc6] second.htmlを追加 Date: Wed Sep 1 17:03:51 2021 +0900 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 first.html create mode 100644 second.html create mode 100644 third.html Successfully rebased and updated refs/heads/main.
ターミナルに戻るとリベースが上手くいっていることが確認できます。
それでは「git log」でコミットの状態をみてみましょう。
$ git log --oneline -n 3 70edcc6 (HEAD -> main) second.htmlを追加 966020f (origin/main) feature2を新規作成 b638345 main2を新規作成
すると、先ほどまで3つあった「〜.htmlを追加」というのが、「second.hemlを追加」という1つのコミットになっています。
これでコミットが1つになっていることが確認できました。
ファイルも元の通りあるのか、本当にコミットが1つに纏まっただけなのかとういうのを確認してみましょう。
$ ls feature.html first.html index.html main2.html secret.txt feature2.html home.html main.html second.html third.html
すると「first.html」も「second.html」も「third.html」もあることが確認できます。
これで確かにコミットが1つに纏まったことが確認できました。
このようにsquashをつかうことでコミットを1つにまとめることができます。
コミットを分割する
最後にコミットを分割するやり方について解説します。
またいつも通り「git rebase -i HEAD~3」と入力します。
pick gh21f6d ヘッダー修正 pick 193054e ファイル追加 pick 41ghaOd READMEとindex修正
今回、コミットの3番目のコミットを見てください。
すると今回は「READMEとindex修正」とコミットメッセージが書かれています。
このコミットでは2つの事をやって、それを一つのコミットにしてしまったという状況です。
今回、その「READMEとindex修正」というのを「README修正」と「index修正」という2つのコミットに分割したいと思います。
それでは分割するやり方を見ていきましょう。
分割するためには分割したいコミットの「pick」を「edit」に書き換えます。
今回ですと「READMEとindex修正」というコミットのところを「edit」に書き換えます。
書き換えたら保存してコミットエディタを終了します。
終了したらまず
$ git reset HEAD^
と入力します。
これは何かというと、「git reset」コマンドというのがコミットを取り消して、ステージングしていない状況にまで戻すコマンドです。
「HEAD^」というのが「edit」と記載しているコミットのことを指します。
「git reset HEAD^」と入力することで、「edit」と記載されているコミットのコミットを取り消して、さらにステージングもしていない状態にまで戻すというコマンドになります。
このコマンドでコミットを取り消してステージもしていない状態に戻したら、「README修正」というのと「index修正」というのをそれぞれでコミットしていきます。
まずREADMEからいきましょう。
$ git add README
でステージに追加して
$ git commit
していきます。
コミットメッセージは「README修正」とします。
これで「README修正」のコミットはできたので、次にindex.htmlの方をコミットしていきます。
$ git add index.html
そして
$ git commit
します。
コミットメッセージは「index.html修正」とします。
こうすることで2つのコミットに分割できました。
これでコミットまでできたので、次はリベースを次のコミットに進めるために
$ git rebase --continue
コマンドを入力します。
これでコミットは分割できます。
実際にやってみよう(コミットを分割する)
それではターミナルに戻って作業していきましょう。
まず今の状態をもう一度確認しておきます。
$ git log --oneline -n 3 70edcc6 (HEAD -> main) second.htmlを追加 966020f (origin/main) feature2を新規作成 b638345 main2を新規作成
すると「second.htmlを追加」というコミットで、前回の操作で3つのコミットが1つにまとめられています。
今回それを2つのコミットに分割していこうと思います。
$ git rebase -i HEAD~3
pick b638345 main2を新規作成 pick 966020f feature2を新規作成 pick 70edcc6 second.htmlを追加
今回は一番最新のコミットである「second.htmlを追加」というのを分割したいので、これを「pick」から「edit」に書き換えます。
書き換えたら保存して終了します。
ターミナルに戻ります。
まずはresetコマンドでコミットの取り消しをしていきましょう。
$ git reset HEAD^
これでコミットの取り消しとステージングしていない状態にすることができているはずです。
$ git status interactive rebase in progress; onto c378922 Last commands done (3 commands done): pick 966020f feature2を新規作成 edit 70edcc6 second.htmlを追加 (see more in file .git/rebase-merge/done) No commands remaining. You are currently editing a commit while rebasing branch 'main' on 'c378922'. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) Untracked files: (use "git add <file>..." to include in what will be committed) first.html second.html third.html nothing added to commit but untracked files present (use "git add" to track)
すると、「first.html」「second.html」「third.html」がステージングされていない状態になっていることがわかります。
これを今回「first.html second.htmlを追加」というコミットと「third.htmlを追加」という2つのコミットに分割してみましょう。
まず「first.html」「second.html」を追加というコミットをつくっていきます。
$ git add first.html $ git add second.html
これをコミットしていきます。
$ git commit -m 'first.htmlとsecond.htmlを追加' [detached HEAD 1b62b2c] first.htmlとsecond.htmlを追加 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 first.html create mode 100644 second.html
コミットできました。
それでは続いて「third.html」 のコミットもやっていきましょう。
$ git add third.html
ではコミットしていきます。
$ git commit -m 'third.htmlを追加' [detached HEAD 55c46b4] third.htmlを追加 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 third.html
これで追加できました。
2つのコミットができたので、続けていきます。
$ git rebase --continue Successfully rebased and updated refs/heads/main.
これで次のリベースへ進んでいきます。
これでリベースが完了です。
「git log」コマンドで確認してみましょう。
$ git log --oneline -n 3 55c46b4 (HEAD -> main) third.htmlを追加 1b62b2c first.htmlとsecond.htmlを追加 966020f (origin/main) feature2を新規作成
すると、「third.htmlを追加」と「first.htmlとsecond.htmlを追加」という2つのコミットに分割されていることが確認できました。
このようにリベースコマンドを使うことで、コミットの順番を入れ替えたり、コミットをまとめたり、逆にコミットを分割したりすることができます。
リベースの内容としてはここまでですが、一番最後にGitHubに今回の内容をアップしておきましょう。
$ git push origin main Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 518 bytes | 259.00 KiB/s, done. Total 5 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 1 local object. To github.com:piketa/git_tutorial.git 966020f..55c46b4 main -> main
参考図書
独学で挫折しそうになったら、オンラインプログラミングスクール