Add cancellation coverage and tighten rewrite tracker · Entire

Add cancellation coverage and tighten rewrite tracker

4e9ecda→main·

Soph·3mo ago·3 files·+80 added/-3 removed

Sessions

edee273e9e3bView 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-edee273e9e3b/index.html)

Changes

3

66 unmodified lines

67
68
69
70
70
71
72
73
350 unmodified lines

424
425
426
427
428
429
430
431
432
433
434
435
433
436
437
438
439
440
1 unmodified line

442
443
444
441
445
446
447
448
449

66 unmodified lines

### 1. Batched bootstrap can claim tag refs were pushed when no tag ref was created

Status: done
Status: partial

Problem:
- In the batched bootstrap tag phase, `FetchPack` returning `git.NoErrAlreadyUpToDate` can skip tag creation entirely even when the tag ref is absent and only the tag object is already reachable.
350 unmodified lines

Rewrite requirement:
- Add benchmarks for relay path overhead, planning overhead, and fallback graph/object work.

Current rewrite note:
- Planner and protocol benchmarks exist, but execution-path benchmarks for bootstrap relay, incremental relay, and materialized fallback still appear missing.

## Rewrite Branch Acceptance Criteria

- All mapping validation happens before network activity. Status: done
- Capability negotiation is centralized and enforced consistently. Status: partial
- Relay strategies are separate packages with explicit inputs and outputs. Status: done
- Tag creation is correct whether or not a pack transfer is needed. Status: done
- Stats and logging are concurrency-safe. Status: partial
- Stats are concurrency-safe. Status: done
- Logging is structured and concurrency-safe. Status: open
- Protocol parsing has explicit malformed-input tests. Status: done
- Rewrite passes `go test ./...` and `go test -race ./...`. Status: done
- Rewrite includes benchmarks for the critical planning and execution paths. Status: done
1 unmodified line

Notes:
- Capability handling is much better centralized under `internal/gitproto`, but the rewrite still uses `go-git` transport/protocol types rather than fully owning the protocol layer end-to-end.
- Stats are now concurrency-safe; logging is still ad hoc `progressf` output rather than a structured logger.
- Stats are now concurrency-safe and race-tested.
- Logging is still ad hoc `progressf` output rather than structured logging.

## Suggested Execution Order

Mdocs/rewrite-issue-list.md+8/-3

1
2
3
4
5
6
7
8
9
10
68 unmodified lines

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

package gitproto

import (
    context
    "errors"
    "net/http"
    "net/http/httptest"
    "testing"

"github.com/go-git/go-git/v5/plumbing/transport"
68 unmodified lines

req, _ = http.NewRequest("GET", "https://example.com", nil)
    ApplyAuth(req, nil)
}

func TestRequestInfoRefsContextCanceled(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        <-r.Context().Done()
    }))
    defer server.Close()

ep, err := transport.NewEndpoint(server.URL + "/repo.git")
    if err != nil {
        t.Fatalf("parse endpoint: %v", err)
    }
    conn := NewConn(ep, "source", nil, http.DefaultTransport)

ctx, cancel := context.WithCancel(context.Background())
    cancel()

_, err = RequestInfoRefs(ctx, conn, "git-upload-pack", "version=2")
    if err == nil {
        t.Fatal("expected cancellation error, got nil")
    }
    if !errors.Is(err, context.Canceled) {
        t.Fatalf("expected context.Canceled, got %v", err)
    }
}

func TestPostRPCStreamContextCanceled(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        <-r.Context().Done()
    }))
    defer server.Close()

ctx, cancel := context.WithCancel(context.Background())
    cancel()

_, err = PostRPCStream(ctx, conn, "git-upload-pack", []byte("0000"), true, "upload-pack fetch")
    if err == nil {
        t.Fatal("expected cancellation error, got nil")
    }
    if !errors.Is(err, context.Canceled) {
        t.Fatalf("expected context.Canceled, got %v", err)
    }
}

Minternal/gitproto/smarthttp_test.go+51

2 unmodified lines

3
4
5
6
7
8
9
148 unmodified lines

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

2 unmodified lines

import (
    "bytes"
    "context"
    "errors"
    "fmt"
    "io"
    "net/http"
148 unmodified lines

}
}

func TestProbe_ContextCanceled(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        <-r.Context().Done()
    }))
    defer server.Close()

ctx, cancel := context.WithCancel(context.Background())
    cancel()

_, err := Probe(ctx, Config{
        Source: Endpoint{URL: server.URL + "/repo.git"},
    })
    if err == nil {
        t.Fatal("expected context cancellation error")
    }
    if !errors.Is(err, context.Canceled) {
        t.Fatalf("expected context.Canceled, got %v", err)
    }
}

func TestBootstrap_IntegrationInitialSyncToEmptyTarget(t *testing.T) {
    sourceRepo, sourceFS := newSourceRepo(t)
    makeCommits(t, sourceRepo, sourceFS, 4)