aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--references.go4
-rw-r--r--references_test.go14
-rw-r--r--repository.go56
-rw-r--r--repository_test.go33
4 files changed, 89 insertions, 18 deletions
diff --git a/references.go b/references.go
index a1872a5..5673ac1 100644
--- a/references.go
+++ b/references.go
@@ -47,7 +47,9 @@ func (s commitSorterer) Len() int {
}
func (s commitSorterer) Less(i, j int) bool {
- return s.l[i].Committer.When.Before(s.l[j].Committer.When)
+ return s.l[i].Committer.When.Before(s.l[j].Committer.When) ||
+ s.l[i].Committer.When.Equal(s.l[j].Committer.When) &&
+ s.l[i].Author.When.Before(s.l[j].Author.When)
}
func (s commitSorterer) Swap(i, j int) {
diff --git a/references_test.go b/references_test.go
index cefc7a2..6e75563 100644
--- a/references_test.go
+++ b/references_test.go
@@ -163,7 +163,19 @@ var referencesTests = [...]struct {
"1e14f94bcf82694fdc7e2dcbbfdbbed58db0f4d9",
"1e3d328a2cabda5d0aaddc5dec65271343e0dc37",
}},
-
+ {"https://github.com/spinnaker/spinnaker.git", "f39d86f59a0781f130e8de6b2115329c1fbe9545", "README.adoc", []string{
+ "638f61b3331695f46f1a88095e26dea0f09f176b",
+ "bd42370d3fe8d410e78acb96f81cb3d838ad1c21",
+ "d6905eab6fec1841c7cf8e4484499f5c8d7d423e",
+ "c0a70a0f5aa494f0ae01c55ba191f2325556489a",
+ "811795c8a185e88f5d269195cb68b29c8d0fe170",
+ "d6e6fe0194447cc280f942d6a2e0521b68ea7796",
+ "174bdbf9edfb0ca88415dd4a673852d5b22e7036",
+ "9944d6cf72b8f82d622d85dad7434472bc8f397d",
+ "e805183c72f0426fb073728c01901c2fd2db1da6",
+ "8ef83dd443a05e9122681950399edaa58a38d466",
+ "d73f9cee49a5ad27a42a6e18af7c49a8f28ad8a8",
+ }},
// FAILS
/*
// this contains an empty move
diff --git a/repository.go b/repository.go
index 62e22a6..651425d 100644
--- a/repository.go
+++ b/repository.go
@@ -654,11 +654,12 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
}
ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
- RefSpecs: r.cloneRefSpec(o, c),
- Depth: o.Depth,
- Auth: o.Auth,
- Progress: o.Progress,
- Tags: o.Tags,
+ RefSpecs: r.cloneRefSpec(o, c),
+ Depth: o.Depth,
+ Auth: o.Auth,
+ Progress: o.Progress,
+ Tags: o.Tags,
+ RemoteName: o.RemoteName,
}, o.ReferenceName)
if err != nil {
return err
@@ -1170,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})
@@ -1190,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)))
@@ -1202,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
}
diff --git a/repository_test.go b/repository_test.go
index bf02933..6c8014c 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -568,6 +568,19 @@ func (s *RepositorySuite) TestPlainClone(c *C) {
c.Assert(cfg.Branches["master"].Name, Equals, "master")
}
+func (s *RepositorySuite) TestPlainCloneWithRemoteName(c *C) {
+ r, err := PlainClone(c.MkDir(), false, &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ RemoteName: "test",
+ })
+
+ c.Assert(err, IsNil)
+
+ remote, err := r.Remote("test")
+ c.Assert(err, IsNil)
+ c.Assert(remote, NotNil)
+}
+
func (s *RepositorySuite) TestPlainCloneContext(c *C) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
@@ -2052,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))
}
}