test(integration): add git-refs push-queue semantics (D6 multi-worktree, D7 two-remote pin) · Entire

test(integration): add git-refs push-queue semantics (D6 multi-worktree, D7 two-remote pin)

d93c1e3·

Soph·1w ago·2 files·+174 added/-4 removed

D6: the git-refs push queue lives in the shared git common dir, so sessions in two worktrees enqueue into ONE queue. A single pre-push from the main worktree pushes both worktrees' checkpoint refs, drains + compacts the queue, and prunes a stale entry (a queued ref with no local ref -> partitionLocalRefs). Adds an AddWorktree test helper (its own .entire/, shared common dir, offset session counter so session IDs don't collide in the shared session store).

D7: PIN the known two-remote queue-clearing gap (test plan decision D-2). The queue records only the ref, not the remote, so a push to remote A drains the queue and remote B never receives those refs. Asserts current behavior with a clear "flip when per-remote tracking lands" note. No production change.

Also resolves the COMMIT_EDITMSG scratch path via git rev-parse --absolute-git-dir so the shadow-commit test helpers work in a linked worktree (where .git is a file); identical to the prior path for normal checkouts.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_012yi3hHGAGepwfrfjPETjGq

Sessions

057f6136f6f5View transcript

[?
Comprehensive Checkpoint Testing CoverageCodex·GPT-5.5·2 steps](/content/gh/entireio/cli/session/019f22a2-95f4-7d71-8140-4d86b0d40aa5#timeline-057f6136f6f5/index.html)

Changes

2

//go:build integration

package integration

import (
    "testing"

"github.com/stretchr/testify/require"
)

// =============================================================================
// D6 / D7 -- git-refs push-queue semantics (integration).
// =============================================================================

// TestGitRefsQueue_MultiWorktreeSharedQueueDrains is D6: the git-refs push queue
// lives in the shared git common dir, so a session in a linked worktree and a
// session in the main worktree both enqueue into ONE queue. A single pre-push
// from the main worktree pushes BOTH worktrees' checkpoint refs, drains the queue
// to empty, and prunes a stale entry (a queued ref that no longer exists locally),
// exercising partitionLocalRefs.
func TestGitRefsQueue_MultiWorktreeSharedQueueDrains(t *testing.T) {
    t.Parallel()

env := NewFeatureBranchEnv(t)
    env.CheckpointStore = StoreGitRefs
    bareDir := env.SetupBareRemote()

// Session in the main worktree enqueues its checkpoint ref into the shared queue.
    _ = createCheckpointedCommit(t, env, "main worktree work", "main_wt.go", "package mainwt", "main worktree work")
    queueAfterMain := env.PushQueueRefs()
    require.NotEmpty(t, queueAfterMain, "main worktree session should enqueue a checkpoint ref")

// Session in a linked worktree (shares the git common dir, so the SAME queue).
    wt := env.AddWorktree("feature/wt-second")
    _ = createCheckpointedCommit(t, wt, "linked worktree work", "wt.go", "package wt", "linked worktree work")

// The shared queue (read from the main worktree) now holds an additional
    // distinct ref enqueued by the linked worktree's session.
    realRefs := env.PushQueueRefs()
    require.Greater(t, len(realRefs), len(queueAfterMain),
        "the linked worktree's session should enqueue an additional ref into the shared common-dir queue")

// A stale entry (no such local ref) must be pruned, not pushed or retried forever.
    staleRef := checkpointRefName("ffffffffffff")
    enqueueCheckpointRef(t, env, staleRef)

// One pre-push from the main worktree drains everything pushable in the queue.
    env.RunPrePush("origin")

for _, ref := range realRefs {
        require.True(t, refExists(t, bareDir, ref),
            "both worktrees' checkpoint refs must reach the remote via the shared queue: %s", ref)
    }
    require.False(t, refExists(t, bareDir, staleRef),
        "a stale queue entry must not be pushed")
    require.Empty(t, env.PushQueueRefs(),
        "the shared queue must be drained and compacted after a successful push (stale entry pruned)")
}

// TestGitRefsQueue_TwoRemotesQueueClearedByFirstPush is D7: it PINS the known
// two-remote queue-clearing gap (test plan decision D-2).
//
// KNOWN BUG / PINNED CURRENT BEHAVIOR: the push queue records only the ref, not
// which remote it was pushed to. A successful pre-push to ANY remote drains the
// queue, so a second remote never receives those refs. This test asserts that
// current (buggy) behavior on purpose, so a regression is visible and so the
// fix is a deliberate, reviewed change.
//
// WHEN THE FIX LANDS (per-remote push tracking, or "drain only when pushed to the
// fetch-resolution target"): flip the final assertion — the second remote SHOULD
// then receive the checkpoint refs.
func TestGitRefsQueue_TwoRemotesQueueClearedByFirstPush(t *testing.T) {
    t.Parallel()

env := NewFeatureBranchEnv(t)
    env.CheckpointStore = StoreGitRefs

bareOrigin := env.SetupBareRemote()
    bareSecond := env.SetupNamedBareRemote("second")

cp := createCheckpointedCommit(t, env, "Add module", "mod.go", "package mod", "Add module")
    require.NotEmpty(t, cp)
    require.Contains(t, env.PushQueueRefs(), checkpointRefName(cp), "checkpoint ref should be queued")

// Push to origin first — this drains the queue.
    env.RunPrePush("origin")
    require.True(t, env.CheckpointExistsOnRemote(bareOrigin, cp),
        "origin should receive the checkpoint ref")
    require.Empty(t, env.PushQueueRefs(),
        "the queue is drained by the first push regardless of remote (root of the D-2 gap)")

// Now push to the second remote. Because the queue is already empty, nothing is
    // sent — the second remote permanently misses the checkpoint.
    env.RunPrePush("second")

// PINNED CURRENT BEHAVIOR (test plan D-2): the second remote never gets the ref.
    // Flip this to require.True when per-remote queue tracking lands.
    require.False(t, env.CheckpointExistsOnRemote(bareSecond, cp),
        "KNOWN BUG (D-2): the second remote misses checkpoint refs the first push drained; "+
        "flip to require.True when per-remote push tracking lands")
}