Merge pull request #706 from antham/resolve-commit-sha1

Resolve full commit sha
diff --git a/repository.go b/repository.go
index 35780e2..928ad9d 100644
--- a/repository.go
+++ b/repository.go
@@ -1021,6 +1021,8 @@
 		case revision.Ref:
 			revisionRef := item.(revision.Ref)
 			var ref *plumbing.Reference
+			var hashCommit, refCommit *object.Commit
+			var rErr, hErr error
 
 			for _, rule := range append([]string{"%s"}, plumbing.RefRevParseRules...) {
 				ref, err = storer.ResolveReference(r.Storer, plumbing.ReferenceName(fmt.Sprintf(rule, revisionRef)))
@@ -1030,14 +1032,27 @@
 				}
 			}
 
-			if ref == nil {
-				return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
+			if ref != nil {
+				refCommit, rErr = r.CommitObject(ref.Hash())
+			} else {
+				rErr = plumbing.ErrReferenceNotFound
 			}
 
-			commit, err = r.CommitObject(ref.Hash())
+			isHash := plumbing.NewHash(string(revisionRef)).String() == string(revisionRef)
 
-			if err != nil {
-				return &plumbing.ZeroHash, err
+			if isHash {
+				hashCommit, hErr = r.CommitObject(plumbing.NewHash(string(revisionRef)))
+			}
+
+			switch {
+			case rErr == nil && !isHash:
+				commit = refCommit
+			case rErr != nil && isHash && hErr == nil:
+				commit = hashCommit
+			case rErr == nil && isHash && hErr == nil:
+				return &plumbing.ZeroHash, fmt.Errorf(`refname "%s" is ambiguous`, revisionRef)
+			default:
+				return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
 			}
 		case revision.CaretPath:
 			depth := item.(revision.CaretPath).Depth
diff --git a/repository_test.go b/repository_test.go
index be7f163..b78fbb7 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -1494,6 +1494,7 @@
 		"branch~1":                   "918c48b83bd081e863dbe1b80f8998f058cd8294",
 		"v1.0.0~1":                   "918c48b83bd081e863dbe1b80f8998f058cd8294",
 		"master~1":                   "918c48b83bd081e863dbe1b80f8998f058cd8294",
+		"918c48b83bd081e863dbe1b80f8998f058cd8294": "918c48b83bd081e863dbe1b80f8998f058cd8294",
 	}
 
 	for rev, hash := range datas {
@@ -1513,10 +1514,19 @@
 	err := r.clone(context.Background(), &CloneOptions{URL: url})
 	c.Assert(err, IsNil)
 
+	headRef, err := r.Head()
+	c.Assert(err, IsNil)
+
+	ref := plumbing.NewHashReference("refs/heads/918c48b83bd081e863dbe1b80f8998f058cd8294", headRef.Hash())
+	err = r.Storer.SetReference(ref)
+	c.Assert(err, IsNil)
+
 	datas := map[string]string{
-		"efs/heads/master~": "reference not found",
-		"HEAD^3":            `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
-		"HEAD^{/whatever}":  `No commit message match regexp : "whatever"`,
+		"efs/heads/master~":                        "reference not found",
+		"HEAD^3":                                   `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
+		"HEAD^{/whatever}":                         `No commit message match regexp : "whatever"`,
+		"4e1243bd22c66e76c2ba9eddc1f91394e57f9f83": "reference not found",
+		"918c48b83bd081e863dbe1b80f8998f058cd8294": `refname "918c48b83bd081e863dbe1b80f8998f058cd8294" is ambiguous`,
 	}
 
 	for rev, rerr := range datas {