導入
rebase はコミットを1つずつ積み直します。もし 同じ場所 を両方の枝が変更していると、積み直す途中で コンフリクト が起きて止まります。merge のときと考え方は同じ。Git が止まった場所を、人間が直してから続けます。
説明
main と feature で、app.js の同じ場所を別内容に書き換えてぶつけます。
git init
git add .
git commit -m "C1"
git switch -c feature
echo "feature の行" > app.js
git add app.js
git commit -m "feature: rewrite app.js"
git switch main
echo "main の行" > app.js
git add app.js
git commit -m "main: rewrite app.js"
git switch feature
git rebase main
CONFLICT (content): Merge conflict in app.js と出て、rebase が 途中で停止 します。ファイルを開くと、両方の変更がマーカー付きで残っています。
cat app.js
<<<<<<< HEAD
main の行
=======
feature の行
>>>>>>> feature: rewrite app.js
merge のときと少し立場が違います。rebase では すでに積み直した側(=main の内容)が HEAD、いま積もうとしている 自分のコミットが下側 に表示されます。正しい最終形に書き直してマーカー3行を消し、git add で「解決した」と伝えます。
echo "main と feature を統合した行" > app.js
git add app.js
merge は git commit で仕上げましたが、rebase の続きは git commit ではありません。git rebase --continue で、残りのコミットの積み直しを続けます。
git rebase --continue
git log --oneline
無事に一直線の履歴が完成しました。もし途中で「やっぱりやめたい」と思ったら、git rebase --abort でrebase を始める前の状態に戻せます(安全弁として覚えておきましょう)。
flowchart LR
A["git rebase main"] -->|"衝突"| B["停止<br/>ファイルにマーカー"]
B -->|"直す → git add"| C["git rebase --continue"]
C --> D["積み直し完了"]
B -.->|"やめる"| E["git rebase --abort"]
やってみよう
上の手順でコンフリクトを起こし、cat app.js でマーカーを確認しましょう。ファイルを書き直して git add したあと、git rebase --continue で仕上げます(git commit ではない点に注意)。最後に git log --oneline で一直線になったことを確かめてください。
演習
コンフリクトを解決して git add したあと、rebase の続きを実行してください。
ヒント1を見る
解決して add したら、rebase は --continue で続けます。
ヒント2を見る
git rebase --continue