Wire max/batch pack byte flags into sync and replicate · Entire
Wire max/batch pack byte flags into sync and replicate
6a219a1→main·
Soph·3mo ago·4 files·+54 added/-1 removed
Replicate against a fresh target for a repo the size of linux currently
fails with "decode report-status: invalid pkt-len found: short pkt-line 4"
because the receive-pack POST body hits a server limit (or times out)
and the target closes the connection before writing a report-status.
The fix is batching, which the bootstrap strategy already supports and
which replicate's bootstrap-fallback already plumbs to the strategy via
Config.BatchMaxPackBytes -- but the flags were only registered on the
bootstrap subcommand. Replicate and sync silently ignored them.
Changes:
- cmd/git-sync/main.go runSyncLike: register --max-pack-bytes and
--batch-max-pack-bytes. Update the usage string for sync, replicate, and plan accordingly. - pkg/gitsync/unstable/client.go buildSyncConfig: forward MaxPackBytes and BatchMaxPackBytes from AdvancedOptions to syncer.Config. The fields already existed on AdvancedOptions; only bootstrap was using them.
- internal/syncer/integration_test.go: add TestRun_Integration- ReplicateBootstrapBatchesWhenConfigured exercising a replicate call with BatchMaxPackBytes set, asserting it reaches the batched bootstrap path (batching=true, batch_count>=2) and leaves source and target heads matching. This guards the plumbing; regressing the forwarding would silently reintroduce the "flag has no effect" bug.
- CHANGELOG.md: document the added flags and the unstable buildSyncConfig forwarding.
Typical usage for a large initial replicate push:
git-sync replicate \
--batch-max-pack-bytes 268435456 \
--max-pack-bytes 10737418240 \
...
splits the push into ~256 MiB batches, each of which the receive-pack server processes and acknowledges before the next starts.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Sessions
08a1fb563aa3View transcript
Changes
4
MCHANGELOG.md+7
cmd/git-sync
- Mmain.go+3/-1
internal/syncer
- Mintegration_test.go+42
pkg/gitsync/unstable
- Mclient.go+2
16 unmodified lines
gitsync.Client.Replicateon the stable embedding surface.gitsync.OperationMode,gitsync.ModeSync,gitsync.ModeReplicate, andSyncPolicy.Modefor selecting the mode from library callers.--max-pack-bytesand--batch-max-pack-bytesflags onsync,replicate, andplan. Previously onlybootstrapexposed them, but replicate's bootstrap-fallback path internally honors both — without these flags, users couldn't split a huge initial replicate push into tractable receive-pack POSTs for size-limited targets. The unstable librarybuildSyncConfignow forwardsMaxPackBytesandBatchMaxPackBytesfromAdvancedOptionstosyncer.Config.
Changed (stable API, breaking)
MCHANGELOG.md+7
82 unmodified lines
1716 unmodified lines
func TestRun_IntegrationReplicateBootstrapBatchesWhenConfigured(t *testing.T) { // Large bootstrap-relay pushes can overwhelm targets with body-size // limits (e.g. go-git-based receive-pack on raft-backed storage). // Replicate falls back through the bootstrap strategy for empty targets, // and must honor BatchMaxPackBytes so callers can split a huge push // into tractable receive-pack POSTs. Without this plumbing the replicate // CLI flag would be silently ignored. sourceRepo, sourceFS := newSourceRepo(t) makeLargeCommits(t, sourceRepo, sourceFS, 20, 200_000)
targetRepo, err := git.Init(memory.NewStorage()) if err != nil { t.Fatalf("init target repo: %v", err) }
sourceServer := newSmartHTTPRepoServerV2(t, sourceRepo) targetServer := newSmartHTTPRepoServer(t, targetRepo) targetServer.receivePackThinCap = true defer sourceServer.Close() defer targetServer.Close()
result, err := Run(context.Background(), Config{ Source: Endpoint{URL: sourceServer.RepoURL()}, Target: Endpoint{URL: targetServer.RepoURL()}, Mode: modeReplicate, ProtocolMode: protocolModeAuto, BatchMaxPackBytes: 500_000, // force > 1 batch for the generated pack }) if err != nil { t.Fatalf("replicate with batched bootstrap failed: %v", err) } if result.OperationMode != modeReplicate { t.Fatalf("expected operation_mode=replicate, got %q", result.OperationMode) } if !result.Batching || result.BatchCount < 2 { t.Fatalf("expected batched bootstrap inside replicate, got batching=%t batch_count=%d result=%+v", result.Batching, result.BatchCount, result) }
assertHeadsMatch(t, sourceRepo, targetRepo, testBranch) }
func TestRun_IntegrationReplicateBootstrapsEmptyTarget(t *testing.T) { sourceRepo, sourceFS := newSourceRepo(t) makeCommits(t, sourceRepo, sourceFS, 2)