リベース
公式サイト:
git-rebase | Git Documentation [Official]
使い方
※一般的に共有のリポジトリ/ブランチでリベースを行うことは非推奨とされる。(他のユーザーがリベース前のコミットにアクセスできなくなるため)
コミットの履歴を確認する。
$ git log --oneline
改変したいコミットの一つ前を指定してインタラクティブなリベースを開始する。(@~
を編集したい場合は @~2
を指定する。)
$ git rebase -i @~2
テキストエディタ (デフォルトでは vi) が起動するので、pick
となっている項を適宜編集する。また、コミットの並べ替えも必要に応じて可能である。
pick
:コミットを使用するedit
:コミットを編集するsquash
:前のコミットに統合するreword
:コミットメッセージを編集する
コミットの編集 (edit
) を指定した場合は、対象のコミットが完了した直後の状態にチェックアウトされている。ファイルに必要な編集を施したら、ステージングして上書きコミットを実行する。
$ git add path/to/modified_file $ git commit --amend
リベースを中止する場合は git rebase --abort
、次に進める場合は git rebase --continue
を実行する。
$ git rebase --continue
途中でコンフリクトが発生した場合は、コンフリクトしたファイルに修正、追加 (git add
)、削除 (git rm
) など行って、git rebase --continue
コマンドを実行してリベースを継続する。
リベースが完了したら git push -f
でリモートに反映させる。
$ git push -f
参考:
git rebase で複数のコミットを1つにまとめる – Qiita
インタラクティブモードで、ToDo リストを再編集してリベースを続行する | kledgeb
コミット履歴を大胆に書き換えるなら git rebase -i がオススメ | yu8mada
今更ながら git rebase をちゃんと使えるようにする | hawksnowlog
How can I squash commits without tracking a remote branch? – Stack Overflow
How do I use interactive rebase with a local-only repository (no remote / origin)? – Stack Overflow
Reordering of commits – Stack Overflow
メリット/デメリット
参考:
なぜ git rebase をやめるべきか | Frasco
rebase して FF マージすることによる一直線の履歴は本当にわかりやすいのか | 誰得UNIX
最初のコミットを修正する
最初のコミットを修正するには、--root
オプションを指定してインタラクティブリベースを開始する。
$ git rebase -i --root
参考:
Git の最初のコミットは空コミットにしよう – Qiita
Git の歴史修正、first commit すら書き換える – Qiita
first commit が git rebase -i できない問題 → git rebase -i --root でできる | 納豆には卵を入れる派です。
How to remove the first commit in Git? – Stack Overflow
自動スカッシュ (autosquash)
スカッシュしたいコミットのコミットメッセージに squash!
を付けて、前のコミットのコミットメッセージを後ろに続ける。
$ git commit -m 'squash! This is a target commit'
--autosquash
オプションを付けてインタラクティブリベースを開始すると、git-rebase-todo
ファイルがスカッシュ用に設定された状態でリベースが開始する。
$ git rebase -i --autosquash @~2
参考:
git rebase -i のための rebase.autosquash オプション – Qiita
git commit --fixup と git rebase --autosquash で簡単に commit が整理できて感動した話 | reboooot․net
コミット履歴を綺麗にするときの git commit --fixup と git rebase --autosquash | 理系学生日記
Git で今作ったコミットを以前のコミットに半自動的に融合させる | 誰得UNIX
git rebase --autosquash | Coderwall
fixup
自動スカッシュ用のコミットを作成するには、--fixup
オプションにコミットハッシュを指定してコミットを実行する。
$ git commit --fixup COMMIT_HASH $ git rebase -i --autosquash COMMIT_HASH~
参考:
git commit --fixup と git rebase --autosquash で簡単に commit が整理できて感動した話 | reboooot․net
コミット履歴を綺麗にするときの git commit --fixup と git rebase --autosquash | 理系学生日記
git commit --fixup で fixup する対象を peco/fzf で選べるスクリプト書いた – Qiita
インタラクティブリベース中に ToDo リストを確認する
$ cat .git/rebase-merge/git-rebase-todo \ | git stripspace --strip-comments
参考:
Show number of ToDo items for interactive rebase · git/git@97f05f4 – GitHub
Show list of commits during interactive rebase – Stack Overflow
REBASE_HEAD
参考:
git error message: rebase_head does not exist – Stack Overflow
--onto オプション
参考:
git rebase --onto を使って、まずは自分だけ幸せになる – Qiita
git rebase --onto どこへ/どこから/どのブランチを – Qiita
git rebase --onto –root で過去の歴史を改変する | なんとな~くしあわせ?の日記
master HEAD 以降をインタラクティブに rebase する
共通の祖先コミットを調べる。
$ git merge-base master HEAD
共通の祖先コミット以降をリベースする。
$ git rebase -i $(git merge-base master HEAD)
参考:
簡単にトピックブランチだけで interactive rebase する – Qiita
コミットをまとめる (sqush)
参考:
Git で push 済の commit を sqush でまとめる方法 – Qiita
履歴の途中にコミットを追加する
参考:
How to inject a commit between some two arbitrary commits in the past? – Stack Overflow
プルリクエスト送信のためにリベースする
参考:
Pull Request 後に upstream に更新が入ったので rebase して conflict を解消して push -f する話 | wyukawa’s diary
Pull Request ベースの開発では git rebase 使った方がいい – Qiita
強制的にプッシュする
リベースした後にプッシュする際、最後のフェッチ以後にリモートでコミットが追加されてない場合のみ、プッシュを成功させる。
$ git push origin develop --force-with-lease
参考:
なぜ rebase 後に強制プッシュをする必要があるのか – Qiita
git rebase からの push --force-with-lease | Just do IT
強制プッシュ時は push -f ではなく --force-with-lease を使おうという話 | TechTechMedia
--force は有害だという考え/--force-with-lease を理解する | アトラシアン株式会社
Git Rebase: Don’t be Afraid of the Force Push | Gerald Versluis
Introduction to Git Rebase and Force Push | GitLab
push after rebase – Stack Overflow
force push or pull push – Stack Overflow
マージコミットを含むブランチをリベースする
--rebase-merges
オプションを付けてインタラクティブリベースを開始する。
$ git rebase -i --rebase-merges @~
参考:
git rebase --rebase-marges について – Qiita
git rebase 時にマージコミットを保持する – Qiita
Git でマージコミットが含まれるブランチを rebase する | 作業ノート
Pull Request の rebase – スタック・オーバーフロー
Rebasing a merge commit – Stack Overflow
マージコミットのメッセージを変更する
--rebase-merges
オプションを付けてインタラクティブリベースを開始する。
$ git rebase -i --rebase-merges @~
開かれた git-rebase-todo
ファイルの merge -C
を merge -c
に変更する。
merge -c 1234abc hoge # Merge branch 'hoge' into piyo
参考:
How to edit / reword a merge commit’s message? – Stack Overflow
参照を強制的に変更する
参考:
force a rebase – Stack Overflow
How can I force a rebase and override merge conflicts – Stack Overflow
Forcing a rebase – Stack Overflow
リファレンス
git-rebase | Git コマンドリファレンス (tracpath.com)
まとめ
ソースコード
git/rebase.c at v2.20.1 · git/git – GitHub