# Merge branch 'main' into feat/review-nonblocking-tui-sink

`7801409`→[main](/content/gh/entireio/cli/commits/main/index.html)·  
  
peyton-alt·4d ago·6 files·+130 added/-8 removed

## Changes

6

- internal/remotehelper/githelper

- Minvariants\_test.go+61/-1

- Mlist.go+2/-2

- Mlist\_test.go+1/-1

- Mpush.go+6/-2

- Arefadv\_cache.go+55

- Mrun.go+5/-2

```
322 unmodified lines

322 unmodified lines

stdin := bufio.NewReader(strings.NewReader("\n"))

var stdout bytes.Buffer
err := handlePush(context.Background(), ft, firstLine, &Options{}, stdin, &stdout)
err := handlePush(context.Background(), ft, &refAdvCache{}, firstLine, &Options{}, stdin, &stdout)
if err == nil {
	t.Fatal("expected error from send-pack exit 1")
}
2 unmodified lines

```

// TestInvariant_PushReusesListForPushAdvertisement pins the fix for ENCLI-267.
// Within one helper session the "push" command MUST reuse the ref
// advertisement fetched during "list for-push" rather than re-fetching
// info/refs. Git snapshots the remote refs from "list for-push" into its
// remote_refs list *before* running the pre-push hook, and the hook pushes
// per-checkpoint refs to the same remote. A fresh info/refs at push time then
// hands send-pack a ref (the freshly-pushed checkpoint) Git never asked to
// push; send-pack emits `error <ref> no match`, and Git — not finding it in
// remote_refs — warns `helper reported unexpected status of <ref>`. Reusing
// the list-for-push snapshot mirrors remote-curl.c's discovery cache and keeps
// that phantom ref out of send-pack's view.
func TestInvariant_PushReusesListForPushAdvertisement(t *testing.T) {
	// No t.Parallel(): t.Setenv("PATH", ...) mutates process-global state.
	if runtime.GOOS == "windows" {
		 t.Skip("shell-script PATH stub is POSIX-only")
	}

ref := testRefMain
	oldSHA := strings.Repeat("a", 40)

// Stub git send-pack: emit the empty-request terminator, drain stdin,
	// then the trailing flush + a plain "ok" helper-status, exit 0.
	stubDir := t.TempDir()
	stub := "#!/bin/sh\nprintf '0000'\ncat > /dev/null\nprintf '0000ok " + ref + "\n'\nexit 0\n"
	if err := os.WriteFile(filepath.Join(stubDir, "git"), []byte(stub), 0o755); err != nil {
		 t.Fatalf("writing stub git: %v", err)
	}
	t.Setenv("PATH", stubDir+string(os.PathListSeparator)+os.Getenv("PATH"))

// The checkpoint ref the pre-push hook would push between list-for-push
	// and push: absent from the first advertisement, present in the second, so
	// a re-fetch (the bug) would expose it to send-pack.
	checkpointRef := "refs/entire/checkpoints/9H/01KX2ATMJ3FAZZFZ8CP1CA279H"
	receivePackCalls := 0
	ft := &fakeTransport{
		infoRefsResp: func() (io.ReadCloser, error) {
			receivePackCalls++
			refLine := oldSHA + " " + ref + "\x00report-status object-format=sha1\n"
			if receivePackCalls == 1 {
				return stringRC(serviceAnnouncement(serviceReceivePack, refLine)), nil
			}
			return stringRC(serviceAnnouncement(serviceReceivePack, refLine,
				oldSHA+" "+checkpointRef+"\n")), nil
		},
		serviceRPCResp: func(string, []byte) (io.ReadCloser, error) {
			return stringRC(""), nil
		},
	}

stdin := strings.NewReader("list for-push\npush " + oldSHA + ":" + ref + "\n\n")
	var stdout bytes.Buffer
	if err := Run(context.Background(), ft, 2, stdin, &stdout); err != nil {
		 t.Fatalf("Run: %v", err)
	}

if receivePackCalls != 1 {
		 t.Fatalf("receive-pack info/refs fetched %d times; want 1 (push must reuse the list-for-push advertisement)", receivePackCalls)
	}
}
```

// writes one "<value> <name>" line per ref followed by a blank-line
// terminator. HEAD is emitted as "@<target> HEAD" when the symref
// capability resolves; detached HEAD falls back to "<sha> HEAD".
func handleList(ctx context.Context, t Transport, forPush bool, stdout io.Writer) error {
func handleList(ctx context.Context, t Transport, adv *refAdvCache, forPush bool, stdout io.Writer) error {
	service := serviceUploadPack
	if forPush {
		service = serviceReceivePack
	}
	refs, err := t.InfoRefs(ctx, service)
	refs, err := adv.infoRefs(ctx, t, service)
	if err != nil {
		return fmt.Errorf("list %s info/refs: %w", service, err)
	}
}

```

func Run(ctx context.Context, t Transport, protocolVersion int, stdin io.Reader, stdout io.Writer) error {
	commandReader := bufio.NewReader(stdin)
	opts := &Options{}
	// One advertisement snapshot per session: "push" reuses what
	// "list for-push" fetched. See refAdvCache / ENCLI-267.
	adv := &refAdvCache{}

for {
		line, err := commandReader.ReadString('\n')
		if err != nil {
			return fmt.Errorf("failed reading command: %w", err)
		}

fmt.Fprintln(stdout)
		
		case line == "list" || line == "list for-push":
			if err := handleList(ctx, t, line == "list for-push", stdout); err != nil {
			if err := handleList(ctx, t, adv, line == "list for-push", stdout); err != nil {
				return err
			}
		}
			 return nil
		case strings.HasPrefix(line, "push "):
			if err := handlePush(ctx, t, line, opts, commandReader, stdout); err != nil {
			if err := handlePush(ctx, t, adv, line, opts, commandReader, stdout); err != nil {
				return err
			}
		}
}

```

package githelper

import (
	"bytes"
	"context"
	"fmt"
	"io"
)

// refAdvCache memoizes the receive-pack ref advertisement across a single
// helper session so the "push" command reuses the exact ref snapshot that
// "list for-push" fetched. This mirrors remote-curl.c's discovery cache
// (get_refs/last_refs): Git builds its remote_refs list from the
// "list for-push" advertisement, then runs the pre-push hook, then issues
// "push". The Entire pre-push hook pushes per-checkpoint refs to the same
// remote in that window, so a fresh info/refs at push time would hand
// send-pack a ref Git never asked to push. send-pack then reports
// `error <ref> no match` and Git — not finding it in remote_refs — warns
// `helper reported unexpected status of <ref>` (ENCLI-267). Reusing the
// snapshot keeps that phantom ref out of send-pack's view.
//
// Only the receive-pack (for-push) advertisement is cached; upload-pack and
// v2 fetches pass straight through, matching remote-curl's per-for_push cache.
type refAdvCache struct {
	receivePack []byte
	cached      bool
}

// infoRefs returns the ref advertisement for service. The receive-pack
// advertisement is fetched from the Transport once and replayed from an
// in-memory buffer on subsequent calls; every other service is fetched fresh.
func (c *refAdvCache) infoRefs(ctx context.Context, t Transport, service string) (io.ReadCloser, error) {
	if service != serviceReceivePack {
		rc, err := t.InfoRefs(ctx, service)
		if err != nil {
			return nil, fmt.Errorf("fetch %s advertisement: %w", service, err)
		}
		return rc, nil
	}
	if c.cached {
		return io.NopCloser(bytes.NewReader(c.receivePack)), nil
	}
	rc, err := t.InfoRefs(ctx, service)
	if err != nil {
		return nil, fmt.Errorf("fetch %s advertisement: %w", service, err)
	}
	defer rc.Close()
	buf, err := io.ReadAll(rc)
	if err != nil {
		return nil, fmt.Errorf("buffer %s advertisement: %w", service, err)
	}
	c.receivePack = buf
	c.cached = true
	return io.NopCloser(bytes.NewReader(buf)), nil
}
