@@ -484,7 +484,9 @@ func (r *Repository) DeleteBranch(name string) error {
484484 return r .Storer .SetConfig (cfg )
485485}
486486
487- func (r * Repository ) resolveToCommitHash (h plumbing.Hash ) (plumbing.Hash , error ) {
487+ // ResolveToCommitHash takes any arbitrary hash and resolves it to a commit
488+ // hash, if possible.
489+ func (r * Repository ) ResolveToCommitHash (h plumbing.Hash ) (plumbing.Hash , error ) {
488490 obj , err := r .Storer .EncodedObject (plumbing .AnyObject , h )
489491 if err != nil {
490492 return plumbing .ZeroHash , err
@@ -495,7 +497,7 @@ func (r *Repository) resolveToCommitHash(h plumbing.Hash) (plumbing.Hash, error)
495497 if err != nil {
496498 return plumbing .ZeroHash , err
497499 }
498- return r .resolveToCommitHash (t .Target )
500+ return r .ResolveToCommitHash (t .Target )
499501 case plumbing .CommitObject :
500502 return h , nil
501503 default :
@@ -676,7 +678,7 @@ func (r *Repository) updateReferences(spec []config.RefSpec,
676678
677679 if ! resolvedRef .Name ().IsBranch () {
678680 // Detached HEAD mode
679- h , err := r .resolveToCommitHash (resolvedRef .Hash ())
681+ h , err := r .ResolveToCommitHash (resolvedRef .Hash ())
680682 if err != nil {
681683 return false , err
682684 }
@@ -1004,6 +1006,16 @@ func (r *Repository) Worktree() (*Worktree, error) {
10041006 return & Worktree {r : r , Filesystem : r .wt }, nil
10051007}
10061008
1009+ func countTrue (vals ... bool ) int {
1010+ sum := 0
1011+ for _ , v := range vals {
1012+ if v {
1013+ sum ++
1014+ }
1015+ }
1016+ return sum
1017+ }
1018+
10071019// ResolveRevision resolves revision to corresponding hash.
10081020//
10091021// Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch,
@@ -1024,8 +1036,9 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
10241036 case revision.Ref :
10251037 revisionRef := item .(revision.Ref )
10261038 var ref * plumbing.Reference
1039+ var tag * object.Tag
10271040 var hashCommit , refCommit * object.Commit
1028- var rErr , hErr error
1041+ var rErr , hErr , tErr error
10291042
10301043 for _ , rule := range append ([]string {"%s" }, plumbing .RefRevParseRules ... ) {
10311044 ref , err = storer .ResolveReference (r .Storer , plumbing .ReferenceName (fmt .Sprintf (rule , revisionRef )))
@@ -1036,24 +1049,33 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
10361049 }
10371050
10381051 if ref != nil {
1052+ tag , tErr = r .TagObject (ref .Hash ())
10391053 refCommit , rErr = r .CommitObject (ref .Hash ())
10401054 } else {
10411055 rErr = plumbing .ErrReferenceNotFound
1056+ tErr = plumbing .ErrReferenceNotFound
10421057 }
10431058
1044- isHash := plumbing .NewHash (string (revisionRef )).String () == string (revisionRef )
1045-
1046- if isHash {
1059+ maybeHash := plumbing .NewHash (string (revisionRef )).String () == string (revisionRef )
1060+ if maybeHash {
10471061 hashCommit , hErr = r .CommitObject (plumbing .NewHash (string (revisionRef )))
1062+ } else {
1063+ hErr = plumbing .ErrReferenceNotFound
10481064 }
10491065
1066+ isTag := tErr == nil
1067+ isCommit := rErr == nil
1068+ isHash := hErr == nil
1069+
10501070 switch {
1051- case rErr == nil && ! isHash :
1052- commit = refCommit
1053- case rErr != nil && isHash && hErr == nil :
1054- commit = hashCommit
1055- case rErr == nil && isHash && hErr == nil :
1071+ case countTrue (isTag , isCommit , isHash ) > 1 :
10561072 return & plumbing .ZeroHash , fmt .Errorf (`refname "%s" is ambiguous` , revisionRef )
1073+ case isTag :
1074+ return & tag .Hash , nil
1075+ case isCommit :
1076+ return & refCommit .Hash , nil
1077+ case isHash :
1078+ return & hashCommit .Hash , nil
10571079 default :
10581080 return & plumbing .ZeroHash , plumbing .ErrReferenceNotFound
10591081 }
0 commit comments