Claude Media
「Could not find merge-base」の対処 — Claude Code

「Could not find merge-base」の対処 — Claude Code

Claude Codeのultrareviewが「Could not find merge-base with the base branch」で拒否したときの3パターンの見分け方と、fetch・ベースブランチ指定による対処を確認します。

/code-review ultraやclaude ultrareviewが「Could not find merge-base with the base branch」で止まったとき、まず見るのは最初の文に続くヒントです。ヒントの文言で、ブランチ名の問題なのか、クローンの履歴が足りないのか、そもそも共有履歴がないのかが分かれます。ultrareviewは、ブランチとベースブランチが共有するコミット(merge-base)を起点に差分を取ります。git merge-baseが何も返さないと、クラウドセッションを起動する前にレビューを拒否します。

ヒントで原因を切り分ける

エラーは、定型の1文目と原因別のヒントでできています。変わるのはヒントの部分です。

Could not find merge-base with main. Pass the base branch explicitly (e.g. `/code-review ultra develop`) or make sure you're in a git repo with a main branch.
くらべる

ヒントの文言から原因を読む

ベース未指定

Pass the base branch explicitly

ベースを渡さなかったため、リポジトリの既定ブランチと比べて失敗した状態です。/code-review ultra developのように比較先を渡します。

指定ブランチが手元にあった

Make sure <branch> exists locally or on origin

指定したブランチは既にローカルクローンにあります。ヒントの括弧にgit fetch origin <branch>が示されます。

指定ブランチが手元になかった

was fetched from origin but shares no history with HEAD

Claude Codeがoriginから取得して比べた結果、HEADと共通の履歴がありませんでした。本当のベースが別のブランチなら、そちらを明示します。

3つ目の文言には例外があります。クローンが浅いのかどうかをClaude Codeが判断できないときは、共有履歴がないという言い方をやめてgit fetch --unshallow originを勧めます。浅いクローンとは、git clone --depth=1のように履歴を切り詰めたクローンのことです。

拒否される場合と、全ファイルレビューに切り替わる場合

merge-baseが見つからなくても、常に拒否されるわけではありません。Claude Codeがクローンを完全だと確認でき、ブランチが1つ以上あるときは、リポジトリの追跡対象ファイルをすべてレビューする形に切り替わります。

この切り替えには、同意の手順が付いています。起動してよいのは、起動ダイアログで確認したときか、claude ultrareviewサブコマンドを自分で実行したときだけです。claude -pのように、どちらも成り立たない実行方法では、全ファイルが対象になることを告げて拒否し、対話セッションを案内します。切り替え後も、通常のブランチレビューと同じサイズ上限(既定で変更500ファイル・8,000行)が掛かります。

全ファイルレビューが大きすぎる場合の出口は、PRモードです。ブランチレビューはリポジトリの状態をまとめてクラウドへアップロードするため、大きすぎるリポジトリでは、PRモードを使うよう促されます。ブランチをpushしてドラフトPRを開き、/code-review ultra <PR番号>を実行します。PRモードでは、手元からは何もアップロードされません。

拒否になるのは次のいずれかです。

  • ベースブランチが見つからない
  • クローンが完全かどうかを判断できない
  • SHA-256オブジェクト形式のように、リポジトリ全体の差分を作れない

ブランチが1本もないdetached HEADは、これより手前の別のエラーです。そちらは「Your checkout has no branches」の対処にまとめています。

実行方法ごとの違い

全ファイルレビューへの切り替えは、実行方法によって扱いが変わります。

/code-review ultraは、起動ダイアログで確認を求めます。claude ultrareviewサブコマンドは、自分で実行したこと自体を同意とみなし、入力を待たずに始めます。CIやスクリプトで使うのはこちらです。ただしClaudeがBashツール経由でサブコマンドを実行した場合は、全ファイルのレビューを拒否します。

claude -p '/code-review ultra'は、クラウドのレビューを起動したあとすぐに終了し、指摘は返ってきません。スクリプトではclaude ultrareviewを使うのが、ドキュメントの案内です。v2.1.218より前は、非対話セッションの/code-review ultraがローカルレビューを実行していました。

対処の順番

ヒントを読んだら、次の順で試します。

手順

merge-baseエラーの対処手順

  1. 1

    ベースブランチを明示して再実行する

    /code-review ultra developのようにブランチ名を渡します。ベースがローカルになくても、Claude Codeがoriginから取得してから比べます。名前に打ち間違いがあるときは、近いブランチ名がエラーに添えられます。ベースにはブランチ名のほか、コミットIDやタグも使え、そのコミット以降のブランチの変更がレビュー対象になります。

  2. 2

    ヒントが示すコマンドを実行する

    git fetch origin <branch>かgit fetch --unshallow originのうち、表示されたほうを実行して再実行します。

  3. 3

    それでも直らなければベースが正しいか疑う

    ヒントが「共通の履歴がない」に変わっているなら、履歴の深さではなく比較先の選び方が原因です。実際の分岐元のブランチを渡します。

小さなリポジトリで履歴の仕組みを再現する

履歴の仕組みは、一時ディレクトリで小さなリポジトリを作ると手早く確かめられます。mainに3コミットを積み、そこから履歴を共有しないdocsブランチをgit checkout --orphanで作ります。

git init -q -b main src && cd src
git commit -q --allow-empty -m c1 && git commit -q --allow-empty -m c2
git checkout -q --orphan docs
git commit -q --allow-empty -m d1
git merge-base main docs; echo "exit=$?"

git merge-baseは何も出力せず、終了コード1を返します。エラーの文面を出しているのはClaude Codeですが、元になる事実はこの「共有コミットがない」という結果です。次に、同じリポジトリをfile://付きで浅くクローンし、git fetch --unshallow originを2回続けます。ローカルのパスのままでは--depthが無視され、最初から完全なクローンになってしまいます。1回目は履歴を取得して終わり、2回目は完全なクローンに対する実行になります。

git clone -q --depth=1 file://$PWD ../cl && cd ../cl
git fetch --unshallow origin
git fetch --unshallow origin
fatal: --unshallow on a complete repository does not make sense

2回目が終了コード128で失敗するこの文言は、エラー一覧がv2.1.221より前の不具合として挙げているものと同じです。当時は、取得済みのベースブランチすべてに--unshallowを勧めていたため、完全なクローンでは勧められたコマンドが必ず失敗しました。v2.1.221以降は、クローンが完全かどうかを見てヒントを出し分けます。更新前でも、完全なクローンなら--unshallowのヒントは読み飛ばし、ベースブランチの指定を見直します。

浅いクローンでは履歴の深さを足す

--depth付きのクローンは履歴が途中で切れているため、共有コミットまで遡れないことがあります。ヒントがgit fetch --unshallow originを勧めているなら、そのまま実行します。

git fetch --unshallow origin

履歴が大きいリポジトリでは、全履歴の取得に時間もデータ量もかかります。単発の作業なら、git fetch --depth=<N> origin <branch>で深さを広げる方法もあります。毎回の実行で全履歴を取り直すのが重いなら、ultrareviewを走らせるジョブのチェックアウトだけ、深さを十分に取る設定にしておく方法もあります。

オーファンブランチは全ファイルレビューの対象になる

git checkout --orphanで作ったブランチは、既存のどのブランチとも履歴を共有しません。gh-pagesのような公開用ブランチや、ドキュメント専用のブランチでよく使われます。前節の再現のとおり、このブランチとmainの間ではgit merge-baseが必ず空を返します。

このとき、ultrareviewは完全なクローンなら拒否ではなく全ファイルレビューに回ります。レビュー対象はオーファンブランチの差分ではなく、追跡対象ファイル全体です。上限に収まらない規模なら、サイズ超過の拒否に変わります。

全体ではなく一部のファイルだけを見たいなら、ローカルの/code-reviewを使う手があります。ドキュメントの比較表では、ローカルの/code-reviewは作業中の差分・PR・ブランチ・パスを対象にでき、/code-review ultraは作業中の差分とPRが対象とされています。

ベースブランチがないリポジトリ

git initしただけでoriginがなく、比較先のベースブランチも無いリポジトリには、比べる相手がありません。ドキュメントは「リポジトリに比較するベースブランチがない」場合を、共有履歴がないときと同じ全ファイルレビューの扱いとしています。クローンが完全で、ブランチが1つ以上あれば、確認のうえで全体がレビューされます。

最初のコミットだけのリポジトリは別扱いです。比べる過去がないため、起動ダイアログでの確認後に全ファイルをレビューします。未追跡ファイルがあると、レビューしたいファイルをgit addするよう促されて拒否されます。サブコマンドやclaude -pでは、同じく拒否されて対話セッションを案内されます。この動作にはv2.1.277以降が必要です。

並列セッションで作業ツリーを分けている場合の注意点は、Claude Code Worktree実践ガイド — 並列セッションの隔離と落とし穴にあります。

差分が空のときは別のメッセージになる

「Could not find merge-base」と似た場面で、ベースとの差分が空のときは別の拒否になります。merge-baseの計算は成功しているので、比較の起点が見つからない今回のエラーとは原因が違います。

この場合は、どのブランチやコミットと比べたかと、今がどのケースにあたるかが示されます。たとえばベースブランチ自体にいて未コミットの変更もない、ブランチのコミットがすべてベースに含まれている、といったケースです。作業のあるブランチへ切り替える、変更をステージするかコミットする、別のベースを渡す、といった抜け道も添えられます。

よくある質問

PRを指定したレビューでも同じエラーが出ますか

PRモードは、手元の作業ツリーをまとめて送るのではなく、クラウドのサンドボックスがホストからPRを直接クローンします。ローカルの履歴の深さは関係しません。PRレビューで別の拒否に当たった場合は、先に「ブランチレビューか、PRレビューか」を切り分けます。

全ファイルレビューが走ってしまったときは

実際の分岐元になるブランチを明示すれば、差分ベースに戻ります。たとえば/code-review ultra developです。履歴を共有しないブランチ同士では、ベースを渡しても戻りません。全ファイル対象のレビューは、差分ベースより対象範囲が広くなります。

この記事を共有:XはてブLinkedIn