TL;DR: 30秒で解決する方法
このエラーを解消する最も確実な方法は、現在の作業を一時的な保存領域に移動し、リベースを完了させてから、変更を元に戻すことです。次の3つのコマンドを実行してください。
git stash
git rebase origin/main
git stash pop
ローカルの変更が一切不要な場合は、git reset --hard を実行して作業状態を完全にリセットできます。ただし、コミットしていない作業は永久に削除されるため、注意してください。
なぜGitはリベースをブロックするのか
Gitはセーフティネットとして機能しています。リベースを行う際、Gitはコミットを一度「巻き戻し」、新しいベースの上に一つずつ再適用します。このプロセスでは、現在作業中のファイルと同じファイルを変更することがよくあります。
例えば、app.js にステージングされていない変更があり、リベースでも app.js を更新する必要がある場合、Gitは未保存の作業を上書きしてしまうリスクを冒しません。これらの変更はまだGitのデータベースに保存されていないため、失われると二度と復元できません。そのため、Gitはコミット履歴を操作する前に、それらのファイルをどう処理するか決定することを強制します。
方法1:Git Stashを使用する(推奨される方法)
多くの開発者は、非破壊的であるためスタッシュ(退避)を好みます。git stash は、ファイルシステムのクリップボードのようなものだと考えてください。コミットされていない変更内容をスタックに保存し、作業ディレクトリを完全にクリーンで同期された状態にします。
- 変更を脇に置く:
git stash - リベースを実行する:
git rebase origin/develop - 作業を再適用する:
git stash pop
git stash pop でコンフリクトが発生した場合は、スタッシュした内容と新しくリベースされたコミットが同じ行を変更していることを意味します。エディタを開いてコンフリクトを解消し、通常通り進めてください。
方法2:「設定して放置」できるAutostash
このエラーを煩わしく感じる場合は、スタッシュのプロセス全体を自動化できます。Git 1.8.4以降、--autostash フラグを使用することで、Gitが自動的にスタッシュの保存と復元(ポップ)を処理してくれます。
git rebase origin/main --autostash
今後行うすべてのリベースでこれをデフォルトの動作にするには、次のグローバル設定コマンドを実行します。
git config --global rebase.autoStash true
これはQOL(生活の質)を大きく向上させる改善です。1つのコマンドで済むようになり、3つのコマンドを入力する手間が省けます。
方法3:WIP(作業中)コミット
時には、多数のファイルを変更しており、スタッシュよりも永続的な記録を残したい場合があります。その場合は、一時的な「WIP」コミットを作成します。これにより、作業内容がGitツリー内に安全に保持されます。
git add .
git commit -m "wip: 作業内容の一時保存"
git rebase origin/main
リベースが完了したら、git reset HEAD~1 を実行することで、ファイルへの変更を保持したまま一時的なコミットを「取り消す」ことができます。これにより、変更内容がステージングされていないファイルとして作業ディレクトリに戻ります。
方法4:ワークスペースをクリーンにする
リベースを妨げている変更が、単なる誤入力やデバッグ用の console.log ステートメントである場合は、それらを削除するだけです。最新のGit(バージョン2.23以降)では、restore コマンドを使用します。
git restore .
古いバージョンの場合、構文は少し異なります。
git checkout -- .
検証:リベースの成功を確認する
すべてが正常に戻ったかどうかをどのように確認すればよいでしょうか?次の3点を確認してください。
- ツリーを確認する:
git log --oneline --graphを実行します。コミットがターゲットブランチの最新コミットから一直線に繋がっているはずです。 - ステータスを確認する:
git statusを実行し、「rebase in progress」というメッセージが表示されていないことを確認します。 - スタッシュを確認する: 方法1を使用した場合は、
git stash listを実行します。ポップが成功し、コンフリクトがなければ、スタッシュは消えているはずです。

