git cloneを実行したのに、次のような警告が出てカレントディレクトリにファイルが展開されないことがあります。
$ git clone https://github.com/user/repo.git Cloning into 'repo'... warning: remote HEAD refers to nonexistent ref, unable to checkout.
このwarningはリモートのHEAD(デフォルトブランチの参照)が指している先が存在しないことをGitが伝えています。cloneは内部的には完了していますが、「どのブランチにチェックアウトすべきか」が分からずファイルが配置されていません。結果として、ローカルディレクトリは存在するのに作業ツリーが空の状態になります。
この記事では、このwarningの正体と4つの典型原因、リモート側・クライアント側それぞれの修復手順、GitHubやGitLabで起きる特有のパターン(master→main改名直後など)、そして同じ問題を起こさないための予防策までを解説します。
この記事で学べること
- 「remote HEAD refers to nonexistent ref」が発生する4つの原因
- HEAD(
refs/remotes/origin/HEAD)とは何か - リモート側の修正:GitHub UIでdefault branchを更新する手順
- クライアント側の修正:
git remote set-headで追跡を修復 - 空リポジトリ/master→main改名直後/削除済みブランチへの対処
- cloneが完了しているのにファイルが見えないケースの復旧
- 同じ問題を起こさないチーム運用ルール
エラーの正体:HEADが「存在しない参照」を指している
GitリポジトリにはHEADという特別な参照があり、「デフォルトブランチ(初期ブランチ)」を指しています。cloneするとクライアント側にrefs/remotes/origin/HEADとしてこの情報がコピーされ、「このブランチをcheckoutすればいい」という指示になります。このHEADが指すブランチがリモート側で削除・改名されていると、「存在しない参照」という状態になってwarningが発生します。
# リモート側HEADの情報(git protocol) git ls-remote --symref origin HEAD # 出力例: # ref: refs/heads/main HEAD ← mainを指す # abc1234... HEAD # クライアント側HEADの設定 cat .git/refs/remotes/origin/HEAD # または git symbolic-ref refs/remotes/origin/HEAD # リモートで存在するブランチ一覧 git ls-remote --heads origin
ポイント:このwarningはcloneが失敗したわけではないことに注意。リポジトリは.gitごとダウンロードされ、すべてのブランチがgit branch -rで見えます。「どのブランチに自動でチェックアウトすべきか分からなかった」だけなので、存在するブランチをcheckoutすれば作業ツリーが復活します。
4つの典型原因
このwarningが出る状況は限定的です。次の4パターンのいずれかに該当します。
どれに当てはまるかを判定
git ls-remote --symref origin HEADで現在HEADが指すブランチを確認git ls-remote --heads originで実在ブランチ一覧を確認- HEADが指すブランチが実在しない → ①②④のいずれか
- 実在ブランチが0件 → ③空リポジトリ
STEP 0:診断してから対処を選ぶ
闇雲に試すより、まず状態を正確に把握する方が早いです。GitHubなどホスティング側の管理画面と、Gitの問い合わせコマンドを併用します。
# リモートのHEADが指す先を確認 git ls-remote --symref origin HEAD # → ref: refs/heads/XXX ← このXXXが実在するかが鍵 # ブランチ一覧(HEAD候補) git ls-remote --heads origin # cloneしたあとの状態確認 cd repo git branch -a # → 存在するリモート追跡ブランチ一覧 # 現在HEADの状況 git status # → "HEAD detached" 等の表示がヒントになる
注意:GitHub/GitLab/Bitbucket等のホスティング側では「デフォルトブランチ」という独自設定を管理画面で持っています。ここを直さない限り、クライアント側でいくら修復しても新規cloneではまたwarningが出ます。根本解決はリモート側設定の更新、クライアント側は症状緩和と覚えましょう。
解決①:ホスティング側でデフォルトブランチを更新する(根本対処)
警告の根本原因はリモートHEADが「存在しないブランチ」を指していることなので、GitHub/GitLab/Bitbucket等の管理画面からデフォルトブランチを正しく設定するのが本筋です。
GitHubでのデフォルトブランチ更新
- リポジトリページ → Settings タブ
- 左メニュー General → Default branch セクション
- 切替アイコン(⇆)をクリック → 実在するブランチを選択 → Update
- 確認ダイアログで I understand, update the default branch を押す
- CI/保護ルール/webhook等の再設定が必要なら併せて更新
GitLab/Bitbucketの場合
- GitLab:Settings → Repository → Default branch
- Bitbucket:Repository settings → Branches → Main branch
- Azure DevOps:Project settings → Repositories → 対象リポ → Default branch
- 自前Gerrit/Gitea/Soft Serve等も管理画面に同様のdefault branch設定あり
自前サーバーでbareリポを直接操作する場合
# サーバーにSSHでログイン ssh git@your-server.example.com cd /path/to/repo.git # 現在のHEAD設定を確認 cat HEAD # 例: ref: refs/heads/master # 実在ブランチを指すよう書き換え git symbolic-ref HEAD refs/heads/main # 確認 cat HEAD # ref: refs/heads/main
ポイント:GitHubなどSaaSの場合は管理画面のUIで完結、自前ホスティングの場合はサーバー側でgit symbolic-ref HEADを書き換えます。いずれも「HEADがどのブランチを指すか」の1箇所を直すだけで根本解決します。
解決②:クライアント側で追跡情報を修復する
リモート側の管理権限が無い、あるいは「今すぐ作業を進めたい」場合はクライアント側だけで応急対処できます。git remote set-headを使います。
# リモートに問い合わせて実在のdefault branchを自動検出+設定 git remote set-head origin --auto # 出力例: origin/HEAD set to main # 明示的に指定する git remote set-head origin main # いったん解除(稀) git remote set-head origin --delete # 確認 git symbolic-ref refs/remotes/origin/HEAD # → refs/remotes/origin/main
作業ツリーにブランチを展開する
# cloneしたがカレントに作業ツリーが無い状態 cd repo ls # → 空っぽ # 実在ブランチを一覧 git branch -r # origin/main # origin/develop # ローカルブランチを作って切り替え git switch main # Git 2.23+ なら自動でリモート追跡を設定 # 旧コマンドでの対応 git checkout -b main origin/main
ポイント:警告が出たあとでもcloneしたデータは無事です。作業ツリーが空なだけで、.git内にはすべての履歴があります。実在するブランチをcheckoutすれば、そこから通常どおり開発を始められます。
原因別の対処レシピ
ケースA:master→main改名直後の残存影響
GitHubでは2020年にmaster→mainへの移行を促進しました。古いリポだと改名時にdefault branch設定がずれているケースがあります。
# 実在ブランチを確認 git ls-remote --heads origin | grep -E "master|main" # クライアントのHEAD追跡を更新 git remote set-head origin --auto # ローカルがmasterを指していた場合の移行 git switch main # Git 2.23+で自動トラック # 古い master ローカルブランチを削除(不要) git branch -d master
master→main移行とブランチ名変更全般はブランチ名を変更する方法も参考にしてください。
ケースB:デフォルトブランチが削除されてしまった
# 管理権限があるなら GitHub UIで # Settings → General → Default branch → 別ブランチに切替 # その後、削除されたブランチをreflogから復元 git clone https://github.com/user/repo.git cd repo git reflog --all | grep "deleted-branch-name" # 見つかったSHAで復元(権限があれば)
main削除からの復旧は誤ってmaster/mainを削除したときの復旧方法を参照。
ケースC:空リポジトリをcloneした
空リポの挙動
- 1つもcommitが無いリポはHEADが仮の状態になる
- warningは出るが、cloneできているのでディレクトリ移動してpush準備できる
- 最初のcommit+pushでdefault branchが確定する
cd repo # Gitのデフォルトブランチ名設定(任意) git config --global init.defaultBranch main # 空リポなので git initの代わりに branch を切る git switch -c main # 最初のcommit echo "# My Project" > README.md git add README.md git commit -m "feat: initial commit" git push -u origin main
ケースD:自前GitサーバーのbareリポでHEAD不整合
ssh git@server cd /var/git/repo.git # 現状 cat HEAD # ref: refs/heads/nonexistent-branch # 実在ブランチを確認 ls refs/heads/ # main develop # HEADを実在ブランチに向ける git symbolic-ref HEAD refs/heads/main
再発防止のチーム運用
同じ問題を起こさないために
- Branch protection rulesでdefault branchを保護して削除禁止に
- ブランチ名変更時はdefault branchを先に切替→古い名前を削除、の順序
- GitHubの「Rename branch」機能を使うとdefault branchが自動追従する
- 空リポを作る時は
Initialize with READMEで最初のcommitを入れておく - 自前サーバー運用なら定期的に
git symbolic-ref HEADを確認するスクリプトを入れる - cloneスクリプトには
git remote set-head origin --autoを忘れずに
#!/bin/bash
# safe-clone.sh
REPO_URL=$1
git clone "$REPO_URL"
cd "$(basename "$REPO_URL" .git)"
# HEADがない場合の自動修復
if ! git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null; then
git remote set-head origin --auto
fi
# 作業ツリーが空だったら実在ブランチに切替
if [ -z "$(ls -A)" ] || [ "$(ls -A | wc -l)" -eq 1 ]; then
git switch "$(git remote show origin | grep "HEAD branch" | awk '{print $NF}')"
fi
実践シナリオ
シナリオ① cloneしたらフォルダが空だった
git clone https://github.com/user/repo.git # warning: remote HEAD refers to nonexistent ref cd repo ls # → 空 # 応急対処:実在ブランチを確認してcheckout git branch -r git switch main # 実在するブランチ名 # 本対処:管理者に伝えてdefault branch設定の更新を依頼
シナリオ② master→main改名を自分で実施
# STEP 1: ローカルを改名 git branch -m master main # STEP 2: 新ブランチをpush(upstreamも設定) git push -u origin main # STEP 3: GitHub UIでdefault branchをmainに変更(先に!) # STEP 4: 旧masterを削除 git push origin --delete master # STEP 5: クライアントのHEAD追跡を更新 git remote set-head origin --auto
改名の詳細はブランチ名を変更する方法を参照。
シナリオ③ 新規リポジトリ作成直後のclone
git clone https://github.com/user/empty-repo.git # warning: you appear to have cloned an empty repository. cd empty-repo # デフォルトブランチ名の設定 git config --global init.defaultBranch main git switch -c main # 初期ファイル cat > README.md << "EOF" # My Project EOF git add README.md git commit -m "feat: initial commit" git push -u origin main
やってはいけない落とし穴
警告を見てcloneを何度もやり直す
warningが出てもcloneは成功しています。再clone前に、まずcd repoで移動しgit branch -rで実在ブランチを確認してください。再cloneしても同じwarningが出る根本原因(default branch設定ズレ)は解消しません。
リモートを操作せずクライアント側だけで済ませる
git remote set-head origin --autoは自分のローカルだけ修復します。リモート側のHEAD設定はそのままなので、他メンバーが新規cloneしたときに同じwarningが出続けます。管理権限があるなら、リモート側のdefault branch設定を正しく直すことが根本解決です。
GitHubの削除済みブランチを復活させずに新ブランチを作る
誤削除したdefault branchを復旧せずに新しい名前を作ると、PR・履歴・webhookなど過去の参照がすべて無効化されます。まずは誤ってmaster/mainを削除したときの復旧方法でreflogから復元を試みてください。
自前サーバーでHEADファイルを直接編集してtypo
bareリポのHEADファイルをechoやviで編集してrefs/heads/mianのようにtypoすると、またwarningが再発します。必ずgit symbolic-ref HEAD refs/heads/mainコマンド経由で設定し、git ls-remote --symrefで検証してください。
空リポに.gitignoreや.gitattributesだけpushしてdefault確定したつもりになる
これらのファイルだけでは一部のホスティングサービスで自動的にdefault branchが確定しないことがあります。確実に初期化するならREADME.md等を含めた最初のcommitをしてからpushしてください。
よくある質問
.git配下に全部あります。git branch -rで実在するリモートブランチを確認し、git switch <branch>で切り替えればファイルが作業ツリーに展開されます。refs/remotes/origin/HEADを更新します。これでgit branch -rの出力や補完などが正常化します。git remote set-head origin --auto+git switch 実在ブランチで作業自体は進められます。ただしリモート側設定が間違っている根本原因は残るため、管理者へ連絡して修正を依頼するのが理想です。cd repoしてブランチを作り最初のcommitをpushすればdefault branchが確定します。以降のcloneでwarningは出なくなります。on: push対象・GitHub Pagesの公開元・webhook等が連動します。Rename機能を使うと多くの連携が自動更新されるので、UIで切り替えるのが無難です。git symbolic-refを直すと履歴はどうなる?git ls-remote --symref origin HEADが最も確実です。ref: refs/heads/xxxのxxxが現在のdefault branch名です。GitHub UIではリポジトリトップで「X branches」の隣にbranch名表示、Settings → Branches でも確認できます。関連記事
- 【Git】誤ってmaster/mainを削除したときの復旧方法 — default branch復旧全般
- 【Git】ブランチ名を変更する方法 — master→main移行の手順
- 【Git】リモートブランチを確認する方法 — ls-remote/branch -aの使い分け
- 【Git】ブランチを削除する方法 — 削除前の安全確認
- 【Git】新しいブランチを作成する基本的な手順 — ブランチ作成の基礎
- 【Git】「does not appear to be a git repository」エラー — リモート設定関連エラー
- 【Git】リモートブランチを削除しても残ってしまうときの原因と解決方法 — prune運用
- 【Git】よく使うgitコマンドまとめ — 日常コマンドの早見表
まとめ
- 警告の正体は「リモートHEADが存在しないブランチを指している」ことで、cloneは成功している
- 原因は4種類:default削除/改名/空リポ/bareリポのHEAD不整合
- 診断は
git ls-remote --symref origin HEADで開始 - 根本解決はリモート側のdefault branch設定更新(GitHub等のUI)
- 応急対処はクライアントで
git remote set-head origin --auto+git switch - 自前サーバーはbareリポで
git symbolic-ref HEAD refs/heads/main - 予防:Branch protectionでdefault削除禁止・Rename機能利用・初期commit必須
このwarningに遭遇しても、焦らずにまずcdで中に入り、git branch -rとgit ls-remote --symrefで状況を把握すれば、多くは5分以内に作業再開できます。「cloneに失敗した?」と思っても、Gitのデータ自体は無事なので慌てずに診断から始めましょう。根本解決にはリモート側のdefault branch設定更新が必要ですが、クライアント側でも応急対処は十分可能です。予防策と合わせて押さえておけば、チーム内で同じ問題が繰り返し発生することも避けられます。

