@@ -1171,7 +1171,18 @@ func (r *Repository) Worktree() (*Worktree, error) {
1171
1171
return & Worktree {r : r , Filesystem : r .wt }, nil
1172
1172
}
1173
1173
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.
1175
1186
//
1176
1187
// Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch,
1177
1188
// 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
1191
1202
case revision.Ref :
1192
1203
revisionRef := item .(revision.Ref )
1193
1204
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
1196
1207
1197
1208
for _ , rule := range append ([]string {"%s" }, plumbing .RefRevParseRules ... ) {
1198
1209
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
1203
1214
}
1204
1215
1205
1216
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
+ }
1206
1223
refCommit , rErr = r .CommitObject (ref .Hash ())
1207
1224
} else {
1208
1225
rErr = plumbing .ErrReferenceNotFound
1226
+ tErr = plumbing .ErrReferenceNotFound
1209
1227
}
1210
1228
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 {
1214
1231
hashCommit , hErr = r .CommitObject (plumbing .NewHash (string (revisionRef )))
1232
+ } else {
1233
+ hErr = plumbing .ErrReferenceNotFound
1215
1234
}
1216
1235
1236
+ isTag := tErr == nil
1237
+ isCommit := rErr == nil
1238
+ isHash := hErr == nil
1239
+
1217
1240
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 :
1219
1246
commit = refCommit
1220
- case rErr != nil && isHash && hErr == nil :
1247
+ case isHash :
1221
1248
commit = hashCommit
1222
- case rErr == nil && isHash && hErr == nil :
1223
- return & plumbing .ZeroHash , fmt .Errorf (`refname "%s" is ambiguous` , revisionRef )
1224
1249
default :
1225
1250
return & plumbing .ZeroHash , plumbing .ErrReferenceNotFound
1226
1251
}
0 commit comments