TL;DR: クイック解決策
このエラーが発生する主な理由は、Gitのインデックス(内部のステージングエリア)が特定のフォルダをサブモジュールとして認識しているものの、.gitmodulesファイル内に対応するURLが見つからないためです。目的に応じて2つの解決方法があります。
方法A: サブモジュールを再登録する
そのフォルダがサブモジュールであるべき場合は、リモートリポジトリの場所をGitに教えます。libs/uiを実際のパスに置き換えてください。
# Gitがインデックスにパスが既に存在すると表示した場合は、まず消去します:
git rm --cached libs/ui
# その後、正しく追加し直します:
git submodule add https://github.com/username/repo.git libs/ui
方法B: 通常のフォルダに変換する
独自の.git履歴を含むフォルダを誤って追加していませんか?サブモジュールのメタデータを削除して、通常のディレクトリとして管理するように変更できます。
git rm --cached libs/ui
rm -rf libs/ui/.git # 内部のGit履歴を削除
git add libs/ui
git commit -m "壊れたサブモジュールを通常のディレクトリに変換"
なぜGitはこのエラーを出すのか?
Gitのサブモジュールは、.gitmodulesファイル、.git/configファイル、そしてGitインデックスの間のデリケートな3者間連携に依存しています。「fatal: No url found」エラーは、この連携が崩れた時に発生します。
具体的には、Gitインデックスには「gitlink」が含まれています。これは別のリポジトリの特定のコミットを指し示す特別な160ビットのエントリです。git submodule updateなどのコマンドを実行すると、Gitはそのgitlinkを確認し、次に.gitmodulesを見てダウンロード元を探します。もしURLが見つからないか、名前が完全に一致しない場合、Gitは処理を中断します。
この混乱を招く一般的なシナリオは以下の通りです:
- マージの失敗:
.gitmodulesでのマージコンフリクトを解消する際に、誤って必要な行を削除してしまった。 - 手動での削除: 開発者がテキストファイルからサブモジュールのエントリを削除したが、Gitの内部追跡(インデックス)からの削除を忘れた。
- ネストされたリポジトリ: 他のプロジェクトからライブラリ(
vendor/bootstrapなど)をコピーしたが、その中に独自の.gitフォルダが隠れたままだった。
実証済みの修復方法
1. .gitmodulesの手動修復
最も簡単な解決策は、設定を自分で記述することです。エディタで.gitmodulesを開き、フォルダパスに合わせて以下のブロックが正しく記述されているか確認してください。
[submodule "libs/ui"]
path = libs/ui
url = https://github.com/example/ui-library.git
ここでの正確さが重要です。[submodule "name"]内の文字列は、プロジェクト構造と一致している必要があります。ファイルを保存したら、以下のコマンドを実行して状態を同期させます。
git submodule sync
git submodule update --init --recursive
2. 「幽霊」サブモジュールの除去
フォルダをサブモジュールにするつもりがなかった場合、Gitが古い.gitファイルによって混乱している可能性があります。これを修正するには、実際のファイルを削除せずにインデックスからパスを削除する必要があります。git rm --cached folder/pathを使用しますが、末尾にスラッシュを付けないように注意してください。これにより、Gitはそのディレクトリを別のリポジトリへのリンクとして扱うのをやめます。
3. サブモジュールキャッシュのリセット
設定が正しく見えるのにエラーが消えない場合は、ローカルキャッシュが壊れている可能性があります。インデックスからエントリを削除して再度追加することで、強制的にリセットできます。これによりgitlinkが更新され、.git/configファイルが.gitmodulesと一致するように更新されます。
リポジトリの状態を確認する
修正を適用した後、すべてが正常に戻ったか確認するために以下の3つのチェックを行ってください。
- ステータスチェック:
git submodule statusを実行します。コミットハッシュの後にパスが表示されるはずです。エラーが出なければ問題ありません。 - 設定チェック:
cat .git/configを実行します。そこの[submodule]セクションが.gitmodulesの内容と一致しているか確認してください。 - ディープアップデート:
git submodule update --init --recursiveを実行します。これが最終テストです。致命的なエラーなしで完了すれば、プロジェクトは完全に修復されています。

