為什麼「把 Git 當資料庫」總是失敗:從 Cargo、Homebrew 到 CocoaPods 的共同教訓

本篇文章更新時間:2025/12/27
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


把 Git 當資料庫的誘惑與陷阱:讀《Package managers keep using git as a database, it never works out》後的三個深刻發現

編輯前言:這篇文章來自 Package managers keep using git as a database, it never works out,它整理了近十年主流套件管理工具的失敗教訓:只要把 Git 當成資料庫,最終都會撞牆。讀完後我覺得這根本是一份「工程師踩雷史年鑑」。

核心觀點 (Key Takeaways)

  • Git 的版本控管特性看似誘人,但只要用在資料查詢或索引,就會崩壞。
  • 愈大的套件生態,愈會被 Git 的歷史累積、樹狀結構與檔案系統限制拖垮。
  • 大多數成功轉彎的專案都逃向 HTTP、CDN、或真正的資料庫;不逃的(例如 vcpkg)依然深受其害。

深入解析

這篇原文列出六個套件管理器的實際案例。我讀的時候特別驚訝:這些團隊都不是新手,它們是 Cargo(Rust)、Homebrew(macOS)、CocoaPods(iOS)、Nixpkgs(NixOS)、vcpkg(Microsoft C++)、Go modules(Go 官方)。但即使如此,大家同樣掉入「Git-as-a-database」的陷阱,而且歷史幾乎完全重複。

原文一句話總結本質問題:「Git inherits filesystem limitations, and filesystems make terrible databases.」

Cargo:從全量 Git clone 到 HTTP sparse index

最經典的例子。最初所有 Cargo 客戶端都要 clone 整個 crates.io index。當套件多到幾十萬筆時,CI 甚至會被卡住在 “Resolving deltas …” 好幾分鐘。最後 Rust 團隊不得不設計 sparse HTTP protocol,讓客戶端只抓需要的 metadata。

Homebrew:GitHub 都受不了了

Homebrew 每次更新都會 forced unshallow,導致使用者動不動就下載 300MB、1GB 的 .git 資料夾。GitHub 直接跟他們說:拜託不要這樣。於是 Homebrew 4.0 大幅改用 JSON over HTTP。

CocoaPods:被 CPU rate limit 逼到放棄 Git

Specs repo 裡幾十萬個 podspec,clone 一次要幾分鐘。GitHub 甚至因為 shallow clone 的負擔而限流。CocoaPods 最後改用 CDN,大幅加速裝機流程,也節省近 1GB 空間。

Nixpkgs:即使使用 tarball 也逃不掉 GitHub 端的壓力

Nix 用的是 channel tarballs,不 clone repository。但 GitHub 還是會被巨大的 fork network 壓垮,因為 Nixpkgs repo 本身接近 83GB,pull request mergeability 檢查又會創建大量中繼 commit。

vcpkg:深度綁死 Git,反而無法逃生

vcpkg 的版本是用 git tree hash 定義,而不是 commit hash。這導致所有需要解析 baseline 的流程,都必須下載完整 commit history。CI 的 shallow clone 會直接造成錯誤,使用者只能乖乖 fetch-depth: 0。這是少數仍無計畫脫離 Git 的專案。

Go modules:導入 GOPROXY 後從 18 分鐘降到 12 秒

go get 原本要 clone 整個 repo 才能讀 go.mod。Grab 的工程師實測:從 18 分鐘降至 12 秒。後來 Go 官方直接推 GOPROXY+sumdb,把版本管理與安全性問題一起解決。

筆者心得與啟發

看完這整篇,我最大的感觸是:只要一開始把 Git 當成可查詢式的資料庫,你後面註定要重寫一次真正的資料庫。

Git 的強項在於:

  • 分散式協作
  • 版本與歷史
  • branch / merge

但套件管理器真正需要的是:

  • 快速 metadata 查詢
  • 稀疏取用(sparse)
  • CDN 快速分發
  • 明確 schema 與唯一性約束

這兩種需求根本不是同一類工具能滿足的。

文章最後一句話我非常認同:

「You’ve built a worse version of what databases already provide.」

如果有朋友下一次說:我們乾脆用 Git 當 registry、或者拿 Git 當 key-value store,看似省事,我會提醒他:Cargo、Homebrew、CocoaPods、Go 模組團隊都試過,結果都花了更多時間逃出來。

在今天的軟體生態中,正確的方向往往是:Git 保持原本的角色,資料庫與 CDN 做它們擅長的事。


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon