git-refs push queue can drop a newer same-ref update during an in-flight push
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 475
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 178
Description
What happened?
The git-refs checkpoint push queue can acknowledge a newer update that was not
actually pushed.
PushQueue.Drain() snapshots queued ref names without removing them. After the
network push succeeds, PushQueue.Remove() removes every current queue entry
whose ref name matches the drained set. If the same checkpoint ref advances and
is enqueued again while that push is in flight, the successful push publishes
the older object but Remove() also deletes the newer same-ref queue entry.
The resulting state is:
- remote checkpoint ref: older object A;
- local checkpoint ref: newer object B;
- push queue: empty.
I expected the enqueue for B to remain queued for the next push. Instead, queue
state says there is nothing pending, so the latest checkpoint transcript,
summary, or attribution can remain local until another write happens to enqueue
that ref again.
This is a local concurrency/correctness and recoverability bug, not a remote
security vulnerability. It requires the same checkpoint ref to be updated
during the network-push window. A serial single-agent workflow is unlikely to
hit it, but it is reachable when concurrent processes or linked worktrees share
the Git common directory and update the same checkpoint.
The relevant paths on current main are:
cmd/entire/cli/checkpoint/pushqueue.go:Drain()returns de-duplicated ref
names;Remove()removes all current entries matching those names.cmd/entire/cli/strategy/manual_commit_push.go: after a successful batch
push,flushCheckpointRefsQueue()callsqueue.Remove(existing).
Steps to reproduce
The smallest queue-level regression is:
func TestPushQueue_RemovePreservesNewerSameRefEntry(t *testing.T) {
t.Parallel()
q := NewPushQueue(t.TempDir())
ref := plumbing.ReferenceName("refs/entire/checkpoints/a1/a1b2c3d4e5f6")
require.NoError(t, q.Enqueue(ref))
drained, err := q.Drain()
require.NoError(t, err)
// Simulate the same ref advancing and being enqueued during the push.
require.NoError(t, q.Enqueue(ref))
require.NoError(t, q.Remove(drained))
remaining, err := q.Peek()
require.NoError(t, err)
require.Equal(t, []plumbing.ReferenceName{ref}, remaining)
}
It currently fails with remaining=[].
I also reproduced the production boundary with a disposable local repository
and bare remote:
- Point a queued checkpoint ref at commit A.
- Start
strategy.PushQueuedCheckpointRefsand pause the bare remote in a
pre-receivehook. - While the push is paused, create commit B, advance the same local checkpoint
ref to B, and enqueue that ref again. - Release the push and wait for it to succeed.
- Compare the remote tip, local tip, and
queue.Peek().
This reproduces deterministically under the controlled pause: remote A, local
B, empty queue. Both unchanged regressions reproduced the expected failure on
current main, while all 8/8 focused upstream TestPushQueue_* tests and 4/4 focused
TestPushQueuedCheckpointRefs* tests passed. The existing
TestPushQueue_RemovePreservesLaterEntries covers a different ref appended
during the push, not a newer generation of the same ref.
Entire CLI version
Entire CLI v0.10.0
OS and architecture
Windows amd64 (Microsoft Windows NT 10.0.26200.0)
Agent
Codex
Terminal
PowerShell
Logs / debug output
drained=[refs/entire/checkpoints/a1/a1b2c3d4e5f6] remaining=[]
newer same-ref enqueue was lost
remote_tip=cd5b922f02ed8c7c275d7938b4eddfa979c8d6f7
local_tip=74724cac5b2968b25d5b50b16c11785ceaef653d
remaining_queue=[]
same-ref update was not retained after successful push
## Additional context
I searched the current public issues and pull requests and found adjacent work,
but no exact report or active fix for this same-ref generation loss:
- `#1635` concerns one remote consuming queue state needed by a second remote.
- `#1917` / `#1926` concern concurrent checkpoint-store writers racing before
queue publication.
- This report concerns a newer enqueue being removed after an older in-flight
network push succeeds.
Additional context
Go version used by the disposable regression module: go1.26.5.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with cmd/entire/cli/checkpoint/pushqueue.go, especially Drain and Remove, then trace flushCheckpointRefsQueue in cmd/entire/cli/strategy/manual_commit_push.go. Run the focused TestPushQueue_* and TestPushQueuedCheckpointRefs* tests, then use the reported same-ref regression scenario to verify that a newer enqueue remains after the older push succeeds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, go
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100