what test coverage do we have now for replicate? · Entire
Review of Branch Changes
Here's my review of the branch changes. The diff adds a new replicate operation mode (source-authoritative relay-only) across the CLI, library API, planner, and a new internal/strategy/replicate package.
Overall
Solid, well-tested addition. The split between sync (reconciliation) and replicate (overwrite) is clean. New code is mostly additive, and there's good test coverage at planner, strategy, session, and CLI levels. A few things worth addressing before merge.
Issues / Nitpicks
Breaking JSON field rename —
execution.mode→execution.transfer_mode(pkg/gitsync/internalbridge/model.go:98,145)ExecutionSummary.Mode→TransferModeis a backwards-incompatible change to the stable embedding surface. If the stability promise matters forpkg/gitsync, consumers parsingexecution.modewill silently break. Either (a) keepmodeas a deprecated alias, (b) call this out in a CHANGELOG, or (c) confirm no external consumers yet.Dead/confusing branch in
defaultOperationMode(cmd/git-sync/main.go:412-424)func defaultOperationMode(name string, defaultMode gitsync.OperationMode) operationMode { if defaultMode != "" { return operationMode(defaultMode) } if name == "plan" { return operationMode(gitsync.ModeSync) } return operationMode(gitsync.ModeSync) }The
name == "plan"branch is identical to the fallback. Justreturn operationMode(gitsync.ModeSync). Also —planpassesdefaultMode=""intentionally, butsyncandreplicatealways pass a value, sonameis never needed. The helper can shrink toif defaultMode != "" { return … }; return operationMode(ModeSync).BuildReplicationPlansmutates its caller'smanagedmap (internal/planner/planner.go:174-185) The prune branch writes back into the passed-in map. Document the side effect. This is the kind of thing that becomes a bug in 6 months.dryRunargument inCanReplicateRelayis effectively dead (internal/planner/relay.go:122-124) The only call site isplanner.CanReplicateRelay(false, relayPlans, …)— hardcoded. Drop the parameter or call it from the dry-run path too.runReplicate allAbsentignores managed refs that aren't indesiredRefs(internal/syncer/syncer.go:~555-565)allAbsentonly scansdesiredRefs. If prune is on and the target has managed refs to delete while every desired ref is absent, we jump into the bootstrap path, which doesn't handle the deletes. A test forreplicate --pruneagainst an "empty except for orphaned managed ref" target is worth adding.SupportsReplicateRelaycalled twice (internal/syncer/syncer.go:~548and again insideCanReplicateRelayat~632) Minor redundancy —CanReplicateRelayalready callsSupportsReplicateRelay. Not wrong, just inefficient readability-wise.closeOncein the strategy is defensive but unused externally (internal/strategy/replicate/replicate.go:83-104) Ifgitproto.LimitPackReaderdoesn't wrap in a double-close-safe reader, a comment explaining whycloseOnceexists would save future readers.Usage string duplication (
cmd/git-sync/main.go:~410) The hugefmt.Sprintfwith every subcommand's flags is now ~doubled in length. Splitting it into per-subcommand helpers is advisable.Replicate relay vs.
--prunedelete flow Adds a test coveringreplicate --pruneend-to-end through thesyncer.
Nice Touches
- Test server now has a reusable
rewriteReceivePackAdvertisementhelper, cleaner than the previous inline capability mutation. operationModeStringdefaulting empty →"sync"in both bridges is consistent.replicatecorrectly rejects--forceat session construction with a clear "use sync instead" message.
Suggested Follow-Ups (not blockers)
- CHANGELOG entry for
TransferModerename. - Document the "replicate fails → retry with sync" semantics in
docs/architecture.md.
Test Coverage for Replicate
Planner (
internal/planner/planner_test.go) — 4 testsTestPlanReplicationRefOverwritesDivergenceTestPlanReplicationRefOverwritesTagRetargetTestCanReplicateRelayRejectsNoThinTestCanReplicateRelayRejectsInvalidPlanAction
Strategy (
internal/strategy/replicate/replicate_test.go) — 1 testTestExecuteReplicateRelaysUpdatesAndDeletesSeparately
Syncer integration (
internal/syncer/integration_test.go) — 2 testsTestRun_IntegrationReplicateRejectsNoThinTargetTestReplicateCanBootstrapRejectsPruneDeletes
Bridge (
pkg/gitsync/internalbridge/model_test.go) — 1 testTestFromSyncResultShapesStableSummary
Public client (
pkg/gitsync/client_test.go) — 1 testTestClientReplicateRejectsUnsupportedMode
CLI (
cmd/git-sync/main_test.go) — 1 testTestRun_Plan_ReplicateMode_JSONShowsReplicate
Gaps to Flag
- No happy-path replicate integration test. A green-path integrate test is needed to validate success scenarios.
- No test for
--forcerejection at session construction. - No test for
replicate --prunesuccessfully deleting an orphaned managed ref. - No test exercising tag replication end-to-end.
- CLI coverage only tests
plan --mode replicate, notreplicateitself.