單體或多倉 iOS/macOS 專案在遠端 Mac CI上常同時碰到 Git SubmoduleGit LFS:網路 RTT 高、指標檔與大檔交錯、子模組 URL 與鑑權分裂。本文拆解瓶頸、給並行拉取與鎖定策略對照表快取與增量 fetch 參數清單、鏡像/直連回退示例閾值與FAQ。延伸閱讀:依賴拉取穩定性 FAQGit 鏡像與代理對比;更多文章見 技術部落格列表。節點與方案可從 首頁購買頁免登入瀏覽。

Submodule 與 LFS 在 CI 中的瓶頸拆解

子模組把「多個遠端」串成樹狀拉取:任一層級逾時都會讓整段 job 失敗。Git LFS 則在 smudge 階段額外打批次請求,與 git fetch 競爭頻寬。跨境 遠端 Mac CI 上常見組合痛點包括:未設定 --jobs 導致子模組序列化、LFS 預設並行不足、以及快取鍵過粗使 LFS 物件無法命中。

建議初始化順序(可寫進腳本)
  • 1. Checkout 父倉固定 SHA(避免浮動分支上子模組指標漂移)。
  • 2. git submodule sync --recursive 對齊 .gitmodules 與實際 URL(尤其剛切換 HTTPS/SSH 時)。
  • 3. git submodule update --init --recursive --jobs 44~8 視 CPU/頻寬調整)。
  • 4. 若 clone 時設 GIT_LFS_SKIP_SMUDGE=1:在父倉與各子模組目錄執行 git lfs pull(必要時加 --include 縮小範圍)。
  • 5. 驗證 git lfs ls-files 無 missing,再進入 Xcode/SwiftPM 建置。

並行拉取與鎖檔策略對照表

「能不能並行」取決於鎖定的是提交還是浮動分支,以及是否允許 LFS 延後下載。

策略並行拉取鎖檔/一致性適用情境
子模組固定 commit + --jobs N高(多遠端同時)以父倉記錄的 submodule SHA 為準正式 release/App Store 建置
子模組跟蹤分支(remote 未鎖)中(仍受遠端節流影響)每日可能漂移,需額外稽核內部整合分支(不建議上線)
GIT_LFS_SKIP_SMUDGE=1 + 批次 lfs pull高(與 submodule 分階段).lfsconfig/遠端 URL 綁定大型素材、多層子模組
單執行緒預設 smudge行為直觀但耗時本機除錯或小倉
# 並行子模組 + LFS 並行示例(CI 環境變數或全域設定)
export GIT_LFS_SKIP_SMUDGE=1
git config --global submodule.fetchJobs 8
git config --global lfs.concurrenttransfers 16
git config --global lfs.activitytimeout 600
git submodule update --init --recursive --jobs 8
git lfs pull

lfs.concurrenttransfers 常設 8~32(視託管方節流);頻寬極窄時可降到 4 換取較少連線競爭。若需限制單連線速率,可在代理層做 QoS,或使用 lfs.basictransfersonly true 強制簡單 HTTP(部分企業防火牆較友善)。

快取與增量 fetch 參數清單

目錄與快取鍵設計(示例)
  • LFS 物件:掛載 ~/.git/lfs/objects(或 $HOME/.cache/git-lfs,依版本);鍵建議含 hashFiles('.gitattributes') + hashFiles('**/.lfsconfig') + 父倉 GITHUB_SHA 前綴。
  • Git 物件:使用 git clone --filter=blob:none 或維護裸鏡像目錄;鍵含 .gitmodules 與子模組指標合併雜湊。
  • 增量 fetch:git fetch --depth=50 origin $SHA;子模組內同樣 shallow,避免拉全歷史。
  • HTTP 緩衝:git config --global http.postBuffer 524288000http.lowSpeedLimithttp.lowSpeedTime 可依頻寬調整以防假死。

快取鍵過細會降低命中率,過粗會帶入過期 LFS 指標;實務上常以「.gitmodules + 子模組 commit 合併雜湊」為一級鍵,二級再以「當次 pipeline 觸發提交」區分。

失敗重試與逾時閾值

  • Git fetch/clone:包一層指數退避,例如 3~5 次,基底 5s、上限 120s;對 RPC failedempty pack 重試有效。
  • LFS batch:lfs.activitytimeout 建議 300~900 秒;跨洋鏈路可與 lfs.dialtimeout 一併拉高。
  • 429/402:對配額與節流錯誤應縮短重試或改走備援儲存,避免打滿 API 配額。

遠端 Mac 網路與磁碟水位檢查

在掛載快取前,先確認節點不會因磁碟滿導致 LFS 寫入半套失敗。建議於 pre-job 腳本檢查:可用空間 ≥ 預估Git + LFS 快取 + 建置產物總和的 1.5 倍;網路可抽樣 curl -o /dev/null -s -w '%{time_total}\n' 對託管 API 與 LFS 端點量測,若連續樣本 RTT 或錯誤率超過內部 SLO,觸發下一節的鏡像/直連切換。

鏡像與直連回退(示例閾值)
  • 同一 job 內對鏡像域名連續 3 次 5xx 或 TLS 握手失敗 → 下一輪改 git remote set-url 為直連上游。
  • 建立連線時間 > 2000 ms(可調)且持續兩個 job → 暫停鏡像,僅對該倉庫走官方端點。
  • 恢復條件:直連連續成功 N 次(如 10)且平均 RTT 低於閾值,再切回鏡像以省頻寬。

FAQ:鑑權失敗與配額

子模組或 LFS 出現 401/403,CI 已設 TOKEN 仍失敗?

檢查子模組 URL 是否與父倉相同鑑權方式(全 HTTPS + PAT 或全 SSH + deploy key)。git submodule sync 後重跑;SSH 需在遠端 Mac上配置 ssh-agentknown_hosts。細部逾時參數可再對照站內 Git 拉取穩定性 FAQ

LFS 配額或組織流量用盡會怎樣?

常見為 402/429 或帶配額文案的錯誤。應啟用/升級託管儲存、將冷資料改工件庫或自建 LFS,並在 CI 對該錯誤停止盲目重試。

並行開太高是否反而更慢?

會。頻寬固定時過多 TCP 連線會造成重傳與節流;請以實測在 4~16 間找甜蜜點,並與 submodule.fetchJobs 一併調整。

小結與下一步

2026 年在遠端 Mac CI同時用好 Git SubmoduleGit LFS:先用固定提交 + 有序初始化穩定指標,再以並行參數快取鍵縮短冷啟動,用逾時與退避吸收跨境波動,並用鏡像/直連閾值避免單點拖垮流水線。若你需要專用 Apple Silicon 節點跑 iOS/macOS 建置,歡迎從 定價購買頁選擇套餐,或到 說明中心查閱存取與網路建議;亦可在 技術部落格繼續閱讀 Git/依賴加速專題。

遠端 Mac 建置節點

讓 Submodule 與 LFS 拉取更穩、更快

租用 MacPull 遠端 Mac,將本文參數與快取策略落在專用環境;免登入即可瀏覽定價、購買與說明。