# Narrow strategy dependencies behind source interfaces

`b074cde`→[main](/content/gh/entireio/git-sync/commits/main/index.html)·

Soph·3mo ago·5 files·+37 added/-11 removed

## Sessions

e8501c11ba8aView transcript

[?\
Can you take a look at the go code (wasm) in /Users/soph/Work/entire/devenv/entire-io-worktree1 based a bit on that I wonder if something like this can be build:Codex·GPT-5.4·1 step](/content/gh/entireio/git-sync/session/019d6d29-8cf7-7fe3-adc9-8c3e4d9d5603#timeline-e8501c11ba8a/index.html)

## Changes

5

- docs

- Mrewrite-issue-list.md+3/-1

- internal

- gitproto

- Mfetch.go+14

- strategy

- bootstrap

- Mbootstrap.go+13/-7

- incremental

- Mincremental.go+4/-1

- materialized

- Mmaterialized.go+3/-2

```
283 unmodified lines

284
285
286
287
287
288
289
290
291
292

283 unmodified lines

- Introduce explicit session/context objects with narrow responsibilities.

Current rewrite note:
- Major strategy and protocol concerns were extracted, but some helpers still carry broad parameter structs and concrete dependencies rather than narrower interfaces.
- Major strategy and protocol concerns were extracted.
- The strategy packages now depend on narrower source-side interfaces instead of the full concrete `gitproto.RefService`.
- Some helpers still carry broad parameter structs, and target-side/push abstractions are still concrete, so this remains partial.

## Performance And Scalability
```
Mdocs/rewrite-issue-list.md+3/-1
```

25 unmodified lines

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

25 unmodified lines

IsTag      bool
}

func (s *RefService) ProtocolName() string {
	if s == nil {
		return ""
	}
	return s.Protocol
}

func (s *RefService) SupportsFetchFeature(feature string) bool {
	if s == nil || s.Protocol != "v2" || s.V2Caps == nil {
		return false
	}
	return s.V2Caps.FetchSupports(feature)
}

// FetchToStore fetches objects from source into the given store, using the
// appropriate protocol version.
func (s *RefService) FetchToStore(
```

Minternal/gitproto/fetch.go+14
```

18 unmodified lines

19
20
21
22
23
24
25
15 unmodified lines

41
42
43
43
44
45
46
47
48
49
50
51
52
81 unmodified lines

134
135
136
131
137
138
139
134
140
141
142
143
294 unmodified lines

438
439
440
435
441
442
443
438
444
445
446
447
63 unmodified lines

511
512
513
508
514
515
516
511
517
518
519
520

18 unmodified lines

"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/protocol/packp"
	"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
	"github.com/go-git/go-git/v5/plumbing/storer"
	"github.com/go-git/go-git/v5/storage/memory"

"github.com/soph/git-sync/internal/convert"
15 unmodified lines

type Params struct {
	SourceConn    *gitproto.Conn
	TargetConn    *gitproto.Conn
	SourceService *gitproto.RefService
	SourceService interface {
		FetchPack(context.Context, *gitproto.Conn, map[plumbing.ReferenceName]gitproto.DesiredRef, map[plumbing.ReferenceName]plumbing.Hash) (io.ReadCloser, error)
		FetchCommitGraph(context.Context, storer.Storer, *gitproto.Conn, gitproto.DesiredRef) error
		ProtocolName() string
		SupportsFetchFeature(string) bool
	}
	TargetAdv     *packp.AdvRefs
	DesiredRefs   map[plumbing.ReferenceName]planner.DesiredRef
	TargetRefs    map[plumbing.ReferenceName]plumbing.Hash
81 unmodified lines

plans []planner.BranchPlan,
	result Result,
) (Result, error) {
	if p.SourceService.Protocol != "v2" {
	if p.SourceService.ProtocolName() != "v2" {
		return result, fmt.Errorf("bootstrap batching currently requires protocol v2")
	}
	if p.SourceService.V2Caps == nil || !p.SourceService.V2Caps.FetchSupports("filter") {
	if !p.SourceService.SupportsFetchFeature("filter") {
		return result, fmt.Errorf("bootstrap batching requires source fetch filter support")
	}

294 unmodified lines

if p.BatchMaxPack > 0 || p.SourceConn == nil || p.SourceConn.Endpoint == nil {
		return 0, false
	}
	if p.SourceService == nil || p.SourceService.Protocol != "v2" {
	if p.SourceService == nil || p.SourceService.ProtocolName() != "v2" {
		return 0, false
	}
	if p.SourceService.V2Caps == nil || !p.SourceService.V2Caps.FetchSupports("filter") {
	if !p.SourceService.SupportsFetchFeature("filter") {
		return 0, false
	}
	repoSizeKB, ok := lookupGitHubRepoSizeKB(ctx, p.SourceConn)
63 unmodified lines

if p.BatchMaxPack > 0 || !isTargetBodyLimitError(err) {
		return 0, false
	}
	if p.SourceService == nil || p.SourceService.Protocol != "v2" {
	if p.SourceService == nil || p.SourceService.ProtocolName() != "v2" {
		return 0, false
	}
	if p.SourceService.V2Caps == nil || !p.SourceService.V2Caps.FetchSupports("filter") {
	if !p.SourceService.SupportsFetchFeature("filter") {
		return 0, false
	}
	limit := int64(defaultAutoBatchMaxPackBytes)
```

Minternal/strategy/bootstrap/bootstrap.go+13/-7

```

5 unmodified lines

6
7
8
9
10
11
12
7 unmodified lines

20
21
22
22
23
24
25
26
27
28

5 unmodified lines

import (
	"context"
	"fmt"
	"io"

"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/protocol/packp"
7 unmodified lines

type Params struct {
	SourceConn    *gitproto.Conn
	TargetConn    *gitproto.Conn
	SourceService *gitproto.RefService
	SourceService interface {
		FetchPack(context.Context, *gitproto.Conn, map[plumbing.ReferenceName]gitproto.DesiredRef, map[plumbing.ReferenceName]plumbing.Hash) (io.ReadCloser, error)
	}
	TargetAdv     *packp.AdvRefs
	DesiredRefs   map[plumbing.ReferenceName]planner.DesiredRef
	TargetRefs    map[plumbing.ReferenceName]plumbing.Hash
```

Minternal/strategy/incremental/incremental.go+4/-1

```

20 unmodified lines

21
22
23
24
24
25
26
27
28
29
67 unmodified lines

97
98
99
98

20 unmodified lines

type Params struct {
	Store         storer.Storer
	SourceConn    *gitproto.Conn
	SourceService *gitproto.RefService
	SourceService interface {
		FetchToStore(context.Context, storer.Storer, *gitproto.Conn, map[plumbing.ReferenceName]gitproto.DesiredRef, map[plumbing.ReferenceName]plumbing.Hash) error
	}
	TargetConn    *gitproto.Conn
	TargetAdv     *packp.AdvRefs
	DesiredRefs   map[plumbing.ReferenceName]planner.DesiredRef
67 unmodified lines

}
	return nil
}
```

Minternal/strategy/materialized/materialized.go+3/-2

```
