rebaseとmergeを動くコミットグラフで並べて比較し、pick、squash、fixup、dropを使った対話的リベースを計画できます。中止の方法やreflogでの取り消し方も解説します。
git rebaseは、ブランチのコミットを別のコミットの上に再適用し、マージコミットのない一直線の履歴にします。フィーチャーブランチでgit rebase mainを実行し、コンフリクトがあれば解消して、git rebase --continueを実行します。コミットをまとめる、メッセージを書き直す、削除するにはgit rebase -iを、やめるにはgit rebase --abortを使います。
よく使うrebaseコマンド
rebaseは、主にコミットを書き換えるという理由から、最も恐れられているgitコマンドです。下のグラフではmergeとrebaseで何が変わるかを正確に示し、プランナーではサンプルのコミットで対話的リベースを試せます。最後のセクションでは、コンフリクト、チームメイトを守るたった1つのルール、rebaseに失敗したブランチを取り戻す方法を扱います。
mergeは実際の履歴をそのまま残してマージコミットを追加するので、共有ブランチでは最も安全です。rebaseは読みやすくbisectしやすい一直線の履歴になるので、レビュー前の自分のフィーチャーブランチに向いています。多くのチームは、手元ではrebaseし、共有の場ではmergeしています。
まだ実行中なら、git rebase --abortですべて元に戻ります。すでに完了しているなら、git reflogを実行してrebase開始直前のエントリーを探し、そのハッシュにgit reset --hardします。ほかのコマンドで変わっていなければ、rebase直後のORIG_HEADも古い先端を指しています。
ほかの人がすでにそれを元に作業しているコミットはrebaseしないことです。rebaseは新しいハッシュを持つ新しいコミットを作るため、古いコミットを持っている人は履歴が重複し、わかりにくいコンフリクトに悩まされます。
どちらもコミットを上のコミットにまとめます。squashはエディターを開き、両方のメッセージを組み合わせられます。fixupはまとめるコミットのメッセージを捨てて、前のコミットのメッセージを残します。fixup -Cは、逆にまとめるコミットのメッセージを残します。
各コミットは新しいベースの上に改めて適用されますが、ベースと同じ行を変更したコミットは自動では適用できません。ファイルを編集してgit addし、git rebase --continueを実行します。再適用するコミットごとに1回ずつコンフリクトが起きることもあります。
git rebase -iは、コミットごとに1行、古いものが上に並んだtodoリストを開きます。行の先頭の単語を変更し、保存してエディターを閉じると、gitがリストを上から順に実行します。
git rebase -iのtodoリストのコマンド
まずfetchしてmainを最新にし、rebaseしてコンフリクトがあれば解消し、書き換えたブランチを安全にpushします。
rebase開始直前の行を探し、ブランチをそこへリセットします。
--ontoは3つの地点を取ります。新しいベース、古いベース、そしてブランチです。移動するのは古いベースより後のコミットだけです。
feature-bはfeature-aから作られています。これでfeature-b自身のコミットだけがmainの上に載ります。
mergeかrebaseか:履歴に何が起きるか
ブランチの統合方法を選ぶ
merge
rebase
マージコミット
mergeはF1とF2をそのまま残し、2つの親を持つ新しいコミットを1つ追加します。
rebaseはF1とF2をM3の上にコピーします。コピー('付き)は新しいハッシュを持ち、元のコミットは取り残されます。
対話的リベースプランナー
古い順に各コミットのアクションを選び、todoリストと結果を確認しましょう。
コミット{n}のアクション
gitが開くtodoリスト
rebase後の履歴
最初の行はsquashやfixupにできません。まとめ先となる上のコミットがないためです。
すべてのコミットが削除されました。ブランチはベースを指すことになります。
{n}件のまとめられたコミットを含む
メッセージを編集済み
無料で始める · クレジットカード不要