aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options.go24
-rw-r--r--remote.go22
-rw-r--r--remote_test.go2
-rw-r--r--repository.go1
-rw-r--r--repository_test.go21
5 files changed, 57 insertions, 13 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/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"),
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{