You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RevParse on an annotated tag returns the tag object's id typed as GitCommitSha, not the commit it points to #234
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.
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.
Activity
matt-edmondson commentedon Oct 17, 2026
Triage
GitRevParseBuilder(RevParse)Tags()reporting tag or tree ids asGitTag.Sha), which is the same peeling problem in a different verb, so consider fixing both together. No open PR covers it. Open PRs Pin --ignore-submodules=none in Status, Diff and Patch [patch] #222/Close revision operands with -- in Log, RevList, Diff and Patch [patch] #223/Mark collapsed untracked and ignored directories in Status() [minor] #226/Keep remote branches whose name ends in /HEAD in Branches() [patch] #229–Add FromFork so GitHub pull requests can be opened from a fork [minor] #231 touch other verbs.Notes: It returns a mistyped id without any error, so commit comparisons silently give the wrong answer. Peeling with
^{commit}makes the method honour itsGitCommitShatype. Note that this changes behaviour for callers who pass tree or blob revisions.Generated by Claude Code