Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLI
AssigneesNone

Relationships

#1634 Add an upstream-state method: status cannot answer whether commits are pushed

Opened by skwump_slruper · 8/13/2026

The type covers working-tree state well but has no way to report tracking-branch state, and the two are easy to confuse in a way that produces false-clean results.

The gap

status returns entries/clean/count, which answers "is the working tree dirty". Nothing in the type answers "are these commits pushed". A repository can be perfectly clean and still hold commits that exist on exactly one machine.

I could not express it with what ships: log takes paths/maxCount/format, diff takes base/head refs, and neither yields ahead/behind against the configured upstream.

Why it matters

I built a fleet check across four clones — "is everything committed and pushed" — on top of status. All four reported clean=true. One of them was carrying an unpushed commit at the time, which an earlier shell version of the same check had correctly found.

So migrating that check from shell to this type would have silently discarded its only true finding, and the run would have gone green. A check that reports success over the defect it was written to catch is worse than no check, and the README framing ("dirty-tree checks via status", "designed for CI automation") makes this an easy trap to walk into.

Suggested shape

A method returning: branch, hasUpstream, upstream, ahead, behind, pushed, synced — with pushed promoted to a tag so it is queryable via CEL without parsing the payload.

Implementation is one call: git rev-list --left-right --count @{u}...HEAD gives behind and ahead together; git rev-parse --abbrev-ref --symbolic-full-name @{u} resolves the upstream and its non-zero exit is the no-upstream signal.

Two semantics worth fixing in the type rather than leaving to each user:

  1. A branch with no upstream should report pushed=false, not vacuously true. Its commits exist on one disk.
  2. ahead and behind should be distinct fields. Collapsing them into one "in sync" boolean loses the case that matters most, which is ahead>0 and behind=0.

Workaround

Extended the type locally via export const extension with an upstreamState method along these lines, which works. Filing because the gap seems general rather than specific to my setup, and because the false-clean failure mode is silent.

One retention note: the shipped result specs are ephemeral with garbageCollection 10. For upstream state specifically, a longer-lived spec is more useful, since "how long has this repository been unpushed" is a question that ephemeral retention destroys.

Upstream repository: https://github.com/swamp-club/swamp-extensions

Environment

  • Extension: @swamp/git@2026.08.07.1
  • swamp: 20260809.004828.0-sha.b61c9de2
  • OS: darwin (x86_64)
  • Deno: 2.8.3
  • Shell: /bin/zsh
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/13/2026, 8:36:26 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.