できない.dev

Git submodule のファイルが空のまま更新できない

submodule は clone 時に自動取得されない。
--recurse-submodules 付きで clone するか、後から git submodule update --init --recursive を実行する。
親リポジトリと submodule は別の HEAD を持つため pull とのセット運用も必要。

#git#submodule#clone#recursive#update

公開:

要約

Git submodule のディレクトリは clone しただけでは中身が空のまま。git clone --recurse-submodules を付けるか、後から git submodule update --init --recursive を実行することで取得できる。
親リポジトリと submodule は別の HEAD を持つので、親を pull した後の同期も忘れやすい。

よくある原因

  1. clone 時にオプション未指定: git clone <url> だけ実行すると .gitmodules に書かれた submodule の中身は取得されず、ディレクトリだけが空の状態で作られる。
  2. submodule 初期化忘れ: 後から submodule が追加されたリポジトリで git pull しても、submodule ディレクトリは空のままで git submodule update --init が必要。
  3. 親リポジトリの更新後: 親が submodule の新しいコミットを指していても、ローカルの submodule HEAD は古いコミットのままになり、git submodule update で追従させる必要がある。
  4. URL 変更未反映: .gitmodules で submodule の URL が変わったが、ローカルの .git/config 側は古い URL を保持しているため fetch 先が間違っている。

解決策

1. 初回 clone でまとめて取得

git clone --recurse-submodules https://example.com/parent.git

--recurse-submodules を付けると、親 clone 完了後に自動で submodule init + submodule update が走る。

2. 既存 clone を初期化する

git submodule update --init --recursive

--init.gitmodules を読み .git/config に submodule を登録するステップ、--recursive はネストした submodule にも適用する。
詳しくは git-submodule 公式ドキュメント を参照。

3. 親の pull とセットで実行

git pull
git submodule update --init --recursive

親の commit が submodule の新しい SHA を指していると、git statusmodified content と表示されることがある。update で submodule の HEAD を親が指す SHA に揃える。

4. URL が変わったとき

git submodule sync --recursive
git submodule update --init --recursive

.gitmodulesurl 行を .git/config 側に反映するのが sync
リポジトリ移行後にはこの 2 行を流すと安全。
さらに踏み込んだ運用は Pro Git の Submodules 章 が詳しい。

この記事は役立ちましたか?