Theme / v0.9.56

Graphify

Codebase 知識圖譜

實戰範例

實戰範例 010:增量重建工作流(update / watch / hook)

日常開發維持圖譜新鮮:graphify update 增量重建、watch 檔案監聽、hook install + git merge driver 解決 graph.json 衝突

背景

範例 001 跟 009 都只跑「一次性 build」:全量 graphify extract . 之後就放著。但真實開發是持續的:

  • 你改了一個 function,圖譜過時了
  • 同事 merge 一個 PR,你本地的 graph.json 跟遠端衝突
  • 團隊共用一份 commit 進 repo 的 graphify-out/,但每次 pull 都要重建

graphify 的增量重建三招解決這些日常摩擦:update(手動增量)、watch(自動監聽)、hook install + git merge driver(融入 git 流程)。這個範例帶你把三招接起來,讓圖譜在持續開發中一直保持新鮮,不必每次都全量重建。

⚠️ 與範例 003 差異:003 談的是「團隊共享 + PR review」,只順帶提到 hook install。本範例聚焦在單人/團隊日常的增量維護流程,涵蓋 watch 與 merge driver 的完整設定。


適用情境

  • 中大型 codebase,全量 build 要 30 秒以上,不想每次改一行就重跑
  • 團隊把 graphify-out/ commit 進 repo,需要處理 merge 衝突
  • 想讓圖譜在背景自動同步,不佔用開發節奏
  • 升級到 v0.9.41,想用新的「縮小圖譜保護」與 POSIX 路徑

增量重建的三個層次

工具 觸發時機 適合場景
graphify update 手動按需 改了幾個檔,想同步圖譜
graphify watch 檔案變動自動觸發 開發中背景跑,持續同步
graphify hook install git commit/merge 觸發 團隊流程,確保 commit 進 repo 的圖譜永遠最新

三者不互斥,可以疊加:個人用 watch,團隊用 hook,臨時用 update


完整流程

步驟 1:建立 baseline 圖譜

先跑一次全量 build 作為 baseline:

cd ~/my-project

uv tool install graphifyy
graphify install --project
graphify extract . --code-only

確認 graphify-out/graph.json 產生。

步驟 2:改幾個檔,手動增量更新

模擬日常開發:加一個新 function、改一個既有 function。

# 加新檔
cat > notifier.py << 'EOF'
def notify(user, message):
    print(f"[notify] {user}: {message}")
EOF

# 改既有檔
echo "    # v2: added logging" >> auth.py

現在跑增量更新,只重抽變動的檔:

graphify update

update 會:

  1. 比對檔案 mtime/hash,找出變動的檔
  2. 只對變動檔重跑 AST 解析
  3. 把新節點/邊 merge 進既有 graph.json,刪掉消失的節點

輸出會告訴你「重新萃取 N 個檔,新增 M 個節點」。比全量 extract 快很多。

💡 v0.9.41 重點:graphify update 不會以「extractor 失敗造成的縮小圖譜」覆寫既有資料。如果你看到 update 被拒絕,先檢查 extractor 是否報錯(例如某個檔 parse 失敗),修正後再重跑。

步驟 3:背景 watch,檔案變動自動重建

不想每次手動 update?開一個終端跑 watch:

graphify watch

watch 會監聽專案目錄,檔案一變動就觸發增量重建。開發時讓它背景跑,你只管寫 code,圖譜自動同步。

[watch] detected change: notifier.py
[watch] incremental update... done (1 file, 0.4s)
[watch] detected change: auth.py
[watch] incremental update... done (1 file, 0.3s)

watch 適合個人本地開發。要停就 Ctrl+C

步驟 4:裝 git hook,把重建融入團隊流程

團隊若把 graphify-out/ commit 進 repo(範例 003 的做法),每個人在 commit/merge 前都要確保圖譜是新的。手動容易忘,裝 hook 自動化:

graphify hook install

graphify hook install 一次寫入三樣東西:

  1. post-commit hook — 每次 git commit 後自動執行 AST-only 重建(零 API 成本)
  2. post-checkout hook — 切 branch 時重建圖譜,確保助理看到的是當前 branch 的 code
  3. graph.json 的 git merge driver(merge=graphify) — 兩人平行 commit graphify-out/ 時自動 union-merged,永不出現 conflict marker

驗證 hook 有裝上:

graphify hook status

輸出類似:

Git hooks (graphify v0.9.41):
  post-commit    installed  → runs AST-only rebuild after commit
  post-checkout  installed  → runs AST-only rebuild after branch switch
  merge driver   installed  → graphify-out/graph.json union-merged via merge=graphify

步驟 5:git pull 不卡 graph.json 衝突

graph.json 是機器產生的 JSON,兩人同時 commit 各自重建的版本,merge 時本來必定衝突。手動解 JSON 衝突是惡夢。

但步驟 4 的 graphify hook install 已經順手把 merge driver 寫好了:graphify-out/graph.json 會套用 merge=graphify,當 git pull / git merge 遇到 graph.json 衝突時,git 不再寫 <<<<<<< 標記,而是交給 driver 把兩邊的圖譜智慧合併:

  1. 讀兩邊的節點 / 邊
  2. 取聯集(node id 相同就合併屬性)
  3. 寫回當前檔

換句話說:步驟 4 一條指令就把 hook 與 merge driver 都搞定,不需要另外手動編輯 .gitattributesgit config

步驟 6:驗證整套流程

模擬一個完整循環:

# 1. 改檔
echo "def new_func(): pass" >> utils.py

# 2. commit(觸發 post-commit hook → AST-only 重建)
git add -A
git commit -m "feat: add new_func"

# 3. hook 輸出
# [graphify post-commit] rebuilding AST graph... 1 file changed, 1 node added

# 4. push
git push origin main

同事 pull 時,因為步驟 4 已裝好 merge driver,graph.json 自動 union-merged:

git pull origin main
# graphify-out/graph.json: merge=graphify driver applied, union-merged cleanly

圖譜永遠是新的,且不會卡在 merge 衝突。


真實輸出範例

$ graphify update
Scanning for changed files... 3 found
Re-extracting: notifier.py, auth.py, utils.py
Merging into existing graph...
  + 2 nodes added (notify, new_func)
  + 1 edge added (login --calls--> notify)
  ~ 0 nodes updated
  - 0 nodes removed
Done in 1.2s

$ graphify watch
[watch] v0.9.41 watching . (recursive, ignore .git/, graphify-out/)
[watch] press Ctrl+C to stop
[watch] 14:23:01 changed: services/billing.py → rebuilt (1 file, 0.5s)
[watch] 14:23:45 changed: services/billing.py, services/auth.py → rebuilt (2 files, 0.7s)

對比傳統做法

情境 沒有增量重建 graphify 增量重建
改一行 code 想同步 全量 extract .,30 秒起跳 update 只跑變動檔,< 1 秒
開發中圖譜同步 手動重跑,容易懶得做 watch 背景跑,零摩擦
兩人 commit 圖譜衝突 手動解 JSON,易出錯 merge=graphify driver 自動合併
忘了重建就 commit commit 進 repo 的圖譜過時 hook install 在每次 commit 後自動重建,下個 commit 一定帶新圖譜

失敗處理

情境 排查
update 報「graph shrunk, refusing to overwrite」 v0.9.41 的保護機制:本次萃取結果比既有圖譜小很多。先檢查 extractor 是否報錯(例如某檔 parse 失敗、.graphifyignore 範圍設錯),修正後重跑
watch 吃 CPU 過高 大型 repo 的檔案監聽成本高;可限定監聽子目錄(例如 graphify watch ./src 而非整個 repo),縮小監聽範圍
hook status 顯示未安裝 重跑 graphify hook install;若 .git/hooks/ 權限不對,chmod +x .git/hooks/post-commit
merge driver 沒生效 確認 graphify hook install 跑過(它會自動寫入 merge=graphify driver);若 hook status 顯示 driver 缺失,重跑一次 install 即可
升級 v0.9.41 後 cache 失效 此版本要求 semantic 節點含 rationale,舊 cache 會自動重新萃取,屬正常現象;先確認語意後端額度充足

內部連結


下一步

  1. PR 審查 + 團隊共享 graphify-out(團隊層級的共享與 CI)
  2. 大型 monorepo 重購(圖譜維持新鮮後,做重購分析)

關鍵學習點

  • update 是手動增量、watch 是自動監聽、hook install 是融入 git 流程;三個不互斥,依場景疊加。
  • v0.9.41 的 update 會拒絕以縮小圖譜覆寫,遇到拒絕先修 extractor,別強制覆蓋。
  • graphify-out/ commit 進 repo 的團隊,一定要設 merge=graphify driver,否則 graph.json 衝突會反覆發生。
  • hook install 是團隊紀律的自動化:把「commit 後順手更新圖譜」從口頭約定變成每次 commit / checkout 自動執行。