【Git】リベース途中でエラーになったときの復旧方法

rebase 中にコンフリクトや操作ミスで止まってしまったときは、まず「今どの段階で止まっているか」を把握し、適切なコマンドで前進・スキップ・撤退のいずれかを選ぶのが近道です。ここでは典型的な停止要因ごとの復旧手順を、作業ディレクトリを壊さず安全に進める順序で解説します。

現在地を確認する

git status

「You are currently rebasing.」と表示される場合はリベースが進行中です。続けるときは git rebase --continue、このコミットを飛ばすなら git rebase --skip、やり直すなら git rebase --abort を使います。どのコミットで止まっているかは git status に「Currently rebasing; onto <hash>」や「You are currently editing a commit while rebasing.」と出ます。

コンフリクトで止まった場合の基本動作

# 1) 衝突しているファイルを開いて手動解決
git add <解決したファイル>

# 2) 解決を Git に伝える
git rebase --continue

まだ解決していないファイルがあると「No changes – did you forget to use ‘git add’?」のように指摘されます。解決が難しいコミットをとりあえず飛ばして先に進めたい場合は git rebase --skip を使います。根本からやり直すときは git rebase --abort で開始前の状態へ戻せます。

作業ツリーが汚れていて開始できない・進めないとき

# エラー例:cannot rebase: You have unstaged changes
#           or
#           Please commit or stash them.

未コミットの変更が残っていると rebase を開始・継続できません。変更を残したいなら一時退避し、終わったら戻します。

git stash push -u -m "rebase-temp"
git rebase --continue   # もしくは rebase を開始
# リベースが終わったら
git stash pop

「rebase が既に進行中」と言われるときの対処

# エラー例:It seems that there is already a rebase in progress

以前の中断が .git ディレクトリ内に残っている状態です。正規の手順で終了させます。

git rebase --continue   # 進められるなら進める
git rebase --abort      # 破棄して開始前へ戻す

それでも解消しないときは、.git/rebase-merge または .git/rebase-apply が壊れている可能性があります。むやみに削除する前に、まず git status で状況を確認し、--abort での撤退を優先します。

インタラクティブ rebase の todo でエラーになったとき

# エラー例:Unknown command: fix # タイポ、あるいはコマンド名が不正
# エラー例:The previous cherry-pick is now empty   # fixup/squash 後に空コミット

todo の修正が必要な場合は編集モードに戻します。コマンド綴りは pickrewordeditsquashfixupdrop などに限定されます。

git rebase --edit-todo
# 誤った行を修正・削除して保存
git rebase --continue

空コミットで止まる場合は、そのコミットを削除したい意図なら drop に変更するか、メッセージ編集を求められたら保存して継続します。

「untracked を上書きするため中断」のエラーを解決する

# エラー例:untracked working tree files would be overwritten by checkout

追跡外ファイルが対象ブランチのファイルと衝突している状態です。必要なら退避し、不要なら削除してから続行します。

# 退避する場合
git stash push -u -m "untracked-backup"

# 不要なら安全に削除(確認してから)
rm path/to/file

git rebase --continue    # あるいは rebase を再実行

コンフリクト解消後に誤って内容を戻してしまった場合のリカバリ

解決作業でファイルを壊したり間違ってスキップした場合でも、ref-log から戻せます。作業中の HEAD の移動履歴を辿り、やり直したい地点のハッシュをチェックアウトしてファイルを取り戻します。

git reflog --date=iso
# 取り戻したい時点のハッシュを控える
git checkout <hash> -- path/to/file
# 取り戻したファイルを現在の作業ツリーに反映

最終手段としての全面撤退

収拾がつかなくなった場合は git rebase --abort を実行し、開始前のブランチ先頭に戻します。既に何段か進めてしまっても、ORIG_HEADreflog から開始直前の位置を特定できます。どうしても戻れないように見えるときでも、git reflog の履歴を辿ればほぼ確実に回復可能です。

git rebase --abort
git reflog
git reset --hard <開始直前のハッシュ>

安全にやり直すコツ

リベースを再開・再試行する前に、現在の状態を退避しておくと安心です。作業ツリー丸ごとを一時ブランチへ退避すれば、何度でも試行錯誤できます。

git switch -c backup/rebase-$(date +%Y%m%d-%H%M%S)
# 退避後に元ブランチへ戻って rebase をやり直す
git switch <元ブランチ>

まとめ

まず git status で現在地を把握し、コンフリクトならファイル修正と git add の後に git rebase --continue、飛ばしたいなら --skip、全面撤退は --abort を選びます。開始・継続を妨げる未保存変更や untracked の衝突は stash で一時退避し、インタラクティブ rebase のミスは --edit-todo で修正します。万一の取りこぼしは reflog から復旧できるため、慌てず手順を踏めば安全に再開できます。