The gap
create-dev-loop.md's Edge cases entry "Branch is behind main or has a merge conflict at Phase 8" prescribes a bare force-push:
git fetch origin
git rebase origin/{{DEFAULT_BRANCH}}
{{TEST_CMD}}
git push --force-with-lease
In a restricted clone — the gardener-managed kind the template already documents elsewhere, whose remote.origin.fetch covers the default branch only — a bare --force-with-lease has no maintained tracking ref to compare against and is rejected as:
! [rejected] <branch> -> <branch> (stale info)
The explicit form --force-with-lease=<branch>:<sha> fixes that, but introduces a second failure with identical wording: the expected value is compared against the remote ref literally and abbreviations are never expanded, so a short SHA copied from git log --oneline is also rejected as (stale info).
Three unrelated causes therefore produce one message — a restricted fetch refspec, an abbreviated SHA, and a genuine concurrent push — and the correct response differs for each. Only the third justifies backing off, which is precisely what an agent reading (stale info) at face value will do, or (worse) it falls back to a plain --force and clobbers unseen work.
Suggested direction
Alongside the rebase fence, state that the lease value must be the full 40-character SHA and should be re-read from the remote at push time:
git ls-remote origin refs/heads/<branch> # full 40-char SHA
git push origin <branch>:<branch> --force-with-lease=<branch>:<full-sha>
and add the disambiguation rule: a (stale info) rejection must not be read as "another session pushed" until the expected SHA has been confirmed to be in full form and re-read from the remote. git rev-parse origin/<branch> also yields the full form but only reflects the last fetch, so git ls-remote is preferable where the lease is meant to be meaningful.
Provenance
Observed in the generated medieval-factions-dev-loop instance (dmccoystephenson/medieval-factions-dev-loop#42), where the restricted-refspec half was already documented and the abbreviated-SHA half was not. The instance has been fixed locally; this issue is filed so the rule is not left to diverge from the template, since the mechanism is plain Git behaviour rather than anything repository-specific. The template's fence was read directly at main before filing.
This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson
The gap
create-dev-loop.md's Edge cases entry "Branch is behind main or has a merge conflict at Phase 8" prescribes a bare force-push:git fetch origin git rebase origin/{{DEFAULT_BRANCH}} {{TEST_CMD}} git push --force-with-leaseIn a restricted clone — the gardener-managed kind the template already documents elsewhere, whose
remote.origin.fetchcovers the default branch only — a bare--force-with-leasehas no maintained tracking ref to compare against and is rejected as:The explicit form
--force-with-lease=<branch>:<sha>fixes that, but introduces a second failure with identical wording: the expected value is compared against the remote ref literally and abbreviations are never expanded, so a short SHA copied fromgit log --onelineis also rejected as(stale info).Three unrelated causes therefore produce one message — a restricted fetch refspec, an abbreviated SHA, and a genuine concurrent push — and the correct response differs for each. Only the third justifies backing off, which is precisely what an agent reading
(stale info)at face value will do, or (worse) it falls back to a plain--forceand clobbers unseen work.Suggested direction
Alongside the rebase fence, state that the lease value must be the full 40-character SHA and should be re-read from the remote at push time:
and add the disambiguation rule: a
(stale info)rejection must not be read as "another session pushed" until the expected SHA has been confirmed to be in full form and re-read from the remote.git rev-parse origin/<branch>also yields the full form but only reflects the last fetch, sogit ls-remoteis preferable where the lease is meant to be meaningful.Provenance
Observed in the generated
medieval-factions-dev-loopinstance (dmccoystephenson/medieval-factions-dev-loop#42), where the restricted-refspec half was already documented and the abbreviated-SHA half was not. The instance has been fixed locally; this issue is filed so the rule is not left to diverge from the template, since the mechanism is plain Git behaviour rather than anything repository-specific. The template's fence was read directly atmainbefore filing.This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson