Skip to content

Commit

Permalink
Merge pull request src-d#830 from novas0x2a/annotated
Browse files Browse the repository at this point in the history
Teach ResolveRevision how to look up annotated tags
  • Loading branch information
mcuadros authored Oct 15, 2018
2 parents 345ffd9 + 323d084 commit 8153e04
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 11 deletions.
45 changes: 35 additions & 10 deletions repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,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 @@ -1191,8 +1202,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 @@ -1203,24 +1214,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
20 changes: 19 additions & 1 deletion repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2065,7 +2065,25 @@ 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))
}
}

func (s *RepositorySuite) TestResolveRevisionAnnotated(c *C) {
f := fixtures.ByURL("https://github.com/git-fixtures/tags.git").One()
sto := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
r, err := Open(sto, f.DotGit())
c.Assert(err, IsNil)

datas := map[string]string{
"refs/tags/annotated-tag": "f7b877701fbf855b44c0a9e86f3fdce2c298b07f",
}

for rev, hash := range datas {
h, err := r.ResolveRevision(plumbing.Revision(rev))

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

Expand Down

0 comments on commit 8153e04

Please sign in to comment.