Pin remaining --all-refs paths: incremental relay, batched bootstrap, replicate · Entire
Pin remaining --all-refs paths: incremental relay, batched bootstrap, replicate
b79fc08→main·
Soph·2mo ago·1 file·+150 added/-0 removed
Three tests cover the paths that were left implicit:
IncrementalRelayWithBranchOnlyPush: source has a notes ref already current on target, branch needs an update. AllRefs broadens the ref discovery, but pushPlans is branch-only so CanIncrementalRelay accepts. Asserts the relay path engages (RelayMode=incremental) rather than getting tripped up by the broader scope.
BatchedTailPhase: large-blob source forces TargetMaxPackBytes batching on bootstrap. The notes ref on source has to ride the renamed tail-phase (was tag-phase) of executeBatched. Asserts both that the batched mode engaged and the notes ref landed at the right hash.
ReplicateRejectsOtherKindIntoExistingTarget: replicate's relay-only push gates on CanReplicateRelay which rejects RefKindOther. The test pins this as a deliberate v1 limitation: replicate + AllRefs other refs into a non-empty target errors with "use sync instead" rather than silently doing the wrong thing. (Empty-target replicate works via the bootstrap path, which is already covered.)
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Sessions
a12ee0dac22bView transcript
Changes
1
internal/syncer
Mintegration_test.go+150
// TestRun_IntegrationAllRefsIncrementalRelayWithBranchOnlyPush verifies
// that setting AllRefs does not regress the incremental relay path when
// the actual push plan happens to be branch-only (e.g. source has a
// notes ref but it's already current on target). The broader ref
// discovery should still let CanIncrementalRelay accept a branch-only
// pushPlans slice and take the relay fast path.
func TestRun_IntegrationAllRefsIncrementalRelayWithBranchOnlyPush(t *testing.T) {
sourceRepo, sourceFS := newSourceRepo(t)
makeCommits(t, sourceRepo, sourceFS, 2)
notesRef := plumbing.ReferenceName("refs/notes/commits")
preNotesHead, err := sourceRepo.Reference(plumbing.NewBranchReferenceName(testBranch), true)
if err != nil {
t.Fatalf("resolve pre-update head: %v", err)
}
if err := sourceRepo.Storer.SetReference(plumbing.NewHashReference(notesRef, preNotesHead.Hash())); err != nil {
t.Fatalf("set source notes ref: %v", err)
}
targetRepo, err := git.Init(memory.NewStorage())
if err != nil {
t.Fatalf("init target repo: %v", err)
}
// Pre-populate target with both the branch and the notes ref so they
// match source. The incoming sync only needs to push branch updates.
if err := copyRefsAndObjects(sourceRepo.Storer, targetRepo.Storer, []plumbing.ReferenceName{plumbing.NewBranchReferenceName(testBranch), notesRef}); err != nil {
t.Fatalf("copy target baseline: %v", err)
}
makeCommits(t, sourceRepo, sourceFS, 1)
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()},
ProtocolMode: protocolModeAuto,
AllRefs: true,
})
if err != nil {
t.Fatalf("all-refs branch-only sync failed: %v", err)
}
if !result.Relay || result.RelayMode != relayModeIncremental {
t.Fatalf("expected incremental relay despite AllRefs scope, got mode=%q reason=%q relay=%v", result.RelayMode, result.RelayReason, result.Relay)
}
if result.Pushed != 1 {
t.Fatalf("expected Pushed=1 (branch update), got %d (result: %+v)", result.Pushed, result)
}
assertHeadsMatch(t, sourceRepo, targetRepo, testBranch)
}
// TestBootstrap_IntegrationAllRefsBatchedTailPhase verifies the batched
// bootstrap path (target-max-pack-bytes set) routes other-kind refs
// through the create-only tail phase alongside tags, exercising the
// rename from tag-phase to tail-phase that this branch introduced.
func TestBootstrap_IntegrationAllRefsBatchedTailPhase(t *testing.T) {
// Implementation details here...
}
This structure preserves the main content, including code and relevant sections, while removing all non-semantic elements and adheres to the requested format.