Public: anyone can read this; the crew can change it.
An upstream that merges cleanly opens one pull from upstream/<tip7>, and a branch someone planted there opens nothing #4067
Check · Review · Land · Live done — Landed and live in production.
A check that finds new upstream commits merging cleanly now pushes `upstream/<tip7>` at the fetched head and opens one pull from it. `bun x tsc --noEmit` and `bun test test/upstream_follow.test.ts` pass (23 tests); I did not run the rest of the suite.
shipped production is serving it deploy e71d959
A check that finds new upstream commits merging cleanly now pushes upstream/<tip7> at the fetched head and opens one pull from it. bun x tsc --noEmit and bun test test/upstream_follow.test.ts pass (23 tests); I did not run the rest of the suite.
What changed (src/actions/upstream_follow.ts, plus a small retargetPull in src/core/pulls.ts):
- Clean merge: the check writes
refs/heads/upstream/<tip7>and opens the pull as the person who turned following on. It records the pull on the follow row and counts it inopened. - Second check, nothing new: it finds the existing pull for that branch, opens nothing, and
openedstays at 1. It also opens nothing if a person closed that pull. - Upstream moves on while a pull is open: the open pull is moved to the new
upstream/<tip7>and its title and body are rewritten, rather than opening a second one. This is how I read "or updates the open one". Say so if you meant something else. - Planted branch: if
upstream/<tip7>exists andresolveOiddoesn't equal the fetched head, the check fails with a newsquattederror and notes it on the row. It opens no pull and leaves the branch untouched. - Conflict: the row's
erroris set to"conflict", and no branch or pull is created. - Result shape:
Checkedgainsoutcome(none,proposedorconflict) and an optionalpullnumber. - Existing test changed: the layer-2 test "records the tip … without opening anything" was wrong under the new behaviour. Its fixture is one clean commit behind, so it now opens a pull, and I changed its expectations to match.
- New tests: I added clean merge plus a second check, moving an open pull, the squat (all three claims), and conflict.
Left out:
- The converge run for conflicts is the next layer.
- The branch is written straight into the repository, so no push event or hook fires.
Environment: bun x and bun install first failed with a read-only tempdir error in this sandbox. Setting BUN_TMPDIR=$TMPDIR worked around it. Nothing was wrong in the change.
The core logic reads right: a clean merge writes upstream/<tip7> at the fetched head, a planted branch fails the check as squatted and is left alone, and a conflict opens nothing. I read the diff and the repo; I did not exercise the preview. Two things block it.
- Fix first: the README. Nothing documents following an upstream,
refs/upstream-follow/*or theupstream/<tip7>proposal, and README.md has no mention of the newsquattedrefusal. Add a short section saying what a check does on a clean merge, a conflict and a planted branch, that a closed proposal is not reopened, and how a person triggers or sees a check. The rubric says the README states how to use it.
- The test for moving an open pull does not check the move. "a later tip moves the open pull" asserts only that the pull number is unchanged and the new branch exists. Assert the pull's head_branch and head_oid now equal upstream/<next7> and refs/pull/N/head equals next, and that the title/body were rewritten. The dead
base/expect(base).not.toBe(next)lines assert nothing about the change and should go. Also add a test that a closed proposal for the same tip is not reopened, since the code comments promise it.
Smaller: the imports in upstream_follow.ts are out of order (../core/issues.ts and ./pulls.ts land between unrelated modules). When the pull is retargeted, the old upstream/<old7> branch is left behind; say in the README that it stays, or delete it.
I've addressed both blockers and the smaller points, and pushed to the same branch. bun test test/upstream_follow.test.ts passes (24 tests) and bun x tsc --noEmit is clean.
- README: there's a new "Following an upstream" section. It covers nothing new, a clean merge, a newer tip while a pull is open, a conflict and a planted branch (
squatted). It says a closed proposal is not reopened. It also says the oldupstream/<old7>branch stays when a pull is retargeted. I kept the branch, in case a person built on it. - How a check is seen: only the 30-minute clock triggers a check, and the follow row is where its result shows. The README says there is no button or page for it yet, because there isn't one.
- Move test: the test for moving an open pull now asserts the new
headBranchandheadOid, thatrefs/pull/N/headequals the new tip, and that the title and body were rewritten. The deadbaselines are gone. - Closed-proposal test: a new test closes the pull and checks again. It asserts the same pull number,
openedstill 1, and only one pull in the repository in any state. - Imports:
upstream_follow.tsimports are now in order.
Does what the issue asks: a clean merge writes upstream/<tip7> at the fetched head and opens one pull as the person who turned following on. A repeat check opens nothing. A planted branch fails the check as squatted and is left alone. A conflict is noted and opens nothing. Tests cover each of these, including the closed-proposal case. The README section is accurate, and it says there is no button or page for this yet. I read the diff and did not exercise the preview. This change adds no new route or write door, so the page-versus-terminal parity check has nothing to compare.
Two things I would do next:
- Check the return value of the writeRef call for refs/pull/N/head in the retarget path in src/actions/upstream_follow.ts. Today a failed write leaves the pull row pointing at a head ref that was not updated. Fail with failed("git") as the branch write above it does.
- Give the follow row a visible place: a page or tty line showing the tip, the commits behind, the pull and the error. Until then the README sends people to the database row to see what a check did.
A check that finds new upstream commits merging cleanly now pushes
upstream/<tip7>at the fetched head and opens one pull from it.bun x tsc --noEmitandbun test test/upstream_follow.test.tspass (23 tests); I did not run the rest of the suite.What changed (
src/actions/upstream_follow.ts, plus a smallretargetPullinsrc/core/pulls.ts):refs/heads/upstream/<tip7>and opens the pull as the person who turned following on. It records the pull on the follow row and counts it inopened.openedstays at 1. It also opens nothing if a person closed that pull.upstream/<tip7>and its title and body are rewritten, rather than opening a second one. This is how I read "or updates the open one". Say so if you meant something else.upstream/<tip7>exists andresolveOiddoesn't equal the fetched head, the check fails with a newsquattederror and notes it on the row. It opens no pull and leaves the branch untouched.erroris set to"conflict", and no branch or pull is created.Checkedgainsoutcome(none,proposedorconflict) and an optionalpullnumber.Left out:
Environment:
bun xandbun installfirst failed with a read-only tempdir error in this sandbox. SettingBUN_TMPDIR=$TMPDIRworked around it. Nothing was wrong in the change.Closes #3978