feat(ui): banner above commits when current branch is behind upstream#1014
Merged
Conversation
When origin/main is ahead of local main (or any tracked remote is
ahead of its local), the workstation's history view shows no signal
that upstream work exists. The chip work in 0.52.0 made remote refs
visually distinct WHEN they appear in the row set, but on a behind
branch the upstream-only commits aren't reachable from local HEAD,
so the chips alone never fire.
This PR adds a single-line banner between the panel header and the
first commit row, rendered when the current branch has a non-zero
behind count. Two wording variants:
Behind-only (behind > 0, ahead === 0):
↓ 2 commits behind origin/main · F fetch · U pull
Diverged (behind > 0 && ahead > 0):
↑2 ↓2 diverged from origin/main · F fetch · U pull --rebase
The diverged variant uses the same ↑N ↓N symbols already defined in
formatBranchDivergence for the branches sidebar, and suggests
\`pull --rebase\` because fast-forward pull is impossible when local
has work. Behind-only uses git status's own "N commits behind X"
wording for familiarity.
Color: warning yellow for both variants — same semantic as the
remote-tracking chip kind from 0.52.0. ASCII fallback uses \`v\` for
\`↓\`, \`+N/-N\` for \`↑N ↓N\`, and \`.\` for \`·\` (mirrors the existing
\`formatBranchDivergence\` ASCII pattern).
The banner does NOT:
- change the log row set (no --all expansion)
- auto-fetch (network side effect; surface the affordance, not the
action)
- fire on synced / ahead-only / no-upstream / detached HEAD
Hotkey hints (\`F\`, \`U\`) match existing global workflows in
inkWorkflows.ts. No new keybindings.
12 new tests in iconography.test.ts pin both variants (behind-only +
diverged), the singular/plural noun, the ASCII fallback for each,
and the no-banner cases (undefined branch, no upstream, behind === 0).
985 workstation + log tests pass.
Manual fixture: \`npm run scenario create branch-sync-showcase --
--run-ui\`. The scenario checks out \`main\` which is 2 behind
\`origin/main\` — the banner should render in warning yellow above
the commit list.
Co-pairs with the upcoming branches-sidebar work (task #4) which
will use the same scenario.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a one-line banner to the history view that announces "the remote has work you don't" for the current branch. Fills a real gap: the chip work in 0.52.0 made remote refs visually distinct when they appear in the row set, but on a behind branch the upstream-only commits aren't reachable from local HEAD, so chips alone never signal it.
What it looks like
Behind-only (current branch is N commits behind, no local commits ahead):
Diverged (both ahead AND behind — fast-forward pull is impossible):
Design choices
↓ N commits behind <upstream>git statusfor familiarity↑N ↓N diverged from <upstream>↑N ↓Nsymbols fromformatBranchDivergenceU pull --rebasecurrentBranchrefASCII fallback mirrors
formatBranchDivergence:vfor↓,+N/-Nfor↑N ↓N,.for·, no color.Implementation
formatUpstreamAheadBannerinsrc/workstation/chrome/iconography.ts(~30 LOC). Two variants, plural-correct, ASCII-fallback, returnsundefinedwhen there's nothing to surface.src/workstation/surfaces/history/index.tsinjecting the banner between the panel header and the existing filter indicator. Readscontext.branches.localBranches.find(b => b.current)for the branch ref.FandUhints point at the existingfetch-remotesandpull-current-branchglobal workflows.Tests
12 new in
iconography.test.ts:↑N ↓Nformat,pull --rebasehint, ASCII fallbackTest plan
npm run test:jest -- src/workstation src/commands/log— 985 pass (was 973 + 12 new)npm run lint— clean on touched filesnpm run scenario create branch-sync-showcase -- --run-ui— HEAD is onmainwhich is 2 behindorigin/main. Banner should read↓ 2 commits behind origin/main · F fetch · U pullin warning yellow above the commit list. PressForUand verify the existing workflows fire.git checkout feat/divergedand re-run. Banner should read↑2 ↓2 diverged from origin/feat/diverged · F fetch · U pull --rebase.git checkout feat/syncedand re-run. No banner (synced).Pairs with
branch-sync-showcasev0.3.3) — the fixture this PR is designed against