# Fix three issues from PR review

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

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

1. evenCheckpoints panic on tiny --target-max-pack-bytes: when numBatches >= len(chain), batchSize truncated to 0 and the index formula produced -1. Guard returns just the tip in this case.

2. Remove stale Mode field from ExecutionSummary: the rename to TransferMode left the old Mode field, causing both "mode" and "transfer_mode" to appear in JSON output. Only TransferMode remains.

3. Make replicate's closeOnceReadCloser thread-safe: switch from plain bool to sync.Once, matching the bootstrap package's implementation.

## Sessions

e6c1525af5a6View transcript

## Changes

5

- internal/strategy

- bootstrap

- Mbootstrap.go+1/-1

- Mbootstrap_test.go+12/-1

- replicate

- Mreplicate.go+7/-6

- pkg/gitsync/internalbridge

- Mmodel.go-2

- Mmodel_test.go+1/-1

```
580 unmodified lines

581
582
583
584
584
585
586
587

580 unmodified lines

}

func evenCheckpoints(chain []plumbing.Hash, numBatches int) []plumbing.Hash {
	if numBatches <= 1 || len(chain) <= 1 {
		if numBatches <= 1 || len(chain) <= 1 || numBatches >= len(chain) {
			return []plumbing.Hash{chain[len(chain)-1]}
		}
	}
	checkpoints := make([]plumbing.Hash, 0, numBatches)
```

Minternal/strategy/bootstrap/bootstrap.go+1/-1

```
228 unmodified lines

229
230
231
232
232
233
234
235

3 unmodified lines

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

228 unmodified lines

}
}

t.Run("more batches than chain returns just tip", func(t *testing.T) {
t.Run("more batches than chain with single element returns just tip", func(t *testing.T) {
	chain := makeHashes(1)
	got := evenCheckpoints(chain, 5)
	if len(got) != 1 {
		t.Fatalf("got %s, want tip %s", got[0], chain[0])
	}
	})

t.Run("more batches than chain with multi-element chain returns just tip", func(t *testing.T) {
	chain := makeHashes(3)
	got := evenCheckpoints(chain, 10)
	if len(got) != 1 {
		t.Fatalf("len = %d, want 1", len(got))
	}
	if got[0] != chain[2] {
		t.Fatalf("got %s, want tip %s", got[0], chain[2])
	}
	})
}

func TestCheckPackSizeAndSubdivide(t *testing.T) {
```

Minternal/strategy/bootstrap/bootstrap_test.go+12/-1

```
4 unmodified lines

5
6
7
8
9
10
11
71 unmodified lines

83
84
85
85
86
87
88
89
89
90
91
92
93
90
91
92
93
94
95
96
97

4 unmodified lines

"context"
	"fmt"
	"io"
	"sync"

"github.com/go-git/go-git/v6/plumbing"

71 unmodified lines

type closeOnceReadCloser struct {
	io.ReadCloser
	closed bool
	once sync.Once
}

func (c *closeOnceReadCloser) Close() error {
	if c.closed {
		return nil
	}
	c.closed = true
	return c.ReadCloser.Close()
	var err error
	c.once.Do(func() {
		err = c.ReadCloser.Close()
	})
	return err
}

func closeOnce(rc io.ReadCloser) io.ReadCloser {
```

Minternal/strategy/replicate/replicate.go+7/-6

```
96 unmodified lines

97
98
99
100
100
101
102
43 unmodified lines

146
147
148
150
149
150
151

96 unmodified lines

Protocol           string       `json:"protocol"`
	OperationMode      string       `json:"operation_mode"`
	Relay              bool         `json:"relay"`
	Mode               string       `json:"mode,omitempty"`
	TransferMode       string       `json:"transfer_mode"`
	Reason             string       `json:"reason"`
	BootstrapSuggested bool         `json:"bootstrap_suggested"`
43 unmodified lines

Protocol:           result.Protocol,
		OperationMode:      result.OperationMode,
		Relay:              result.Relay,
		Mode:               result.RelayMode,
		TransferMode:       result.RelayMode,
		Reason:             result.RelayReason,
		BootstrapSuggested: result.BootstrapSuggested,
```

Mpkg/gitsync/internalbridge/model.go-2

```
84 unmodified lines

85
86
87
88
88
89
90
91

84 unmodified lines

if got.Counts.Applied != 1 || got.Counts.Skipped != 2 || got.Counts.Blocked != 3 || got.Counts.Deleted != 4 {
		t.Fatalf("unexpected counts: %+v", got.Counts)
	}
	if !got.Execution.DryRun || !got.Execution.Relay || got.Execution.OperationMode != "replicate" || got.Execution.Mode != "incremental-relay" || got.Execution.TransferMode != "incremental-relay" || got.Execution.Reason != "fast-forward" {
	if !got.Execution.DryRun || !got.Execution.Relay || got.Execution.OperationMode != "replicate" || got.Execution.TransferMode != "incremental-relay" || got.Execution.Reason != "fast-forward" {
		t.Fatalf("unexpected execution summary: %+v", got.Execution)
	}
	if !got.Execution.Batch.Enabled || got.Execution.Batch.Done != 5 || got.Execution.Batch.Planned != 6 {
