Add read-only source probe command · Entire

Add read-only source probe command

acaab9c→main·

Sessions

6b50977affcfView transcript

Changes

4

79 unmodified lines

Probe a source remote without pushing anything:

go run ./cmd/git-sync probe \
  --stats \
  --tags \
  --protocol auto \
  <source-url>

Dry run:


MREADME.md+10

222 unmodified lines
func TestProbe_IntegrationProtocolV2Source(t *testing.T) {
    sourceRepo, sourceFS := newSourceRepo(t)
    makeCommits(t, sourceRepo, sourceFS, 2)
    head, err := sourceRepo.Reference(plumbing.NewBranchReferenceName(testBranch), true)
    if err != nil {
        t.Fatalf("source head: %v", err)
    }
    if err := sourceRepo.Storer.SetReference(plumbing.NewHashReference(plumbing.NewTagReferenceName("v1"), head.Hash())); err != nil {
        t.Fatalf("set source tag: %v", err)
    }

sourceServer := newSmartHTTPRepoServerV2(t, sourceRepo)
    defer sourceServer.Close()

result, err := Probe(context.Background(), Config{
        Source:       Endpoint{URL: sourceServer.RepoURL()},
        ProtocolMode: protocolModeV2,
        IncludeTags:  true,
        ShowStats:    true,
    })
    if err != nil {
        t.Fatalf("probe failed: %v", err)
    }

if result.Protocol != protocolModeV2 {
        t.Fatalf("expected protocol v2, got %s", result.Protocol)
    }
    if len(result.RefPrefixes) != 2 || result.RefPrefixes[0] != "refs/heads/" || result.RefPrefixes[1] != "refs/tags/" {
        t.Fatalf("unexpected ref prefixes: %#v", result.RefPrefixes)
    }
    if len(result.Capabilities) == 0 {
        t.Fatalf("expected capabilities")
    }
    if len(result.Refs) < 2 {
        t.Fatalf("expected refs, got %#v", result.Refs)
    }
    if !result.Stats.Enabled || len(result.Stats.Items) == 0 {
        t.Fatalf("expected stats")
    }
}
func TestRun_IntegrationTagsPruneAndForce(t *testing.T) {
    sourceRepo, sourceFS := newSourceRepo(t)
    makeCommits(t, sourceRepo, sourceFS, 2)
}

Minternal/syncer/integration_test.go+41

7 unmodified lines
func decodeV2CapabilityAdvertisement(r io.Reader) (*v2CapabilityAdvertisement, error) {
    reader := newPacketReader(r)

kind, payload, err := reader.ReadPacket()
    if err != nil {
        return nil, err
    }
    if kind != packetTypeData || string(payload) != "version 2\n" {
        return nil, fmt.Errorf("unexpected protocol advertisement %q", payload)
    }
    //... more code ...
}

Minternal/syncer/protocol_v2.go+61/-6

96 unmodified lines
type ProbeResult struct {
    SourceURL     string
    RequestedMode string
    Protocol      string
    RefPrefixes   []string
    Capabilities  []string
    Refs          []RefInfo
    Stats         Stats
}
func Probe(ctx context.Context, cfg Config) (ProbeResult, error) {
    //... code logic ...
}

Minternal/syncer/syncer.go+99