ResolveRevision resolves revision to corresponding hash. It will always resolve to a commit hash, not a tree or annotated tag. Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch, refs/tags/tag, refs/remotes/origin/branch, refs/remotes/origin/HEAD, tilde and caret (HEAD~1, ma
(in plumbing.Revision)
| 1567 | // Implemented resolvers : HEAD, branch, tag, heads/branch, refs/heads/branch, |
| 1568 | // 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}), hash (prefix and full) |
| 1569 | func (r *Repository) ResolveRevision(in plumbing.Revision) (*plumbing.Hash, error) { |
| 1570 | rev := in.String() |
| 1571 | if rev == "" { |
| 1572 | return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound |
| 1573 | } |
| 1574 | |
| 1575 | p := revision.NewParserFromString(rev) |
| 1576 | items, err := p.Parse() |
| 1577 | |
| 1578 | if err != nil { |
| 1579 | return nil, err |
| 1580 | } |
| 1581 | |
| 1582 | var commit *object.Commit |
| 1583 | |
| 1584 | for _, item := range items { |
| 1585 | switch item := item.(type) { |
| 1586 | case revision.Ref: |
| 1587 | revisionRef := item |
| 1588 | |
| 1589 | var tryHashes []plumbing.Hash |
| 1590 | |
| 1591 | tryHashes = append(tryHashes, r.resolveHashPrefix(string(revisionRef))...) |
| 1592 | |
| 1593 | ref, err := expand_ref(r.Storer, plumbing.ReferenceName(revisionRef)) |
| 1594 | if err == nil { |
| 1595 | tryHashes = append(tryHashes, ref.Hash()) |
| 1596 | } |
| 1597 | |
| 1598 | // in ambiguous cases, `git rev-parse` will emit a warning, but |
| 1599 | // will always return the oid in preference to a ref; we don't have |
| 1600 | // the ability to emit a warning here, so (for speed purposes) |
| 1601 | // don't bother to detect the ambiguity either, just return in the |
| 1602 | // priority that git would. |
| 1603 | gotOne := false |
| 1604 | for _, hash := range tryHashes { |
| 1605 | commitObj, err := r.CommitObject(hash) |
| 1606 | if err == nil { |
| 1607 | commit = commitObj |
| 1608 | gotOne = true |
| 1609 | break |
| 1610 | } |
| 1611 | |
| 1612 | tagObj, err := r.TagObject(hash) |
| 1613 | if err == nil { |
| 1614 | // If the tag target lookup fails here, this most likely |
| 1615 | // represents some sort of repo corruption, so let the |
| 1616 | // error bubble up. |
| 1617 | tagCommit, err := tagObj.Commit() |
| 1618 | if err != nil { |
| 1619 | return &plumbing.ZeroHash, err |
| 1620 | } |
| 1621 | commit = tagCommit |
| 1622 | gotOne = true |
| 1623 | break |
| 1624 | } |
| 1625 | } |
| 1626 |