- Date: 2026-04-03
- Status: Accepted
- Sprint: 2 / Task 6, 10
Plan 設計 GitHubClient 透過 REST API 取得所有 commit 資料(list + per-commit detail)。Smoke test 實測 PetClinic(~1,023 commits)花 ~15 分鐘,其中 ~8 分鐘是 N+1 API 呼叫(GET /repos/{owner}/{repo}/commits/{sha} 逐筆取 file-level changes)。
分析後發現 CommitInfo 所需的全部欄位(sha、message、author、timestamp、parents、changed files with numstat)都可以從 local git log 取得。唯一 GitHub-only 的資料是 IssueInfo(issues 不存在於 git)。
新增 LocalGitClient(@Service),使用 ProcessBuilder 執行 git log --format="%x00%H%x00%an%x00%aI%x00%P%x00%B%x00" --numstat,以 NUL byte 作為欄位分隔符(git content 不含 NUL)。IngestionService 改為:
- Commits:
localGitClient.parseCommits(repoPath)— local git, 無網路 I/O - Issues:
gitHubClient.fetchIssues(owner, repo)— GitHub API(唯一剩餘的 API 依賴)
同時移除 CommitInfo.ChangedFile.patch 欄位(dead code,從未被任何 consumer 使用)。
- JGit — Java library,不需外部 process,但 numstat/diff-tree API 複雜且需新增依賴。Pipeline 已假設 local checkout 存在,git CLI 更簡單且普遍可用。
- GitHub GraphQL API — 可在 1-2 個 query 取得所有 commits + files,但仍受 rate limit 限制(5,000 pts/hr),且增加 API 複雜度。Local git 是 O(1) 沒有 rate limit。
- 保留 REST API + 跳過 merge commits detail — 只能省 ~30% calls,不解決根本問題。
- Pipeline 執行需要 git binary(開發和 CI/CD 環境普遍有)
- Commit data 不再受 GitHub API rate limit 影響(只有 issues 消耗 quota)
IngestionService.ingest()的owner/repo參數對 commits 無意義,僅用於 issuesGitHubClient.fetchCommits()保留但不再被 orchestrator 呼叫- PetClinic smoke test: 15m 8s → 6m 21s(commit fetching 從 ~8 min 降至 0.2 sec)