@@ -1171,7 +1171,18 @@ func (r *Repository) Worktree() (*Worktree, error) {
11711171 return & Worktree {r : r , Filesystem : r .wt }, nil
11721172}
11731173
1174- // ResolveRevision resolves revision to corresponding hash.
1174+ func countTrue (vals ... bool ) int {
1175+ sum := 0
1176+ for _ , v := range vals {
1177+ if v {
1178+ sum ++
1179+ }
1180+ }
1181+ return sum
1182+ }
1183+
1184+ // ResolveRevision resolves revision to corresponding hash. It will always
1185+ // resolve to a commit hash, not a tree or annotated tag.
11751186//
11761187// Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch,
11771188// refs/tags/tag, refs/remotes/origin/branch, refs/remotes/origin/HEAD, tilde and caret (HEAD~1, master~^, tag~2, ref/heads/master~1, ...), selection by text (HEAD^{/fix nasty bug})
@@ -1191,8 +1202,8 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
11911202 case revision.Ref :
11921203 revisionRef := item .(revision.Ref )
11931204 var ref * plumbing.Reference
1194- var hashCommit , refCommit * object.Commit
1195- var rErr , hErr error
1205+ var hashCommit , refCommit , tagCommit * object.Commit
1206+ var rErr , hErr , tErr error
11961207
11971208 for _ , rule := range append ([]string {"%s" }, plumbing .RefRevParseRules ... ) {
11981209 ref , err = storer .ResolveReference (r .Storer , plumbing .ReferenceName (fmt .Sprintf (rule , revisionRef )))
@@ -1203,24 +1214,38 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
12031214 }
12041215
12051216 if ref != nil {
1217+ tag , tObjErr := r .TagObject (ref .Hash ())
1218+ if tObjErr != nil {
1219+ tErr = tObjErr
1220+ } else {
1221+ tagCommit , tErr = tag .Commit ()
1222+ }
12061223 refCommit , rErr = r .CommitObject (ref .Hash ())
12071224 } else {
12081225 rErr = plumbing .ErrReferenceNotFound
1226+ tErr = plumbing .ErrReferenceNotFound
12091227 }
12101228
1211- isHash := plumbing .NewHash (string (revisionRef )).String () == string (revisionRef )
1212-
1213- if isHash {
1229+ maybeHash := plumbing .NewHash (string (revisionRef )).String () == string (revisionRef )
1230+ if maybeHash {
12141231 hashCommit , hErr = r .CommitObject (plumbing .NewHash (string (revisionRef )))
1232+ } else {
1233+ hErr = plumbing .ErrReferenceNotFound
12151234 }
12161235
1236+ isTag := tErr == nil
1237+ isCommit := rErr == nil
1238+ isHash := hErr == nil
1239+
12171240 switch {
1218- case rErr == nil && ! isHash :
1241+ case countTrue (isTag , isCommit , isHash ) > 1 :
1242+ return & plumbing .ZeroHash , fmt .Errorf (`refname "%s" is ambiguous` , revisionRef )
1243+ case isTag :
1244+ commit = tagCommit
1245+ case isCommit :
12191246 commit = refCommit
1220- case rErr != nil && isHash && hErr == nil :
1247+ case isHash :
12211248 commit = hashCommit
1222- case rErr == nil && isHash && hErr == nil :
1223- return & plumbing .ZeroHash , fmt .Errorf (`refname "%s" is ambiguous` , revisionRef )
12241249 default :
12251250 return & plumbing .ZeroHash , plumbing .ErrReferenceNotFound
12261251 }
0 commit comments