Closed4

【git】git rebase -i でコミットをまとめる

Ryouhei FurugenRyouhei Furugen

はじめに

pushする前の細かいcommitをまとめるため、rebase -iで、squashを使った手順をメモしてまとめてみました。

今回は以下サイトのsquashの部分のみのメモです。
こちらのサイトではrebaseの他の使い方や、図も入っていてわかりやすく説明されてます。
こちらも参考にしてみてください。
http://tkengo.github.io/blog/2013/05/16/git-rebase-reference/

この記事がどなたかの参考になれば幸いです。
また、もし間違い等ございましたらご指摘いただけるとありがたいです。

rebaseについて

rebaseできることは以下。今回はsquashのみです。

  • コミットメッセージを編集する
  • コミットをまとめる
  • コミットを分割する
  • コミットの順番を移動させる
  • コミットを削除する

squash

rebase -i でコミットをまとめる際、
編集画面でまとめたいコミットを指定するkeyword(?)みたいなもの。
squashが指定されたコミットはその1つ前のコミットとまとめられます。

環境

MacOS 12.1
zsh

手順

  1. terminalでコマンド使って、まとめたいcommitをvimで表示する。
  2. 表示されたcommit一覧で、まとめたいcommitを選択
  3. commitメッセージを編集
  4. vimを保存して終了
  5. (おまけ) rebaseをミスったときにやめて元に戻す方法
  6. (おまけ) 今回使う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

参考

https://qiita.com/tomoya1993/items/7b7dfffd3553e55601ef

最後に

読んでいただきありがとうございました!

他参考にしたサイト

図が載っているのでわかりやすい
https://backlog.com/ja/git-tutorial/stepup/32/

Ryouhei FurugenRyouhei Furugen

※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が呼ばれる。

Ryouhei FurugenRyouhei Furugen

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にマージしたってこと。

Ryouhei FurugenRyouhei Furugen

上で出てきたmerge commitはrebase -i ではまとめられないっぽい。

実際にやってみたが commitが編集画面で出てこない。
以下方法でrebase -i を使ってcommitを指定した。

  1. 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
  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)

git rebase -i HEAD~2

これでも出てこない。
のであきらめる。

このスクラップは2022/02/28にクローズされました