Skip to content

Status() reports Ahead = 0, Behind = 0 when the upstream branch is gone, so unpushed commits look in sync #177

Closed

Description

@matt-edmondson

What's wrong

GitStatusParser only sets ahead and behind when it reads a # branch.ab header, and both default to 0 (GitIntegration/Parsing/GitStatusParser.cs:130-136). GitStatus.Ahead and GitStatus.Behind are plain int, and nothing records that the upstream is missing (GitIntegration/Models/GitStatus.cs:22-28).

Porcelain v2 prints # branch.upstream origin/feat but leaves out # branch.ab entirely when the configured upstream ref does not exist. That happens when:

  • the remote branch was deleted after a merge, or
  • the upstream was configured but never fetched.

Failure scenario (reproduced with git 2.43)

  1. Push branch feat with -u, then make one more local commit.
  2. Run git push origin --delete feat.
  3. git status --porcelain=v2 --branch prints # branch.oid …, # branch.head feat, # branch.upstream origin/feat, and no branch.ab line. (git status -sb shows [gone].)
  4. Status() returns Upstream = origin/feat, Ahead = 0, Behind = 0.

A caller that checks Upstream != null && Ahead == 0 concludes there is nothing to push. It may then discard the branch or worktree and lose the unpushed commit. That is exactly the "is it safe to throw this away" question the library is meant to answer.

Suggested fix

Either:

  • make Ahead/Behind int?, null when branch.upstream is present without branch.ab; or
  • add bool IsUpstreamGone (true when branch.upstream is present without branch.ab), and document that Ahead/Behind are meaningless while it is true.

Acceptance criteria

  • A parser test covers headers with branch.upstream and no branch.ab.
  • An integration test deletes the remote branch and asserts that the gone state is reported, not 0/0.

Activity

  1. matt-edmondson commented on Oct 6, 2026

    @matt-edmondson
    ContributorAuthor

    Triage

    • Category: Bug
    • Priority: High. When the upstream branch is gone, a branch with unpushed commits reports 0/0, which looks "safe to discard". Callers that clean up branches or worktrees from this signal can lose work.
    • Area / suggested owner: Status parsing (Parsing/GitStatusParser.cs, Models/GitStatus.cs). The fix may change the public API if Ahead/Behind become nullable.
    • Duplicates / in progress: Not a duplicate. No open PR covers it.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions