diff options
-rw-r--r-- | references.go | 4 | ||||
-rw-r--r-- | references_test.go | 14 | ||||
-rw-r--r-- | repository.go | 56 | ||||
-rw-r--r-- | repository_test.go | 33 |
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)) } } |