Skip to content

RevParse on an annotated tag returns the tag object's id typed as GitCommitSha, not the commit it points to #234

Closed

Description

@matt-edmondson

What's wrong

The two parts of RevParse disagree about what it returns:

  • The builder in GitIntegration/Builders/GitRevParseBuilder.cs is declared as IGitCommandBuilder<GitCommitSha>. The v2 design (docs/superpowers/specs/2026-08-19-gitintegration-v2-design.md, around line 352) also says it returns GitCommitSha.
  • The command it runs is git rev-parse --verify --end-of-options <rev>, and the output is parsed straight into a GitCommitSha. rev-parse returns the object that <rev> names, which is not always a commit.

Reproduction (git 2.43)

CreateTag("v1").Annotating("msg")
RevParse("HEAD") -> 08f58d6…   (the commit)
RevParse("v1")   -> 9253098…   (the annotated tag object, not the commit)

HEAD^{tree} and HEAD:path also return a tree or blob id, and it comes back typed as a commit SHA.

Why it matters

Callers get a GitCommitSha that is not a commit, so commit comparisons quietly give the wrong answer:

  • "Is v1 at HEAD?" answers false: RevParse("v1") == RevParse("HEAD") is false even when the tag points at HEAD.
  • "Does this Log() entry match the tag?" also answers false.

The type is what makes this misleading. Nothing fails, so the wrong answer goes unnoticed. Existing tests only call RevParse("HEAD") (GitRoundTripTests.cs, around line 819).

This is related to #148, where Tags() reports a tag or tree id as GitTag.Sha. That bug is in a different verb.

Suggested fix / acceptance criteria

  • Peel the operand to a commit by passing <rev>^{commit}. That makes RevParse honour its GitCommitSha return type: an annotated tag resolves to its commit, and a tree or blob revision fails cleanly instead of returning a mistyped id.
  • Alternative, if raw object lookup is wanted: offer it as a separate, explicitly typed entry point (an object id, not GitCommitSha). Update the doc in GitRepository.cs (around line 198) to match.
  • Add an integration test: after creating an annotated tag at HEAD, RevParse("<tag>") == RevParse("HEAD").
  • Add a test that RevParse("HEAD^{tree}") either throws or is not typed as a commit SHA.

Activity

  1. matt-edmondson commented on Oct 17, 2026

    @matt-edmondson
    ContributorAuthor

    Triage

    Notes: It returns a mistyped id without any error, so commit comparisons silently give the wrong answer. Peeling with ^{commit} makes the method honour its GitCommitSha type. Note that this changes behaviour for callers who pass tree or blob revisions.


    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