refactor(staged): derive PR push button state from git upstream relation#743
refactor(staged): derive PR push button state from git upstream relation#743matt2e wants to merge 2 commits into
Conversation
Replaces the SHA comparison in BranchCardPrButton with a small helper that reads timeline.gitState.upstream.relation, so cases like originAhead no longer misclassify as "needs push". Falls back to HEAD/PR SHA comparison only when upstream is missing (fork PRs). After a successful push, trigger a git-state refresh instead of mutating prHeadSha optimistically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
When a different branch is checked out (expectedBranchMatches === false), `upstream.relation` is computed against HEAD's upstream (e.g. main vs origin/main) and `headSha` belongs to the wrong branch — so the missing- upstream SHA fallback in shouldShowPushChanges would almost certainly surface a spurious "needs push". Return false early in that case. Also adds a default arm with an exhaustiveness assertion so future additions to UpstreamRelation produce a compile-time error instead of silently falling through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28935ca17a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| commands.refreshBranchGitState(branch.id).catch((e) => { | ||
| console.warn('[Staged] Failed to refresh git state after push:', e); | ||
| }); |
There was a problem hiding this comment.
Force-refresh git state after push completion
After a successful push, this now relies on refreshBranchGitState to flip hasUnpushed back to false, but that command is TTL-gated (FetchMode::Ttl, 30s) and can skip fetching if a refresh ran recently. Because git push does not update refs/remotes/origin/<branch> locally, skipping fetch leaves upstream.relation as localAhead, so the UI can keep showing "Push changes" even though the push succeeded. This is reproducible when the user pushes shortly after any prior git-state refresh.
Useful? React with 👍 / 👎.
Summary
latestCommit.sha !== prHeadShaheuristic inBranchCardPrButtonwith a newshouldShowPushChangeshelper that readstimeline.gitState.upstream.relation(localAhead/diverged=> show,inSync/originAhead=> hide).origin/<branch>ref), and bail out entirely when a different branch is checked out so we don't compare unrelated SHAs.prHeadSha, lettingupstream.relationsettle back toinSyncon its own.Test plan
pnpm test prButtonGitState(or equivalent vitest run) passes