# Route strategies through target push abstractions

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

## Sessions

00b8437a4e4aView transcript

## Changes

8

- docs
  - Mrewrite-issue-list.md+2/-1

- internal
  - gitproto
    - Mpush.go+27
  - strategy
    - bootstrap
      - Mbootstrap.go+30/-24
      - Mbootstrap_test.go+94
    - incremental
      - Mincremental.go+19/-11
      - Mincremental_test.go+143/-4
    - materialized
      - Mmaterialized.go+10/-8
  - syncer
    - Msyncer.go+11/-10

```
285 unmodified lines

Current rewrite note:
- 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.
- The strategies now also depend on a narrower target-side push executor instead of raw target transport state, and direct strategy tests exercise those boundaries.
- Some helpers still carry broad parameter structs, so this remains partial rather than fully complete.

## Performance And Scalability
```

Mdocs/rewrite-issue-list.md+2/-1

```
21 unmodified lines

// Pusher wraps target-side receive-pack state behind a smaller execution API.
type Pusher struct {
	Conn    *Conn
	Adv     *packp.AdvRefs
	Verbose bool
}

// NewPusher builds a target-side push executor.
func NewPusher(conn *Conn, adv *packp.AdvRefs, verbose bool) Pusher {
	return Pusher{Conn: conn, Adv: adv, Verbose: verbose}
}

// PushPack streams a pack to the target.
func (p Pusher) PushPack(ctx context.Context, commands []PushCommand, pack io.ReadCloser) error {
	return PushPack(ctx, p.Conn, p.Adv, commands, pack, p.Verbose)
}

// PushCommands sends ref-only updates without a pack.
func (p Pusher) PushCommands(ctx context.Context, commands []PushCommand) error {
	return PushCommands(ctx, p.Conn, p.Adv, commands, p.Verbose)
}

// PushObjects encodes and pushes locally materialized objects.
func (p Pusher) PushObjects(ctx context.Context, commands []PushCommand, store storer.Storer, hashes []plumbing.Hash) error {
	return PushObjects(ctx, p.Conn, p.Adv, commands, store, hashes, p.Verbose)
}

// preparePush opens a receive-pack session and builds the base request with
// sideband negotiation. Shared by PushObjects, PushPack, and PushCommands.
func preparePush(
```
Minternal/gitproto/push.go+27

```

16 unmodified lines

// Params holds the inputs for a bootstrap execution.
type Params struct {
	SourceConn    *gitproto.Conn
	TargetConn    *gitproto.Conn
	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
	MaxPackBytes  int64
	BatchMaxPack  int64
	Verbose       bool
	Logger        *slog.Logger
	TargetPusher interface {
		PushPack(context.Context, []gitproto.PushCommand, io.ReadCloser) error
		PushCommands(context.Context, []gitproto.PushCommand) error
	}
	DesiredRefs  map[plumbing.ReferenceName]planner.DesiredRef
	TargetRefs   map[plumbing.ReferenceName]plumbing.Hash
	MaxPackBytes int64
	BatchMaxPack int64
	Verbose      bool
	Logger       *slog.Logger
}

// Result holds the outcome of the bootstrap strategy.

``` 
remaining content would continue as structured like this with code blocks, layouts, etc.

Use this cleaned content structure as needed.
