Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

Git 子模組顯示「not our ref」?替換前先追查被記錄的提交

雜湊來自超級專案,不是你預期的分支。先保存 gitlink、核對實際 URL,並證明物件位於本機、可遠端取得或確實缺失,再決定同步、推送、fork 或更改固定提交。

原創圖:從超級專案 gitlink 經有效 URL 到遠端參照與物件。
原創示意圖:改變依賴前先追蹤記錄 OID 和有效 URL。 Watch at Ease

「not our ref」不是繼續加入 --force 的提示。它表示超級專案要求精確物件,而目前路徑沒有交付;改動前先保留這項請求。

安全順序是記錄、路由、物件、修復:找出 gitlink OID、確認有效 URL、驗證本機物件及遠端可達性,再選最小且明確的修復。

凍結失敗狀態並讀取 gitlink

不要先執行 rm -rf、deinit、--force 或 --remote。保存失敗的超級專案提交、完整錯誤、子模組路徑與本機工作。執行 git ls-tree HEAD -- path/to/submodule;mode 160000 條目記錄精確 OID。

OID 是第一項證據。官方資料模型稱它為 gitlink;.gitmodules 的分支名稱不能取代固定值。若 CI 顯示另一雜湊,要在實際失敗的超級專案提交上重查。

核對 Git 實際使用的 URL

比較 .git/config 與 .gitmodules 的 submodule URL。初始化會複製 URL,之後修改 .gitmodules 不會自動改寫舊 checkout;因此正確 OID 可能被送往錯誤倉庫。

若上游確實換址,執行 git submodule sync --recursive 並再檢查。sync 不會創造物件或授予存取權;記錄 URL 時不要帶入憑證。

區分本機存在、公開參照與可取得性

在子模組內以 git cat-file -e OID^{commit} 檢查物件,並保留只有原機器擁有的物件庫。常見失敗是超級專案先推了 gitlink,子模組提交卻尚未推送。

git ls-remote --heads --tags URL 只列出公開參照,不是全部不可達物件;沒有比對不能證明刪除。用相同身分執行一般 fetch 並保留結果。

依證據選擇修復

URL 過期就同步後重試同一 OID。本機有而遠端沒有,就先推到自有遠端,或建立授權 fork 並更新 URL。若主機有物件但 CI 取不到,修復權限,不要移動依賴。

只有 OID 無法恢復或專案刻意升級時,才測試替代提交並在超級專案提交新 gitlink。記錄舊新 OID、URL 與理由,讓審查者看見真正變更。

把 --remote 與重 clone 視為測試

普通 update 目標是記錄 OID;--remote 改用遠端分支尖端,可能成功卻更換提交。只有明確採用跟隨分支政策時才使用。

乾淨 clone 可驗證修復,但不能推送本機物件或修正舊路由。以 push --recurse-submodules=check/on-demand、URL 審查及精確 CI checkout 預防再發。

原創決策矩陣:核對 gitlink、URL 與物件後處理缺失提交。
原創示意圖:有證據後再選同步、推送、fork、權限修復或明確更改 gitlink。 Watch at Ease