問題の発生Git リポジトリを新しくクローンしたばかりで、すべてが順調に見えるのに、特定のサブフォルダに入ると様子がおかしいことがあります。期待していたライブラリや共有コンポーネントの代わりに、ディレクトリは完全な空の状態になっています。コードをコンパイルしたりビルドスクリプトを実行したりしようとすると、Git は次のようなエラーを表示してプロセスを停止させます。
Submodule path 'folder_name' not initialized. Use 'git submodule update --init' to fix it.
これは、標準的な git clone がメインプロジェクトのファイルのみを取得するために起こります。Git はサブモジュールを個別のエンティティとして扱います。明示的にコンテンツを要求するまで、それらのフォルダは空のシェルのまま放置されます。
なぜ Git はサブモジュールを空のままにするのかサブモジュールを「ブックマーク」と考えてみてください。メインリポジトリ(「スーパープロジェクト」)は、実際にはサブモジュールのファイルを保存していません。その代わりに、どのバージョンの外部リポジトリを使用すべきかを Git に伝える、特定の 40 文字のコミットハッシュという小さなポインタを保存しています。メインリポジトリをクローンした際、Git はそのポインタを認識しますが、大容量の外部ライブラリデータをダウンロードする前に、ユーザーからのコマンドを待ちます。
解決策 1:すでにクローン済みのリポジトリを修正するすでにプロジェクトをクローンしており、空のフォルダを前に途方に暮れているなら、数秒で修正できます。プロジェクトのルートディレクトリから以下のコマンドを実行してください。
ステップ 1:サブモジュールの登録まず、Git に対して .gitmodules ファイルを確認し、ローカル設定をセットアップするように指示する必要があります。
git submodule init
ステップ 2:データの取得次に、実際にリモートサーバーにアクセスしてファイルをダウンロードするように Git に指示します。このコマンドは、メインプロジェクトに記録されている特定のコミットハッシュをチェックアウトします。
git submodule update
プロのショートカットほとんどの開発者は、これらを 1 つのコマンドにまとめます。この方が高速で、何もしなければ空のままになってしまうネストされたサブモジュール(サブモジュールの中のサブモジュール)も処理できます。
git submodule update --init --recursive
常に --recursive フラグを使用することをお勧めします。プロジェクト構造が複雑な場合でも、手動でのトラブルシューティングの手間を省くことができます。
解決策 2:最初のクローン時にエラーを防止するすべてを一度にプルすることで、この面倒な問題を完全に回避できます。新しいプロジェクトをクローンする際、コマンドにフラグを 1 つ追加するだけです。
git clone --recurse-submodules https://github.com/username/repository.git
Git のバージョンが 2.13 より古い場合は、代わりに --recursive を使用する必要があるかもしれません。モダンなバージョン(2.13 以降)では --recurse-submodules が推奨されますが、どちらも基本的には同じ結果になります。
修正を確認する方法コマンドが完了すると、フォルダ内にファイルが表示されるはずです。しかし、Git にステータスを確認させるのがより確実です。
1. ファイルの一覧を表示するフォルダのサイズを確認するか、隠しファイルを表示して、サブモジュール内に .git ファイルが存在することを確認します。
ls -la folder_name/
2. Git の内部ステータスを確認するサブモジュールのステータスコマンドを実行して、Git がローカルファイルをどのように認識しているか正確に確認します。
git submodule status
先頭の記号に注目してください。- はサブモジュールがまだ初期化されていないことを意味します。+ はファイルは存在するが、チェックアウトされているバージョンがメインリポジトリの期待するものと一致していないことを意味します。空白(記号なし)であれば、すべてが完璧な状態です。
よくある落とし穴のトラブルシューティング### .gitmodules ファイルが見当たらないgit submodule init を実行しても何も起こらない場合は、プロジェクトのルートに .gitmodules ファイルがあるか確認してください。このテキストファイルはマップの役割を果たします。これがないと、Git はサブモジュールがどこにあるのか判断できません。正常なファイルは以下のようになっています。
[submodule "folder_name"]
path = folder_name
url = https://github.com/example/library.git
認証の失敗サブモジュールがプライベートリポジトリである場合、サブモジュールの更新はしばしば失敗します。メインリポジトリが HTTPS を使用し、サブモジュールが SSH を使用している場合、Git は設定されていないキーを要求することがあります。更新を実行する前に、サブモジュールの URL に個別にアクセスできることを確認してください。
Detached HEAD(分離された HEAD)状態git submodule update を実行した後、サブモジュールは「Detached HEAD」状態になります。これは正常ですので、心配はいりません。Git はブランチ名ではなく、特定のコミットを指しています。そのサブモジュール内でコードを書く必要がある場合は、まずそのフォルダ内で git checkout main などを実行してブランチに移動してください。
クリーンな状態を強制する誤ってフォルダ内のファイルを変更してしまったために、サブモジュールの更新が失敗することがあります。それらの変更を破棄して正しいファイルを取得したい場合は、force フラグを追加します。
git submodule update --init --recursive --force

