refactor(strategy): replace empty-remote network probe with a local, git-branch-only guard · Entire
refactor(strategy): replace empty-remote network probe with a local, git-branch-only guard
db1c52f→main·
karthik-rameshkumar·3d ago·7 files·+96 added/-453 removed
Implements pjbgf's CHANGES_REQUESTED review (#1744):
- Gate by checkpoint type: git-refs stores checkpoints under refs/entire/*, which a forge cannot select as a default branch, so the first-user-branch guard is git-branch only. prePush now returns via prePushCheckpointRefs for git-refs without ever consulting the guard.
- Decide locally, no network: deferCheckpointPushOnEmptyRemote now checks only
for a local remote-tracking ref (refs/remotes/
/*) via git for-each-ref. Git records one after the first successful push, so deferred metadata publishes on the next push. Removes the ls-remote probe entirely — a network round trip on pre-push can trigger an SSH security-key touch prompt, and per-push-URL probing multiplied those prompts. - Use only the remote git handed the hook: dropped PushTargetsInDir / get-url --push --all (and its multi-pushurl handling). Different push URLs can need different auth (unexpected Yubikey flashing).
This deletes the whole probe/marker apparatus from the prior rounds — marker file, TTL, fingerprint, os.Root storage, probe timeout, disable-time sweep, and the PushTargetsInDir helper — since a local ref check needs no memoization.
Note: HEAD-specifically (refs/remotes/
Tests: unit test proves the guard is local-only (unreachable URL, never dialed); integration test now asserts both behaviors — git-branch defers then publishes, git-refs publishes on the first push. Alternates canary records a tracking ref to reflect an established remote. Full canary 59/59.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
01KXGBJKM1XD05SF7J8PRD4AP6View transcript
Changes
7
cmd/entire/cli
checkpoint/remote
Mgit.go-54
Mgit_test.go-33
integration_test
- Mreal_hook_push_test.go+22/-101
Msetup.go-3
strategy
Mmanual_commit_push.go+43/-205
Mmanual_commit_push_test.go+25/-57
e2e/tests
- Malternates_test.go+6
2 unmodified lines
3
4
5
6
6
7
8
232 unmodified lines
241
242
243
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
244
245
246
2 unmodified lines
import (
"context"
"encoding/base64"
"errors"
"fmt"
"log/slog"
"os"
232 unmodified lines
return lsRemote(ctx, dir, remote, patterns...)
}
// PushTargetsInDir resolves the endpoint or endpoints Git will use for a push.
// A named remote may configure pushurl, which differs from its fetch URL and
// can contain more than one destination. URLs and local paths are already
// concrete push targets and are returned unchanged.
func PushTargetsInDir(ctx context.Context, dir, target string) ([]string, error) {
if target == "" {
return nil, errors.New("push target must not be empty")
}
if isConcretePushTarget(target) {
return []string{target}, nil
}
cmd := newCommand(ctx, "remote", "get-url", "--push", "--all", target)
if dir != "" {
cmd.Dir = dir
}
disableTerminalPrompt(cmd)
out, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("git remote get-url --push: %w", err)
}
var targets []string
for _, line := range strings.Split(string(out), "\n") {
if pushURL := strings.TrimSpace(line); pushURL != "" {
targets = append(targets, pushURL)
}
}
if len(targets) == 0 {
return nil, fmt.Errorf("git remote get-url --push: no push target for %q", target)
}
return targets, nil
}
// isConcretePushTarget reports whether target is already a concrete push
// endpoint (a URL or local path) rather than a git remote NAME whose pushurl
// must be resolved. It deliberately does not reuse IsURL's '@' heuristic, which
// misclassifies a remote name that merely contains '@' (e.g. "build@ci") as a
// URL and would skip pushurl resolution for it. Following git's own transport
// detection, an scp-like SSH target has a colon before any slash
// ("[user@]host:path"); a bare remote name has neither a scheme nor such a
// colon.
func isConcretePushTarget(target string) bool {
if strings.Contains(target, "://") || isLocalPath(target) {
return true
}
// scp-like SSH URL: a colon appears before any slash.
if i := strings.IndexAny(target, ":/"); i >= 0 && target[i] == ':' {
return true
}
return false
}
func lsRemote(ctx context.Context, dir, remote string, patterns ...string) ([]byte, error) {
args := append([]string{"ls-remote", remote}, patterns...)
cmd := newCommand(ctx, args...)
``