Commit fb25a63
authored
π€ perf: replace git bundle with native git push for SSH runtime (#3137)
## Summary
Replaces the git-bundle-create β SSH-pipe β git-fetch-bundle workflow
with a single `git push` over SSH. Git's native smart protocol
negotiates which objects the remote already has, transferring only the
delta. This makes subsequent workspace creations near-instant on slow
connections instead of re-uploading the entire repository history every
time.
## Background
When the SSH runtime creates a new workspace, it syncs the local project
to the remote. Previously, this always created a **full git bundle**
(`git bundle create - --branches --tags`) containing the entire
reachable history, piped it byte-by-byte over SSH to a temp file, then
imported it with `git fetch`. Even if only one commit changed since the
last sync, the full repo was re-uploaded.
The remote already has:
- A bare git repo (`.mux-base.git`) that can receive pushes natively
- Git installed (the code already runs git commands on it)
- SSH connectivity (that's how we connect)
So the bundle approach was reimplementing what `git push` does natively
with its pack negotiation protocol.
## Implementation
The core change is straightforward β `syncProjectToRemote()` now runs:
```
git -C <project> push --force --atomic <host>:<base-repo-path> \
+refs/heads/*:refs/mux-bundle/* \
+refs/tags/*:refs/tags/*
```
with `GIT_SSH_COMMAND` set to mirror the runtime's SSH config (port,
identity file, ControlPath multiplexing, host key policy). This
preserves the existing `refs/mux-bundle/*` staging namespace and tag
handling.
**New:** `buildGitSshCommand()` β constructs the SSH command string from
the runtime's config, matching OpenSSHTransport's `buildSSHArgs()`
settings.
**Removed (163 lines):**
- `transferBundleToRemote()` β bundle creation + SSH pipe upload
- `pipeReadableToWebWritable()` β streaming helper only used for bundles
- `waitForProcessExit()` β only used by bundle upload
- Temp file management and cleanup
- `spawn`/`ChildProcess` imports
**Preserved:** `shouldReuseCurrentBundleTrunk()` β the skip-if-unchanged
optimization that avoids sync entirely when all refs already match. This
still works because `git push` populates the same `refs/mux-bundle/*`
namespace.
## Risks
**Low.** The refspec mapping is identical
(`+refs/heads/*:refs/mux-bundle/*`, `+refs/tags/*:refs/tags/*`), so the
remote base repo ends up in the same state. The
`shouldReuseCurrentBundleTrunk` skip logic, worktree creation, and all
downstream code are unchanged.
`--atomic` ensures that if any ref update fails, none are applied β
preventing partial sync states. `--force` ensures we always sync to the
local state even after history rewrites.
---
_Generated with `mux` β’ Model: `anthropic:claude-opus-4-6` β’ Thinking:
`xhigh` β’ Cost: `$6.97`_
<!-- mux-attribution: model=anthropic:claude-opus-4-6 thinking=xhigh
costs=6.97 -->1 parent 60a2570 commit fb25a63
1 file changed
Lines changed: 323 additions & 83 deletions
0 commit comments