【git】git rebase -i でコミットをまとめる
はじめに
pushする前の細かいcommitをまとめるため、rebase -iで、squashを使った手順をメモしてまとめてみました。
今回は以下サイトのsquashの部分のみのメモです。
こちらのサイトではrebaseの他の使い方や、図も入っていてわかりやすく説明されてます。
こちらも参考にしてみてください。
この記事がどなたかの参考になれば幸いです。
また、もし間違い等ございましたらご指摘いただけるとありがたいです。
rebaseについて
rebaseできることは以下。今回はsquashのみです。
- コミットメッセージを編集する
- コミットをまとめる
- コミットを分割する
- コミットの順番を移動させる
- コミットを削除する
squash
rebase -i でコミットをまとめる際、
編集画面でまとめたいコミットを指定するkeyword(?)みたいなもの。
squashが指定されたコミットはその1つ前のコミットとまとめられます。
環境
MacOS 12.1
zsh
手順
- terminalでコマンド使って、まとめたいcommitをvimで表示する。
- 表示されたcommit一覧で、まとめたいcommitを選択
- commitメッセージを編集
- vimを保存して終了
- (おまけ) rebaseをミスったときにやめて元に戻す方法
- (おまけ) 今回使うVimの基本操作
以下手順の詳細です。
1. terminalでrebaseコマンド使って、まとめたいcommitをvimで表示する。
以下が構文
git rebase -i <commit>
<commit>には'commitID~数字'で編集したいcommitをcommitID含め、遡った数字でcommit指定して表示。
以下はHEADから1つ遡ったcommitまで表示。
git rebase -i HEAD~2
特定のcommitから2つ遡って表示する場合は
git rebase -i cce19c9~2
するとこういう感じの画面が出る
pick cce19c9 通信用のクラスの実装とテストの追加
pick 70b3379 メソッド名のタイポ修正
pick aebf22c テストが落ちてたので修正
# Rebase cce19c9..aebf22c onto b8e5722
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
...
2. 表示されたcommit一覧で、まとめたいcommitを選択
まとめたいコミットの左側のpick(何もしないという意味。)を以下のように、squashに変更する。
pick cce19c9 通信用のクラスの実装とテストの追加
squash 70b3379 メソッド名のタイポ修正
pick aebf22c テストが落ちてたので修正
squashを入れると一つ前のコミットとまとめられ、1つになる。
編集が終わったら、:wqで保存して終了。次へ進む。
3. commitメッセージを編集
以下のような画面になるので、編集してcommitメッセージを書く
(#はコメントアウト)
選択されているコミットのメッセージが書いてあるので、
コミットメッセージを編集する。
- 編集前
# This is a combination of 2 commits.
# The first commit's message is:
通信用のクラスの実装とテストの追加
# This is the 2nd commit message:
メソッド名のタイポ修正
# Please enter the commit message for your changes. Lines starting
...
- 編集後
通信用のクラスの実装とテストの追加
# Please enter the commit message for your changes. Lines starting
...
4. vimを保存して終了
編集終わったら、ノーマルモードに戻して、
:wqで保存してvim終了。
5. rebaseを中止して変更を元に戻す(rebaseでミスってやめたい時)
- rebaseの編集画面(vim)は保存せずに:qで閉じる。
- この時commitがrebaseされたように表示されるが、
慌てずに、
git rebase --abort
これでrebaseを中断して元に戻る。
参考
あのコミットをなかった事に。git rebase -i の使い方 - karakaram-blog
6. Vimの基本操作
今回特に使ったもの
- 編集する(INSERTモード )にする
aかi - 編集モードからノーマルモードに戻る
esc - 1文字削除
d - 1行削除
dd
参考
最後に
読んでいただきありがとうございました!
他参考にしたサイト
図が載っているのでわかりやすい
※AndroidStudio Arctic fox 20.3.1 Patch4(挿入している図とか)
以下をやると、
git rebase -i HEAD~2
とやると、自分の場合は
pick 6113996 #46 cloud firestoreと連携した。
pick de8340b #47 cloud firestoreのサンプルコードでデータを取得できたことを確認。
pick 383eac3 #49 firestore_test.dartのlistViewにコメント追加
pick 9c79789 #49 ビルドできない問題を解決した。
pick 36e2bd1 #49 ビルドできない問題を解決した。
pick 819cab7 #49 ビルドできない問題を解決した。
pick c0701fb GoogleService-Info.plistを削除
pick d152edd #49 .gitignore変更した
pick fccc660 #49 firestore_test.dartのdocument.data()にコメント追加
pick 1f9327b #51 index.dartの内容をTodo App参考に変更。player_modelにfetchIndex()追加。StreamBuilderを使わないように不要なコードをコメントアウト
pick b4561ea #51 firestoreのindexコレクションをListTileで表示できるようにした。
pick c5166b5 #46 不要なコメント削除、変更
pick 3129223 #54 FloatingActionButtonをConsumerで囲んで、onPressedのなかでfetchIndex()を呼んだ。リアルタイムでtitleがリストに反映されるようになった。
と大量に出てくる。
android studioのブランチ画面だと、
自分の予測では
pick ***まーじコミットの諸々***
pick 3129223 #54 FloatingActionButtonをConsumerで囲んで、onPressedのなかでfetchIndex()を呼んだ。リアルタイムでtitle
...
こんな感じで出てくると予想していた。
仮説
rebase -i で呼び出したcommitの中にマージされた時のcommit(marge commit?)が入っていると、
マージ前のブランチのcommitが大量に呼ばれるみたい。(どこまでかは不明)
つまりmarge commitはrebaseで編集はできない。その代わりmarge前の各ブランチのcommitが呼ばれる。
Gitのmerge commitについて
Merge remote-tracking branch 'origin/feature/70_add_current_position_to_firestore' into feature/70_add_current_position_to_firestore
これって何ですか?っていうことを調べてみた。
remote-tracking branch
要点は
ローカルにはmaster とorigin/masterの2つのブランチが存在する。
- master はローカルの更新を見ている。
- origin/masterはリモート側の更新を見ている。
- git fetchを行った際に origin/masterは最新になるがmaster は更新されない。
- git merge origin/master を行うと master ← origin/masterへmerge される。
ということです。
自分のところのブランチとサーバー側のブランチを別々にもっておいて突き合わせてマージする、簡単ですね。
追跡ブランチ (tracking branch) というブランチが何なのか調べた - snowlongの日記
ここの図がわかりやすい。
「追跡ブランチ (tracking branch)」が何であるか考える前に、 Git の2つの概念について確認しておきましょう。「リモート追跡ブランチ (remote-tracking branch)」と「上流ブランチ (upstream branch)」です。
上流ブランチは大雑把にいうと「引数なしで git pull したとき対象になるブランチ」のことです。たとえば master をチェックアウトして git pull すると自動的に origin/master の変更を引っ張ってきますね。ここで origin/master はローカルブランチ master の上流ブランチです。「master は origin/master を追跡 (tracking) している」ともいいます。
Git で「追跡ブランチ」って言うのやめましょう - Qiita
つまり、
remote-tracking branch
は
ローカルにある、
リモートを追跡しているブランチのこと。
それをローカルの同じ名前のブランチにmergeしたってこと。
つまりローカル側で、
remote-tracking branch→rocal branchにマージしたってこと。
上で出てきたmerge commitはrebase -i ではまとめられないっぽい。
実際にやってみたが commitが編集画面で出てこない。
以下方法でrebase -i を使ってcommitを指定した。
- git log --oneline で rebase 元になるコミット ID を探す
$ git checkout feature/hogehoge
$ git log --oneline
コミットID_4 (HEAD -> feature/hogehoge, origin/feature/hogehoge)コミットメッセージ_4
コミットID_3 コミットメッセージ_3
コミットID_2 コミットメッセージ_2
コミットID_1 (origin/develop, origin/HEAD, develop) コミットメッセージ_1
- git rebase -i <コミット ID> で rebase を実行する
まとめるコミット ID の1つ前を指定して、git rebase -i を実行します。
今回の場合は コミットID_2 〜 コミットID_4 をまとめるので コミットID_1 を指定します。
$ git rebase -i コミットID_1
git rebase -i HEAD~2
これでも出てこない。
のであきらめる。