Desktop branch chip stays on "Create PR" with a full diff count after a squash merge (merge-base detection can't see squash merges)
Summary
After a branch is pushed and its PR is squash-merged, the desktop branch chip keeps showing the unmerged state — the "Create PR" button plus a full diff count — instead of switching to the merged appearance. The branch is fully merged and the working tree has nothing left to push.
This is the bug half of #59984 (closed NOT_PLANNED, filed as an enhancement bundled with a separate custom-/pr-skill request), refiled as a bug with a root cause. Same family as #57128 (stale rows in the Create PR panel).
Environment
- Claude Code 2.1.224, desktop app on macOS 26.5.2 (Darwin 25.5.0)
- Session running in a git worktree
- Repo default merge strategy: squash
What the chip shows
job-toolkit 8.8.26-caregiver-downstream-positioning +2,306 −12 [Create PR ▾]
Actual repo state at that moment
$ git status --short # (empty — clean)
$ git log --oneline origin/<branch>..HEAD | wc -l
0 # nothing unpushed
$ gh pr view 260 --json state,mergeCommit
state=MERGED sha=3b086ba # squash-merged onto main
Root cause
The +2,306 −12 figure is exactly the three-dot (merge-base) diff against origin/main:
$ git diff --shortstat origin/main...HEAD
12 files changed, 2306 insertions(+), 12 deletions(-) # ← matches the chip exactly
$ git diff --shortstat origin/main..HEAD # two-dot, for contrast
8 files changed, 40 insertions(+), 386 deletions(-)
The merge-base is still the pre-merge main:
$ git merge-base origin/main HEAD
ce56cb97accdc700180f892181535de643290a51 # main as it was BEFORE the squash merge
That is the expected consequence of a squash merge: the squash commit (3b086ba) is a brand-new single commit whose parent is old-main, so none of the branch's commits become ancestors of main. Any "is this branch merged?" test based on ancestry or merge-base therefore answers no, forever, for every squash-merged branch — and the chip renders the entire branch as outstanding work.
git branch --merged has the same blind spot, so this likely affects any detection path built on it.
Suggested fix
Two detection strategies that survive a squash merge:
- Ask GitHub. The branch has an associated PR whose state is
MERGED;gh pr view --json state,mergeCommit(or the equivalent API call) is authoritative regardless of merge strategy. This also covers rebase merges. - Compare content, not ancestry.
git cherry <upstream> <branch>marks patch-equivalent commits with-. Worth noting it did not rescue this case — it reported0equivalent and12unmerged, because squashing 12 commits into 1 changes every patch id. So content-equivalence would need to compare trees (e.g.git diff --quiet origin/main HEAD -- <paths>) rather than per-commit patch ids. Strategy 1 is the more reliable one.
A cheap interim improvement: if an associated PR exists at all, the button should read "View PR" rather than "Create PR", which is the ask in #59984 (1).
Possible confounder, stated honestly
The PR here was created and merged with the gh CLI, not through the chip's own "Create PR" flow. So an alternative explanation is that the UI only tracks PRs it created itself, and never learned about this one. I can't distinguish the two from outside the app. However, the diff figure is provably merge-base-derived (it matches git diff origin/main...HEAD to the digit), so at minimum the diff-count half of the chip is computed in a way that squash merges defeat.
Expected behavior
Once the branch's PR is merged, the chip should show its merged state rather than offering to create a PR and reporting thousands of lines of pending changes.