Skip to content

Commit

Permalink
Teach ResolveRevision how to look up annotated tags
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Lundy <[email protected]>
  • Loading branch information
novas0x2a committed May 11, 2018
1 parent e63b032 commit 5dd9376
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
45 changes: 35 additions & 10 deletions repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,18 @@ func (r *Repository) Worktree() (*Worktree, error) {
return &Worktree{r: r, Filesystem: r.wt}, nil
}

// ResolveRevision resolves revision to corresponding hash.
func countTrue(vals ...bool) int {
sum := 0
for _, v := range vals {
if v {
sum++
}
}
return sum
}

// 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, master~^, tag~2, ref/heads/master~1, ...), selection by text (HEAD^{/fix nasty bug})
Expand All @@ -1024,8 +1035,8 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
case revision.Ref:
revisionRef := item.(revision.Ref)
var ref *plumbing.Reference
var hashCommit, refCommit *object.Commit
var rErr, hErr error
var hashCommit, refCommit, tagCommit *object.Commit
var rErr, hErr, tErr error

for _, rule := range append([]string{"%s"}, plumbing.RefRevParseRules...) {
ref, err = storer.ResolveReference(r.Storer, plumbing.ReferenceName(fmt.Sprintf(rule, revisionRef)))
Expand All @@ -1036,24 +1047,38 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err
}

if ref != nil {
tag, tObjErr := r.TagObject(ref.Hash())
if tObjErr != nil {
tErr = tObjErr
} else {
tagCommit, tErr = tag.Commit()
}
refCommit, rErr = r.CommitObject(ref.Hash())
} else {
rErr = plumbing.ErrReferenceNotFound
tErr = plumbing.ErrReferenceNotFound
}

isHash := plumbing.NewHash(string(revisionRef)).String() == string(revisionRef)

if isHash {
maybeHash := plumbing.NewHash(string(revisionRef)).String() == string(revisionRef)
if maybeHash {
hashCommit, hErr = r.CommitObject(plumbing.NewHash(string(revisionRef)))
} else {
hErr = plumbing.ErrReferenceNotFound
}

isTag := tErr == nil
isCommit := rErr == nil
isHash := hErr == nil

switch {
case rErr == nil && !isHash:
case countTrue(isTag, isCommit, isHash) > 1:
return &plumbing.ZeroHash, fmt.Errorf(`refname "%s" is ambiguous`, revisionRef)
case isTag:
commit = tagCommit
case isCommit:
commit = refCommit
case rErr != nil && isHash && hErr == nil:
case isHash:
commit = hashCommit
case rErr == nil && isHash && hErr == nil:
return &plumbing.ZeroHash, fmt.Errorf(`refname "%s" is ambiguous`, revisionRef)
default:
return &plumbing.ZeroHash, plumbing.ErrReferenceNotFound
}
Expand Down
2 changes: 1 addition & 1 deletion repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ func (s *RepositorySuite) TestResolveRevision(c *C) {
h, err := r.ResolveRevision(plumbing.Revision(rev))

c.Assert(err, IsNil)
c.Assert(h.String(), Equals, hash)
c.Check(h.String(), Equals, hash, Commentf("while checking %s", rev))
}
}

Expand Down

0 comments on commit 5dd9376

Please sign in to comment.