症状

git submodule update を実行してもエラーが出る、または submodule の内容が更新されない。

結論:まずこれを確認

  1. git submodule status で submodule の状態を確認する
  2. 初期化されていなければ git submodule init を先に実行する
  3. --remote オプションの有無で挙動が変わることを理解する

操作フロー

    flowchart TD
    A[submodule update でエラー/更新されない] --> B{git submodule status を確認}
    B -->|先頭に - がある| C[初期化されていない]
    B -->|先頭に + がある| D[ローカルに未コミットの変更あり]
    B -->|先頭にスペース| E[正常な状態]
    C --> F[git submodule init を実行]
    F --> G[git submodule update を再実行]
    D --> H[submodule内の変更を確認]
    H --> I{変更を残す?}
    I -->|Yes| J[submodule内でcommit/stash]
    I -->|No| K[git submodule update --force]
    E --> L{最新を取得したい?}
    L -->|Yes| M[git submodule update --remote]
    L -->|No| N[親リポジトリ記録のコミットを確認]
  

よくある原因

  • submodule が初期化されていない - clone 直後は init が必要
  • submodule 内にローカル変更がある - 未コミットの変更があると update が止まる
  • .gitmodules.git/config の不整合 - URL やパスが一致していない
  • SSH 鍵や認証の問題 - submodule のリモートにアクセスできない
  • submodule のパスが変更された - 親リポジトリで移動・削除された
  • ネットワークの問題 - リモートに接続できない
  • サブモジュールが detached HEAD 状態 - ブランチ追跡が設定されていない

操作手順

ステップ1: submodule の状態を確認する

    git submodule status
  

出力の見方:

先頭文字 意味
- 初期化されていない
+ 親リポジトリ記録と異なるコミットをチェックアウト中
U マージコンフリクトあり
スペース 正常

🔍 チェックポイント: 先頭が - なら初期化が必要、+ ならローカル変更を確認する

ステップ2: 初期化されていない場合

    git submodule init
git submodule update
  

または一括で実行:

    git submodule update --init
  

再帰的に(submodule の中の submodule も含めて)初期化する場合:

    git submodule update --init --recursive
  

🔍 チェックポイント: 実行後に git submodule status で先頭が - でなくなっていれば成功

ステップ3: submodule 内のローカル変更を確認する

    cd path/to/submodule
git status
git diff
  

変更を残す場合:

    git stash
# または
git commit -m "ローカルの変更を保存"
  

変更を破棄する場合:

    cd ..  # 親リポジトリに戻る
git submodule update --force
  

🔍 チェックポイント: git status でクリーンな状態になっていれば update 可能

ステップ4: リモートの最新を取得する場合

親リポジトリに記録されたコミットではなく、submodule のリモート最新を取得する場合:

    git submodule update --remote
  

特定の submodule のみ更新:

    git submodule update --remote path/to/submodule
  

🔍 チェックポイント: git diff で submodule の参照コミットが変わっていれば成功

ステップ5: URL や設定の不整合を修正する

.gitmodules の設定を .git/config に同期する:

    git submodule sync
git submodule update --init
  

🔍 チェックポイント: git config --list | grep submodule で URL が正しいことを確認

ステップ6: 認証エラーの場合

SSH 接続を確認:

    ssh -T git@github.com
  

HTTPS に切り替える場合:

    git config submodule.path/to/submodule.url https://github.com/user/repo.git
git submodule sync
  

🔍 チェックポイント: 認証成功のメッセージが表示されること

NG行動

やってはいけないこと 理由
submodule ディレクトリを手動で rm -rf して再 clone .git/modules 内のキャッシュと不整合が起きる
git submodule update --force を状況確認せずに実行 ローカルの作業中の変更が消える
.gitmodules を直接編集して sync を忘れる .git/config と不整合になり動作しない
submodule 内で直接 git pull して親で commit しない 他の人が clone したとき古いコミットを参照する

よくある質問(FAQ)

Q1: --init--remote の違いは?

A: --init は未初期化の submodule を初期化する。--remote は submodule のリモートブランチの最新コミットを取得する。親リポジトリに記録されたコミットを取得するだけなら --remote は不要。

Q2: clone 時に submodule も一緒に取得するには?

A: git clone --recurse-submodules URL を使用する。既存のリポジトリなら git submodule update --init --recursive を実行する。

Q3: submodule を完全に削除するには?

A: 以下の手順で削除する:

    git submodule deinit -f path/to/submodule
rm -rf .git/modules/path/to/submodule
git rm -f path/to/submodule
git commit -m "Remove submodule"
  

関連するトラブル

準備中

解決しない場合

  • 公式ドキュメント: Git - Submodules
  • 確認すべきファイル: .gitmodules, .git/config, .git/modules/
  • 次に調べるキーワード: git submodule foreach, git submodule absorbgitdirs, gitmodules path mismatch