テクノロジー · 実用ガイド
Git submodule の「not our ref」?置き換える前に記録済みコミットを追跡する
ハッシュは期待したブランチではなくスーパープロジェクトから来ます。gitlink、実効 URL、ローカルオブジェクトとリモート到達性を記録してから、sync、push、fork、または意図的な置換を選びます。

「not our ref」は --force を重ねる合図ではありません。スーパープロジェクトが要求した正確なオブジェクトを現在の経路が渡せなかったという意味です。
安全な順序は記録、経路、オブジェクト、修復です。gitlink OID と実効 URL を確認し、ローカル存在とリモート到達性を証明してから修復します。
失敗状態を保存し gitlink を読む
rm -rf、deinit、--force、--remote より先に、失敗したスーパープロジェクトのコミット、完全なエラー、パス、ローカル作業を保存します。git ls-tree HEAD -- path/to/submodule の mode 160000 エントリが正確な OID です。
この OID が最初の証拠です。.gitmodules のブランチ名はピンの代わりではありません。CI が別の OID を示すなら、現在のブランチ先端ではなく実際に失敗したコミットを調べます。
Git が実際に使う URL を確認する
.git/config と .gitmodules の submodule URL を比較します。初期化時に URL がコピーされ、その後 .gitmodules を変えても古い checkout は自動更新されません。正しい OID を誤ったリポジトリへ要求する場合があります。
意図的な移転なら git submodule sync --recursive 後に再確認します。sync はオブジェクトも権限も作りません。認証情報を含めずに実効 URL を記録します。
ローカル存在・公開参照・取得可能性を分ける
submodule 内で git cat-file -e OID^{commit} を実行し、ローカルだけに存在するオブジェクトストアを保全します。典型例は submodule コミットを push する前に superproject の gitlink を push した状態です。
git ls-remote --heads --tags URL は公開参照を示すだけで、到達不能な全オブジェクトではありません。一致がなくても削除の証明にはなりません。同じ資格情報で通常 fetch を試し、結果を保存します。
証拠に合う修復を選ぶ
URL が古ければ同じ OID のまま同期します。ローカルだけなら管理できるリモートへ push するか、fork を作って URL を明示変更します。ホストにあるのに CI が取得できない場合は権限を直します。
OID が回収不能、または依存を意図的に更新するときだけ、検証済み代替を checkout・test し、submodule パスを add して新しい gitlink を commit します。旧新 OID、URL、理由を残します。
--remote と再 clone を証明と混同しない
通常 update は記録 OID、--remote はリモートブランチ先端を使うため、成功しても別コミットかもしれません。ブランチ追従が設計方針のときだけ使います。
クリーン clone は修復後の再現性テストです。push --recurse-submodules=check/on-demand、URL 変更レビュー、正確な CI checkout で再発を防ぎます。
