Twinned from https://github.com/cfsh/ninefold/issues/643 by tools/beads/import_github.py's reconcile pass.
merge_pr.py moves your current branch to main on any worktree-based checkout, silently. Work that is committed but not pushed is unreachable afterwards.
Filed separately from #566 because that issue is a broad "can't merge on Linux" thread and this is one specific, severe, actively-armed defect that should not be lost in it. Reported there first: <https://github.com/cfsh/ninefold/issues/566#issuecomment-5204988764>
tools/pr/merge_pr.py:454-456, after a successful merge:
```python run(["git", "checkout", "main"], check=False) run(["git", "fetch", "origin"], check=False) run(["git", "reset", "--hard", "origin/main"], check=False) ```
git checkout main cannot succeed on a worktree box — git permits one worktree per branch, and main is checked out in the parent (~/nf/ninefold). It is check=False, so the failure is discarded. The reset --hard then runs anyway, against whatever ref is actually checked out: your feature branch.
Immediately after merge_pr.py 596 from /root/nf/devs/bork:
``` ## feat/reviewer-worktrees...origin/feat/reviewer-worktrees [ahead 4, behind 7] HEAD = d574e15 "reviewer: check the PR description is still true of the PR (#596)" ```
d574e15 was main's tip. The local branch had been repointed at main; four commits were no longer reachable by that name. Recovered with git reset --hard origin/feat/reviewer-worktrees only because they were pushed.
The same run's probe-gate line agrees: [probe-gate] sweeping probes on feat/reviewer-worktrees @ d574e15 — it gated main's tree while naming the feature branch.
merged #596 and synced main and reads as clean.Gate the reset on the checkout actually succeeding, and say so when it does not:
```python switched = run(["git", "checkout", "main"], check=False) run(["git", "fetch", "origin"], check=False) if switched.ok: run(["git", "reset", "--hard", "origin/main"], check=False) else: print("merge_pr: NOT syncing local main — it is checked out in another " "worktree. Sync it there; this checkout is untouched.", file=sys.stderr) ```
Strictly better on every box: unchanged behaviour on a normal clone, and on a worktree box it stops rewriting a ref it was never asked to touch. Worth a test that a failed checkout main produces no reset --hard, since the current failure mode is exactly "an error was swallowed and the next command ran regardless".
⚠️ Workaround until then: git checkout --detach before running merge_pr.py, so there is no branch pointer to move. That is what I did for the following merge, deliberately.
Found while wrapping the #576 chunk. Unclaimed.
None.
No comments.