From 0424668fe943700d53eb16f20710bc944351f6a5 Mon Sep 17 00:00:00 2001 From: Max Shepherd-Cross Date: Mon, 15 Jun 2026 13:03:27 +1000 Subject: [PATCH 1/2] docs: handle squash merge readback --- land-and-deploy/SKILL.md | 12 ++++++++++++ land-and-deploy/SKILL.md.tmpl | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index f2c3e75c7..20e96d820 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -1479,6 +1479,18 @@ Capture merge SHA: gh pr view --json mergeCommit -q .mergeCommit.oid ``` +Squash/rebase merge readback guard: +- Do **not** prove success by requiring the PR head SHA to be an ancestor of the base branch. GitHub squash and rebase merges deliberately create a new commit, so `git merge-base --is-ancestor origin/` can fail even when the PR is merged. +- Once GitHub reports `state == "MERGED"` with a non-null `mergeCommit.oid`, treat that as authoritative. Record the merge SHA and continue. +- If local cleanup or readback is needed, fetch the base branch and compare/sync against the merge commit, not the old PR branch commit: +```bash +BASE=$(gh pr view --json baseRefName -q .baseRefName) +MERGE_SHA=$(gh pr view --json mergeCommit -q .mergeCommit.oid) +git fetch origin "$BASE" +git diff --quiet "$MERGE_SHA" origin/"$BASE" || git log --oneline --decorate -1 "$MERGE_SHA" origin/"$BASE" +``` +- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer non-destructive cleanup such as `git switch --detach "$MERGE_SHA"` for throwaway task worktrees. Do not force-push or reset a user's branch unless they explicitly ask. + Worktree cleanup — non-destructive, candidate-based: ```bash git worktree list --porcelain diff --git a/land-and-deploy/SKILL.md.tmpl b/land-and-deploy/SKILL.md.tmpl index 98976ad02..fd2fb5db1 100644 --- a/land-and-deploy/SKILL.md.tmpl +++ b/land-and-deploy/SKILL.md.tmpl @@ -631,6 +631,18 @@ Capture merge SHA: gh pr view --json mergeCommit -q .mergeCommit.oid ``` +Squash/rebase merge readback guard: +- Do **not** prove success by requiring the PR head SHA to be an ancestor of the base branch. GitHub squash and rebase merges deliberately create a new commit, so `git merge-base --is-ancestor origin/` can fail even when the PR is merged. +- Once GitHub reports `state == "MERGED"` with a non-null `mergeCommit.oid`, treat that as authoritative. Record the merge SHA and continue. +- If local cleanup or readback is needed, fetch the base branch and compare/sync against the merge commit, not the old PR branch commit: +```bash +BASE=$(gh pr view --json baseRefName -q .baseRefName) +MERGE_SHA=$(gh pr view --json mergeCommit -q .mergeCommit.oid) +git fetch origin "$BASE" +git diff --quiet "$MERGE_SHA" origin/"$BASE" || git log --oneline --decorate -1 "$MERGE_SHA" origin/"$BASE" +``` +- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer non-destructive cleanup such as `git switch --detach "$MERGE_SHA"` for throwaway task worktrees. Do not force-push or reset a user's branch unless they explicitly ask. + Worktree cleanup — non-destructive, candidate-based: ```bash git worktree list --porcelain From 05f19d7f129b893bf38fabe8859fac0b06716aeb Mon Sep 17 00:00:00 2001 From: Max Shepherd-Cross Date: Mon, 15 Jun 2026 13:11:34 +1000 Subject: [PATCH 2/2] docs: avoid detached post-merge worktrees --- land-and-deploy/SKILL.md | 2 +- land-and-deploy/SKILL.md.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index 20e96d820..757e8a7c7 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -1489,7 +1489,7 @@ MERGE_SHA=$(gh pr view --json mergeCommit -q .mergeCommit.oid) git fetch origin "$BASE" git diff --quiet "$MERGE_SHA" origin/"$BASE" || git log --oneline --decorate -1 "$MERGE_SHA" origin/"$BASE" ``` -- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer non-destructive cleanup such as `git switch --detach "$MERGE_SHA"` for throwaway task worktrees. Do not force-push or reset a user's branch unless they explicitly ask. +- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer a named local branch at the merge commit, for example `git switch -c "codex/post-merge-pr-$PR_NUMBER" "$MERGE_SHA"`. Avoid detached HEAD in Codex Desktop worktrees because git action workers often expect `git symbolic-ref --short HEAD` to return a branch. Do not force-push or reset a user's branch unless they explicitly ask. Worktree cleanup — non-destructive, candidate-based: ```bash diff --git a/land-and-deploy/SKILL.md.tmpl b/land-and-deploy/SKILL.md.tmpl index fd2fb5db1..e6b19858b 100644 --- a/land-and-deploy/SKILL.md.tmpl +++ b/land-and-deploy/SKILL.md.tmpl @@ -641,7 +641,7 @@ MERGE_SHA=$(gh pr view --json mergeCommit -q .mergeCommit.oid) git fetch origin "$BASE" git diff --quiet "$MERGE_SHA" origin/"$BASE" || git log --oneline --decorate -1 "$MERGE_SHA" origin/"$BASE" ``` -- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer non-destructive cleanup such as `git switch --detach "$MERGE_SHA"` for throwaway task worktrees. Do not force-push or reset a user's branch unless they explicitly ask. +- If the worktree is clean and only needs to stop looking diverged after a squash merge, prefer a named local branch at the merge commit, for example `git switch -c "codex/post-merge-pr-$PR_NUMBER" "$MERGE_SHA"`. Avoid detached HEAD in Codex Desktop worktrees because git action workers often expect `git symbolic-ref --short HEAD` to return a branch. Do not force-push or reset a user's branch unless they explicitly ask. Worktree cleanup — non-destructive, candidate-based: ```bash