Skip to content

perf(mcp): batch git spawns in the worktree transaction (~40→30 per write)#64

Merged
ABB65 merged 1 commit into
mainfrom
perf/transaction-batch-spawns
Jul 9, 2026
Merged

perf(mcp): batch git spawns in the worktree transaction (~40→30 per write)#64
ABB65 merged 1 commit into
mainfrom
perf/transaction-batch-spawns

Conversation

@ABB65

@ABB65 ABB65 commented Jul 9, 2026

Copy link
Copy Markdown
Member

What

Every local write (content_save, model_save, bulk, normalize apply) runs through createTransaction. A single 2-locale content_save spawned ~40 git subprocesses; profiling showed the git work is tiny (~0.5s) — the cost is spawn overhead. Two behavior-preserving batches cut it:

  • Commit identity via env — the worktree git instance carries GIT_AUTHOR_*/GIT_COMMITTER_* in its env instead of two git config user.* spawns per transaction (and per contentrain_merge). Git honors these for the sync merges and the feature-branch commit alike.
  • Batched selectiveSync — one git ls-tree over the changed paths replaces the per-file cat-file -e existence loop; one git checkout HEAD -- <files> replaces the per-file checkout loop (per-file fallback on error preserves precise skip accounting). Working-tree deletions are parallel fs removals.

Measured (single 2-locale content_save, profiled with GIT_TRACE)

before after
git spawns ~40 ~30
config 2 0
cat-file 5 0
checkout 7 3
wall-clock ~1600ms ~780ms

The selectiveSync win scales with file count, so bulk writes benefit the most.

Safety

No behavior change. Verified green: transaction.test.ts 15/15 (covers selectiveSync, auto-merge, mergeBranch), content + model + core content 53/53. oxlint + tsc clean. gc/maintenance auto-runs are intentionally left alone (they operate on the user's real object store).

🤖 Generated with Claude Code

Every local write goes through createTransaction, which spawned ~40 git
processes for a single content_save. Two behavior-preserving batches:

- Commit identity via env: the worktree git instance carries GIT_AUTHOR_*/
  GIT_COMMITTER_* instead of two `git config user.*` spawns per transaction
  (and per mergeBranch). Git honors these for the sync merges and the
  feature-branch commit alike.
- selectiveSync batching: one `git ls-tree` over the changed paths replaces
  the per-file `cat-file -e` existence loop; one `git checkout HEAD -- <files>`
  replaces the per-file checkout loop (per-file fallback on error preserves
  precise skip accounting). Deletions are parallel fs removals.

Measured: a 2-locale content_save drops from ~40 git spawns to ~30 (config
2->0, cat-file 5->0, checkout 7->3) and ~1600ms -> ~780ms. selectiveSync
scales with file count, so bulk writes benefit most. Behavior unchanged:
transaction 15/15, content+model 53/53 green.
@netlify

netlify Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploy Preview for contentrain-ai ready!

Name Link
🔨 Latest commit cfface5
🔍 Latest deploy log https://app.netlify.com/projects/contentrain-ai/deploys/6a4f6dfd0406f4000892e90b
😎 Deploy Preview https://deploy-preview-64--contentrain-ai.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ABB65
ABB65 merged commit 8ef59d6 into main Jul 9, 2026
6 checks passed
@ABB65
ABB65 deleted the perf/transaction-batch-spawns branch July 9, 2026 09:51
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant