From 38b9d5711a0d8156a5b5b1e5dd9972558b1389a7 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Mon, 4 Sep 2017 13:53:55 +0200 Subject: Remote.Fetch Tags logic improvement and fix NoTags --- remote.go | 22 ++++++++++++++++------ remote_test.go | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/remote.go b/remote.go index 1c9d1cd..3e24763 100644 --- a/remote.go +++ b/remote.go @@ -279,7 +279,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (storer.ReferenceSt } } - updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs) + updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, o.Tags) if err != nil { return nil, err } @@ -481,10 +481,17 @@ func getHaves(localRefs storer.ReferenceStorer) ([]plumbing.Hash, error) { return result, nil } -func calculateRefs(spec []config.RefSpec, +const refspecTag = "+refs/tags/*:refs/tags/*" + +func calculateRefs( + spec []config.RefSpec, remoteRefs storer.ReferenceStorer, - tags TagFetchMode, + tagMode TagMode, ) (memory.ReferenceStorage, error) { + if tagMode == AllTags { + spec = append(spec, refspecTag) + } + iter, err := remoteRefs.IterReferences() if err != nil { return nil, err @@ -493,9 +500,7 @@ func calculateRefs(spec []config.RefSpec, refs := make(memory.ReferenceStorage, 0) return refs, iter.ForEach(func(ref *plumbing.Reference) error { if !config.MatchAny(spec, ref.Name()) { - if !ref.Name().IsTag() || tags != AllTags { - return nil - } + return nil } if ref.Type() == plumbing.SymbolicReference { @@ -645,6 +650,7 @@ func buildSidebandIfSupported(l *capability.List, reader io.Reader, p sideband.P func (r *Remote) updateLocalReferenceStorage( specs []config.RefSpec, fetchedRefs, remoteRefs memory.ReferenceStorage, + tagMode TagMode, ) (updated bool, err error) { isWildcard := true for _, spec := range specs { @@ -674,6 +680,10 @@ func (r *Remote) updateLocalReferenceStorage( } } + if tagMode == NoTags { + return updated, nil + } + tags := fetchedRefs if isWildcard { tags = remoteRefs diff --git a/remote_test.go b/remote_test.go index 51180ce..10f6708 100644 --- a/remote_test.go +++ b/remote_test.go @@ -143,7 +143,7 @@ func (s *RemoteSuite) TestFetchWithNoTags(c *C) { s.testFetch(c, r, &FetchOptions{ Tags: NoTags, RefSpecs: []config.RefSpec{ - config.RefSpec("+refs/heads/master:refs/remotes/origin/master"), + config.RefSpec("+refs/heads/*:refs/remotes/origin/*"), }, }, []*plumbing.Reference{ plumbing.NewReferenceFromStrings("refs/remotes/origin/master", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f"), -- cgit From 7cdc44306dd1b3bba4a219bf3c40c5097a505a8e Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Mon, 4 Sep 2017 13:54:02 +0200 Subject: Repository.Clone added Tags option, and set by default AllTags as git does --- options.go | 24 ++++++++++++++++++------ repository.go | 1 + repository_test.go | 21 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/options.go b/options.go index 26002e4..9f10aae 100644 --- a/options.go +++ b/options.go @@ -50,6 +50,9 @@ type CloneOptions struct { // stored, if nil nothing is stored and the capability (if supported) // no-progress, is sent to the server to avoid send this information. Progress sideband.Progress + // Tags describe how the tags will be fetched from the remote repository, + // by default is AllTags. + Tags TagMode } // Validate validates the fields and sets the default values. @@ -66,6 +69,10 @@ func (o *CloneOptions) Validate() error { o.ReferenceName = plumbing.HEAD } + if o.Tags == InvalidTagMode { + o.Tags = AllTags + } + return nil } @@ -103,18 +110,19 @@ func (o *PullOptions) Validate() error { return nil } -type TagFetchMode int +type TagMode int -var ( +const ( + InvalidTagMode TagMode = iota // TagFollowing any tag that points into the histories being fetched is also // fetched. TagFollowing requires a server with `include-tag` capability // in order to fetch the annotated tags objects. - TagFollowing TagFetchMode = 0 + TagFollowing // AllTags fetch all tags from the remote (i.e., fetch remote tags // refs/tags/* into local tags with the same name) - AllTags TagFetchMode = 1 + AllTags //NoTags fetch no tags from the remote at all - NoTags TagFetchMode = 2 + NoTags ) // FetchOptions describes how a fetch should be performed @@ -133,7 +141,7 @@ type FetchOptions struct { Progress sideband.Progress // Tags describe how the tags will be fetched from the remote repository, // by default is TagFollowing. - Tags TagFetchMode + Tags TagMode } // Validate validates the fields and sets the default values. @@ -142,6 +150,10 @@ func (o *FetchOptions) Validate() error { o.RemoteName = DefaultRemoteName } + if o.Tags == InvalidTagMode { + o.Tags = TagFollowing + } + for _, r := range o.RefSpecs { if err := r.Validate(); err != nil { return err diff --git a/repository.go b/repository.go index fbc7871..b86054f 100644 --- a/repository.go +++ b/repository.go @@ -440,6 +440,7 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error { Depth: o.Depth, Auth: o.Auth, Progress: o.Progress, + Tags: o.Tags, }, o.ReferenceName) if err != nil { return err diff --git a/repository_test.go b/repository_test.go index 6184949..4480484 100644 --- a/repository_test.go +++ b/repository_test.go @@ -177,6 +177,27 @@ func (s *RepositorySuite) TestCloneContext(c *C) { c.Assert(err, NotNil) } +func (s *RepositorySuite) TestCloneWithTags(c *C) { + url := s.GetLocalRepositoryURL( + fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(), + ) + + r, err := Clone(memory.NewStorage(), nil, &CloneOptions{URL: url, Tags: NoTags}) + c.Assert(err, IsNil) + + remotes, err := r.Remotes() + c.Assert(err, IsNil) + c.Assert(remotes, HasLen, 1) + + i, err := r.References() + c.Assert(err, IsNil) + + var count int + i.ForEach(func(r *plumbing.Reference) error { count++; return nil }) + + c.Assert(count, Equals, 3) +} + func (s *RepositorySuite) TestCreateRemoteAndRemote(c *C) { r, _ := Init(memory.NewStorage(), nil) remote, err := r.CreateRemote(&config.RemoteConfig{ -- cgit