diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-08-02 08:12:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-02 08:12:44 +0200 |
commit | 9befb514d83e22268d00ab2c0fdd797b3742f0e9 (patch) | |
tree | 923a78009cce4531912b92e1b756a6a8f3ee6d32 | |
parent | 91cdedae7faffca0a707fa47780efafe157ba47c (diff) | |
parent | e5c6fa237776870483cbe227d7f7ea943f35cb12 (diff) | |
download | go-git-9befb514d83e22268d00ab2c0fdd797b3742f0e9.tar.gz |
Merge pull request #501 from smola/config-multiple-urls
config: multiple values in RemoteConfig (URLs and Fetch)
-rw-r--r-- | _examples/remotes/main.go | 2 | ||||
-rw-r--r-- | config/config.go | 51 | ||||
-rw-r--r-- | config/config_test.go | 29 | ||||
-rw-r--r-- | example_test.go | 2 | ||||
-rw-r--r-- | plumbing/format/config/decoder_test.go | 5 | ||||
-rw-r--r-- | plumbing/format/config/fixtures_test.go | 14 | ||||
-rw-r--r-- | plumbing/format/config/option.go | 51 | ||||
-rw-r--r-- | plumbing/format/config/section.go | 27 | ||||
-rw-r--r-- | plumbing/format/config/section_test.go | 19 | ||||
-rw-r--r-- | remote.go | 11 | ||||
-rw-r--r-- | remote_test.go | 55 | ||||
-rw-r--r-- | repository.go | 2 | ||||
-rw-r--r-- | repository_test.go | 14 | ||||
-rw-r--r-- | storage/filesystem/config_test.go | 6 | ||||
-rw-r--r-- | storage/test/storage_suite.go | 2 | ||||
-rw-r--r-- | submodule.go | 2 | ||||
-rw-r--r-- | worktree_test.go | 8 |
17 files changed, 219 insertions, 81 deletions
diff --git a/_examples/remotes/main.go b/_examples/remotes/main.go index 90817dc..7cae8bb 100644 --- a/_examples/remotes/main.go +++ b/_examples/remotes/main.go @@ -27,7 +27,7 @@ func main() { Info("git remote add example https://github.com/git-fixtures/basic.git") _, err = r.CreateRemote(&config.RemoteConfig{ Name: "example", - URL: "https://github.com/git-fixtures/basic.git", + URLs: []string{"https://github.com/git-fixtures/basic.git"}, }) CheckIfError(err) diff --git a/config/config.go b/config/config.go index bcea63e..cb10738 100644 --- a/config/config.go +++ b/config/config.go @@ -159,13 +159,22 @@ func (c *Config) marshalCore() { func (c *Config) marshalRemotes() { s := c.Raw.Section(remoteSection) - s.Subsections = make(format.Subsections, len(c.Remotes)) + newSubsections := make(format.Subsections, 0, len(c.Remotes)) + added := make(map[string]bool) + for _, subsection := range s.Subsections { + if remote, ok := c.Remotes[subsection.Name]; ok { + newSubsections = append(newSubsections, remote.marshal()) + added[subsection.Name] = true + } + } - var i int - for _, r := range c.Remotes { - s.Subsections[i] = r.marshal() - i++ + for name, remote := range c.Remotes { + if !added[name] { + newSubsections = append(newSubsections, remote.marshal()) + } } + + s.Subsections = newSubsections } func (c *Config) marshalSubmodules() { @@ -187,8 +196,9 @@ func (c *Config) marshalSubmodules() { type RemoteConfig struct { // Name of the remote Name string - // URL the URL of a remote repository - URL string + // URLs the URLs of a remote repository. It must be non-empty. Fetch will + // always use the first URL, while push will use all of them. + URLs []string // Fetch the default set of "refspec" for fetch operation Fetch []RefSpec @@ -203,7 +213,7 @@ func (c *RemoteConfig) Validate() error { return ErrRemoteConfigEmptyName } - if c.URL == "" { + if len(c.URLs) == 0 { return ErrRemoteConfigEmptyURL } @@ -233,8 +243,13 @@ func (c *RemoteConfig) unmarshal(s *format.Subsection) error { fetch = append(fetch, rs) } + var urls []string + for _, f := range c.raw.Options.GetAll(urlKey) { + urls = append(urls, f) + } + c.Name = c.raw.Name - c.URL = c.raw.Option(urlKey) + c.URLs = urls c.Fetch = fetch return nil @@ -246,9 +261,21 @@ func (c *RemoteConfig) marshal() *format.Subsection { } c.raw.Name = c.Name - c.raw.SetOption(urlKey, c.URL) - for _, rs := range c.Fetch { - c.raw.SetOption(fetchKey, rs.String()) + if len(c.URLs) == 0 { + c.raw.RemoveOption(urlKey) + } else { + c.raw.SetOption(urlKey, c.URLs...) + } + + if len(c.Fetch) == 0 { + c.raw.RemoveOption(fetchKey) + } else { + var values []string + for _, rs := range c.Fetch { + values = append(values, rs.String()) + } + + c.raw.SetOption(fetchKey, values...) } return c.raw diff --git a/config/config_test.go b/config/config_test.go index cfab36d..97f4bbf 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -13,6 +13,11 @@ func (s *ConfigSuite) TestUnmarshall(c *C) { [remote "origin"] url = git@github.com:mcuadros/go-git.git fetch = +refs/heads/*:refs/remotes/origin/* +[remote "alt"] + url = git@github.com:mcuadros/go-git.git + url = git@github.com:src-d/go-git.git + fetch = +refs/heads/*:refs/remotes/origin/* + fetch = +refs/pull/*:refs/remotes/origin/pull/* [submodule "qux"] path = qux url = https://github.com/foo/qux.git @@ -28,10 +33,13 @@ func (s *ConfigSuite) TestUnmarshall(c *C) { c.Assert(cfg.Core.IsBare, Equals, true) c.Assert(cfg.Core.Worktree, Equals, "foo") - c.Assert(cfg.Remotes, HasLen, 1) + c.Assert(cfg.Remotes, HasLen, 2) c.Assert(cfg.Remotes["origin"].Name, Equals, "origin") - c.Assert(cfg.Remotes["origin"].URL, Equals, "git@github.com:mcuadros/go-git.git") + c.Assert(cfg.Remotes["origin"].URLs, DeepEquals, []string{"git@github.com:mcuadros/go-git.git"}) c.Assert(cfg.Remotes["origin"].Fetch, DeepEquals, []RefSpec{"+refs/heads/*:refs/remotes/origin/*"}) + c.Assert(cfg.Remotes["alt"].Name, Equals, "alt") + c.Assert(cfg.Remotes["alt"].URLs, DeepEquals, []string{"git@github.com:mcuadros/go-git.git", "git@github.com:src-d/go-git.git"}) + c.Assert(cfg.Remotes["alt"].Fetch, DeepEquals, []RefSpec{"+refs/heads/*:refs/remotes/origin/*", "+refs/pull/*:refs/remotes/origin/pull/*"}) c.Assert(cfg.Submodules, HasLen, 1) c.Assert(cfg.Submodules["qux"].Name, Equals, "qux") c.Assert(cfg.Submodules["qux"].URL, Equals, "https://github.com/foo/qux.git") @@ -45,6 +53,11 @@ func (s *ConfigSuite) TestMarshall(c *C) { worktree = bar [remote "origin"] url = git@github.com:mcuadros/go-git.git +[remote "alt"] + url = git@github.com:mcuadros/go-git.git + url = git@github.com:src-d/go-git.git + fetch = +refs/heads/*:refs/remotes/origin/* + fetch = +refs/pull/*:refs/remotes/origin/pull/* [submodule "qux"] url = https://github.com/foo/qux.git `) @@ -54,7 +67,13 @@ func (s *ConfigSuite) TestMarshall(c *C) { cfg.Core.Worktree = "bar" cfg.Remotes["origin"] = &RemoteConfig{ Name: "origin", - URL: "git@github.com:mcuadros/go-git.git", + URLs: []string{"git@github.com:mcuadros/go-git.git"}, + } + + cfg.Remotes["alt"] = &RemoteConfig{ + Name: "alt", + URLs: []string{"git@github.com:mcuadros/go-git.git", "git@github.com:src-d/go-git.git"}, + Fetch: []RefSpec{"+refs/heads/*:refs/remotes/origin/*", "+refs/pull/*:refs/remotes/origin/pull/*"}, } cfg.Submodules["qux"] = &Submodule{ @@ -88,7 +107,7 @@ func (s *ConfigSuite) TestUnmarshallMarshall(c *C) { output, err := cfg.Marshal() c.Assert(err, IsNil) - c.Assert(output, DeepEquals, input) + c.Assert(string(output), DeepEquals, string(input)) } func (s *ConfigSuite) TestValidateInvalidRemote(c *C) { @@ -122,7 +141,7 @@ func (s *ConfigSuite) TestRemoteConfigValidateMissingName(c *C) { } func (s *ConfigSuite) TestRemoteConfigValidateDefault(c *C) { - config := &RemoteConfig{Name: "foo", URL: "http://foo/bar"} + config := &RemoteConfig{Name: "foo", URLs: []string{"http://foo/bar"}} c.Assert(config.Validate(), IsNil) fetch := config.Fetch diff --git a/example_test.go b/example_test.go index 585b38a..1b369ba 100644 --- a/example_test.go +++ b/example_test.go @@ -91,7 +91,7 @@ func ExampleRepository_CreateRemote() { // Add a new remote, with the default fetch refspec _, err := r.CreateRemote(&config.RemoteConfig{ Name: "example", - URL: "https://github.com/git-fixtures/basic.git", + URLs: []string{"https://github.com/git-fixtures/basic.git"}, }) if err != nil { diff --git a/plumbing/format/config/decoder_test.go b/plumbing/format/config/decoder_test.go index 412549f..0a8e92c 100644 --- a/plumbing/format/config/decoder_test.go +++ b/plumbing/format/config/decoder_test.go @@ -17,7 +17,10 @@ func (s *DecoderSuite) TestDecode(c *C) { cfg := &Config{} err := d.Decode(cfg) c.Assert(err, IsNil, Commentf("decoder error for fixture: %d", idx)) - c.Assert(cfg, DeepEquals, fixture.Config, Commentf("bad result for fixture: %d", idx)) + buf := bytes.NewBuffer(nil) + e := NewEncoder(buf) + _ = e.Encode(cfg) + c.Assert(cfg, DeepEquals, fixture.Config, Commentf("bad result for fixture: %d, %s", idx, buf.String())) } } diff --git a/plumbing/format/config/fixtures_test.go b/plumbing/format/config/fixtures_test.go index 12ff288..f3533df 100644 --- a/plumbing/format/config/fixtures_test.go +++ b/plumbing/format/config/fixtures_test.go @@ -87,4 +87,18 @@ var fixtures = []*Fixture{ AddOption("sect1", "subsect1", "opt2", "value2b"). AddOption("sect1", "subsect2", "opt2", "value2"), }, + { + Raw: ` + [sect1] + opt1 = value1 + opt1 = value2 + `, + Text: `[sect1] + opt1 = value1 + opt1 = value2 +`, + Config: New(). + AddOption("sect1", "", "opt1", "value1"). + AddOption("sect1", "", "opt1", "value2"), + }, } diff --git a/plumbing/format/config/option.go b/plumbing/format/config/option.go index 3c391c6..d4775e4 100644 --- a/plumbing/format/config/option.go +++ b/plumbing/format/config/option.go @@ -1,6 +1,7 @@ package config import ( + "fmt" "strings" ) @@ -21,6 +22,15 @@ func (o *Option) IsKey(key string) bool { return strings.ToLower(o.Key) == strings.ToLower(key) } +func (opts Options) GoString() string { + var strs []string + for _, opt := range opts { + strs = append(strs, fmt.Sprintf("%#v", opt)) + } + + return strings.Join(strs, ", ") +} + // Get gets the value for the given key if set, // otherwise it returns the empty string. // @@ -69,16 +79,39 @@ func (opts Options) withAddedOption(key string, value string) Options { return append(opts, &Option{key, value}) } -func (opts Options) withSettedOption(key string, value string) Options { - for i := len(opts) - 1; i >= 0; i-- { - o := opts[i] - if o.IsKey(key) { - result := make(Options, len(opts)) - copy(result, opts) - result[i] = &Option{key, value} - return result +func (opts Options) withSettedOption(key string, values ...string) Options { + var result Options + var added []string + for _, o := range opts { + if !o.IsKey(key) { + result = append(result, o) + continue + } + + if contains(values, o.Value) { + added = append(added, o.Value) + result = append(result, o) + continue + } + } + + for _, value := range values { + if contains(added, value) { + continue + } + + result = result.withAddedOption(key, value) + } + + return result +} + +func contains(haystack []string, needle string) bool { + for _, s := range haystack { + if s == needle { + return true } } - return opts.withAddedOption(key, value) + return false } diff --git a/plumbing/format/config/section.go b/plumbing/format/config/section.go index 547da1e..4a17e3b 100644 --- a/plumbing/format/config/section.go +++ b/plumbing/format/config/section.go @@ -1,6 +1,9 @@ package config -import "strings" +import ( + "fmt" + "strings" +) // Section is the representation of a section inside git configuration files. // Each Section contains Options that are used by both the Git plumbing @@ -36,8 +39,26 @@ type Subsection struct { type Sections []*Section +func (s Sections) GoString() string { + var strs []string + for _, ss := range s { + strs = append(strs, fmt.Sprintf("%#v", ss)) + } + + return strings.Join(strs, ", ") +} + type Subsections []*Subsection +func (s Subsections) GoString() string { + var strs []string + for _, ss := range s { + strs = append(strs, fmt.Sprintf("%#v", ss)) + } + + return strings.Join(strs, ", ") +} + // IsName checks if the name provided is equals to the Section name, case insensitive. func (s *Section) IsName(name string) bool { return strings.ToLower(s.Name) == strings.ToLower(name) @@ -113,8 +134,8 @@ func (s *Subsection) AddOption(key string, value string) *Subsection { // SetOption adds a new Option to the Subsection. If the option already exists, is replaced. // The updated Subsection is returned. -func (s *Subsection) SetOption(key string, value string) *Subsection { - s.Options = s.Options.withSettedOption(key, value) +func (s *Subsection) SetOption(key string, value ...string) *Subsection { + s.Options = s.Options.withSettedOption(key, value...) return s } diff --git a/plumbing/format/config/section_test.go b/plumbing/format/config/section_test.go index cfd9f3f..0290386 100644 --- a/plumbing/format/config/section_test.go +++ b/plumbing/format/config/section_test.go @@ -69,3 +69,22 @@ func (s *SectionSuite) TestSubsection_RemoveOption(c *C) { } c.Assert(sect.RemoveOption("key1"), DeepEquals, expected) } + +func (s *SectionSuite) TestSubsection_SetOption(c *C) { + sect := &Subsection{ + Options: []*Option{ + {Key: "key1", Value: "value1"}, + {Key: "key2", Value: "value2"}, + {Key: "key1", Value: "value3"}, + }, + } + + expected := &Subsection{ + Options: []*Option{ + {Key: "key1", Value: "value1"}, + {Key: "key2", Value: "value2"}, + {Key: "key1", Value: "value4"}, + }, + } + c.Assert(sect.SetOption("key1", "value1", "value4"), DeepEquals, expected) +} @@ -43,8 +43,11 @@ func (r *Remote) Config() *config.RemoteConfig { } func (r *Remote) String() string { - fetch := r.c.URL - push := r.c.URL + var fetch, push string + if len(r.c.URLs) > 0 { + fetch = r.c.URLs[0] + push = r.c.URLs[0] + } return fmt.Sprintf("%s\t%s (fetch)\n%[1]s\t%[3]s (push)", r.c.Name, fetch, push) } @@ -71,7 +74,7 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error { return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name) } - s, err := newSendPackSession(r.c.URL, o.Auth) + s, err := newSendPackSession(r.c.URLs[0], o.Auth) if err != nil { return err } @@ -211,7 +214,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (storer.ReferenceSt o.RefSpecs = r.c.Fetch } - s, err := newUploadPackSession(r.c.URL, o.Auth) + s, err := newUploadPackSession(r.c.URLs[0], o.Auth) if err != nil { return nil, err } diff --git a/remote_test.go b/remote_test.go index ece052a..4953b12 100644 --- a/remote_test.go +++ b/remote_test.go @@ -26,25 +26,25 @@ type RemoteSuite struct { var _ = Suite(&RemoteSuite{}) func (s *RemoteSuite) TestFetchInvalidEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "http://\\"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"http://\\"}}) err := r.Fetch(&FetchOptions{RemoteName: "foo"}) c.Assert(err, ErrorMatches, ".*invalid character.*") } func (s *RemoteSuite) TestFetchNonExistentEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "ssh://non-existent/foo.git"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"ssh://non-existent/foo.git"}}) err := r.Fetch(&FetchOptions{}) c.Assert(err, NotNil) } func (s *RemoteSuite) TestFetchInvalidSchemaEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "qux://foo"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"qux://foo"}}) err := r.Fetch(&FetchOptions{}) c.Assert(err, ErrorMatches, ".*unsupported scheme.*") } func (s *RemoteSuite) TestFetchInvalidFetchOptions(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "qux://foo"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"qux://foo"}}) invalid := config.RefSpec("^*$ñ") err := r.Fetch(&FetchOptions{RefSpecs: []config.RefSpec{invalid}}) c.Assert(err, Equals, config.ErrRefSpecMalformedSeparator) @@ -52,7 +52,7 @@ func (s *RemoteSuite) TestFetchInvalidFetchOptions(c *C) { func (s *RemoteSuite) TestFetchWildcard(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) s.testFetch(c, r, &FetchOptions{ @@ -68,7 +68,7 @@ func (s *RemoteSuite) TestFetchWildcard(c *C) { func (s *RemoteSuite) TestFetchWildcardTags(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()), + URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())}, }) s.testFetch(c, r, &FetchOptions{ @@ -87,7 +87,7 @@ func (s *RemoteSuite) TestFetchWildcardTags(c *C) { func (s *RemoteSuite) TestFetch(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()), + URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())}, }) s.testFetch(c, r, &FetchOptions{ @@ -101,7 +101,7 @@ func (s *RemoteSuite) TestFetch(c *C) { func (s *RemoteSuite) TestFetchContext(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()), + URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())}, }) ctx, cancel := context.WithCancel(context.Background()) @@ -113,12 +113,11 @@ func (s *RemoteSuite) TestFetchContext(c *C) { }, }) c.Assert(err, NotNil) - } func (s *RemoteSuite) TestFetchWithAllTags(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()), + URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())}, }) s.testFetch(c, r, &FetchOptions{ @@ -138,7 +137,7 @@ func (s *RemoteSuite) TestFetchWithAllTags(c *C) { func (s *RemoteSuite) TestFetchWithNoTags(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()), + URLs: []string{s.GetLocalRepositoryURL(fixtures.ByTag("tags").One())}, }) s.testFetch(c, r, &FetchOptions{ @@ -154,7 +153,7 @@ func (s *RemoteSuite) TestFetchWithNoTags(c *C) { func (s *RemoteSuite) TestFetchWithDepth(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) s.testFetch(c, r, &FetchOptions{ @@ -193,7 +192,7 @@ func (s *RemoteSuite) TestFetchWithProgress(c *C) { sto := memory.NewStorage() buf := bytes.NewBuffer(nil) - r := newRemote(sto, &config.RemoteConfig{Name: "foo", URL: url}) + r := newRemote(sto, &config.RemoteConfig{Name: "foo", URLs: []string{url}}) refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*") err := r.Fetch(&FetchOptions{ @@ -229,7 +228,7 @@ func (s *RemoteSuite) TestFetchWithPackfileWriter(c *C) { mock := &mockPackfileWriter{Storer: fss} url := s.GetBasicLocalRepositoryURL() - r := newRemote(mock, &config.RemoteConfig{Name: "foo", URL: url}) + r := newRemote(mock, &config.RemoteConfig{Name: "foo", URLs: []string{url}}) refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*") err = r.Fetch(&FetchOptions{ @@ -258,7 +257,7 @@ func (s *RemoteSuite) TestFetchNoErrAlreadyUpToDate(c *C) { func (s *RemoteSuite) TestFetchNoErrAlreadyUpToDateButStillUpdateLocalRemoteRefs(c *C) { r := newRemote(memory.NewStorage(), &config.RemoteConfig{ - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) o := &FetchOptions{ @@ -294,7 +293,7 @@ func (s *RemoteSuite) TestFetchNoErrAlreadyUpToDateWithNonCommitObjects(c *C) { } func (s *RemoteSuite) doTestFetchNoErrAlreadyUpToDate(c *C, url string) { - r := newRemote(memory.NewStorage(), &config.RemoteConfig{URL: url}) + r := newRemote(memory.NewStorage(), &config.RemoteConfig{URLs: []string{url}}) o := &FetchOptions{ RefSpecs: []config.RefSpec{ @@ -311,7 +310,7 @@ func (s *RemoteSuite) doTestFetchNoErrAlreadyUpToDate(c *C, url string) { func (s *RemoteSuite) TestString(c *C) { r := newRemote(nil, &config.RemoteConfig{ Name: "foo", - URL: "https://github.com/git-fixtures/basic.git", + URLs: []string{"https://github.com/git-fixtures/basic.git"}, }) c.Assert(r.String(), Equals, ""+ @@ -331,7 +330,7 @@ func (s *RemoteSuite) TestPushToEmptyRepository(c *C) { r := newRemote(sto, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: url, + URLs: []string{url}, }) rs := config.RefSpec("refs/heads/*:refs/heads/*") @@ -369,7 +368,7 @@ func (s *RemoteSuite) TestPushContext(c *C) { r := newRemote(sto, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: url, + URLs: []string{url}, }) ctx, cancel := context.WithCancel(context.Background()) @@ -392,7 +391,7 @@ func (s *RemoteSuite) TestPushTags(c *C) { r := newRemote(sto, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: url, + URLs: []string{url}, }) err = r.Push(&PushOptions{ @@ -416,7 +415,7 @@ func (s *RemoteSuite) TestPushNoErrAlreadyUpToDate(c *C) { r := newRemote(sto, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: fs.Root(), + URLs: []string{fs.Root()}, }) err = r.Push(&PushOptions{ @@ -490,7 +489,7 @@ func (s *RemoteSuite) TestPushForce(c *C) { url := dstFs.Root() r := newRemote(sto, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: url, + URLs: []string{url}, }) oldRef, err := dstSto.Reference(plumbing.ReferenceName("refs/heads/branch")) @@ -540,25 +539,25 @@ func (s *RemoteSuite) TestPushNewReference(c *C) { } func (s *RemoteSuite) TestPushInvalidEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "http://\\"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"http://\\"}}) err := r.Push(&PushOptions{RemoteName: "foo"}) c.Assert(err, ErrorMatches, ".*invalid character.*") } func (s *RemoteSuite) TestPushNonExistentEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "ssh://non-existent/foo.git"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"ssh://non-existent/foo.git"}}) err := r.Push(&PushOptions{}) c.Assert(err, NotNil) } func (s *RemoteSuite) TestPushInvalidSchemaEndpoint(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "origin", URL: "qux://foo"}) + r := newRemote(nil, &config.RemoteConfig{Name: "origin", URLs: []string{"qux://foo"}}) err := r.Push(&PushOptions{}) c.Assert(err, ErrorMatches, ".*unsupported scheme.*") } func (s *RemoteSuite) TestPushInvalidFetchOptions(c *C) { - r := newRemote(nil, &config.RemoteConfig{Name: "foo", URL: "qux://foo"}) + r := newRemote(nil, &config.RemoteConfig{Name: "foo", URLs: []string{"qux://foo"}}) invalid := config.RefSpec("^*$ñ") err := r.Push(&PushOptions{RefSpecs: []config.RefSpec{invalid}}) c.Assert(err, Equals, config.ErrRefSpecMalformedSeparator) @@ -567,7 +566,7 @@ func (s *RemoteSuite) TestPushInvalidFetchOptions(c *C) { func (s *RemoteSuite) TestPushInvalidRefSpec(c *C) { r := newRemote(nil, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: "some-url", + URLs: []string{"some-url"}, }) rs := config.RefSpec("^*$**") @@ -580,7 +579,7 @@ func (s *RemoteSuite) TestPushInvalidRefSpec(c *C) { func (s *RemoteSuite) TestPushWrongRemoteName(c *C) { r := newRemote(nil, &config.RemoteConfig{ Name: DefaultRemoteName, - URL: "some-url", + URLs: []string{"some-url"}, }) err := r.Push(&PushOptions{ diff --git a/repository.go b/repository.go index 7f5b793..92174d6 100644 --- a/repository.go +++ b/repository.go @@ -408,7 +408,7 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error { c := &config.RemoteConfig{ Name: o.RemoteName, - URL: o.URL, + URLs: []string{o.URL}, } if _, err := r.CreateRemote(c); err != nil { diff --git a/repository_test.go b/repository_test.go index 558149b..00ce120 100644 --- a/repository_test.go +++ b/repository_test.go @@ -181,7 +181,7 @@ func (s *RepositorySuite) TestCreateRemoteAndRemote(c *C) { r, _ := Init(memory.NewStorage(), nil) remote, err := r.CreateRemote(&config.RemoteConfig{ Name: "foo", - URL: "http://foo/foo.git", + URLs: []string{"http://foo/foo.git"}, }) c.Assert(err, IsNil) @@ -205,7 +205,7 @@ func (s *RepositorySuite) TestDeleteRemote(c *C) { r, _ := Init(memory.NewStorage(), nil) _, err := r.CreateRemote(&config.RemoteConfig{ Name: "foo", - URL: "http://foo/foo.git", + URLs: []string{"http://foo/foo.git"}, }) c.Assert(err, IsNil) @@ -426,7 +426,7 @@ func (s *RepositorySuite) TestFetch(c *C) { r, _ := Init(memory.NewStorage(), nil) _, err := r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) c.Assert(err, IsNil) c.Assert(r.Fetch(&FetchOptions{}), IsNil) @@ -449,7 +449,7 @@ func (s *RepositorySuite) TestFetchContext(c *C) { r, _ := Init(memory.NewStorage(), nil) _, err := r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) c.Assert(err, IsNil) @@ -531,7 +531,7 @@ func (s *RepositorySuite) TestCloneConfig(c *C) { c.Assert(cfg.Core.IsBare, Equals, true) c.Assert(cfg.Remotes, HasLen, 1) c.Assert(cfg.Remotes["origin"].Name, Equals, "origin") - c.Assert(cfg.Remotes["origin"].URL, Not(Equals), "") + c.Assert(cfg.Remotes["origin"].URLs, HasLen, 1) } func (s *RepositorySuite) TestCloneSingleBranchAndNonHEAD(c *C) { @@ -629,7 +629,7 @@ func (s *RepositorySuite) TestPush(c *C) { _, err = s.Repository.CreateRemote(&config.RemoteConfig{ Name: "test", - URL: url, + URLs: []string{url}, }) c.Assert(err, IsNil) @@ -657,7 +657,7 @@ func (s *RepositorySuite) TestPushContext(c *C) { _, err = s.Repository.CreateRemote(&config.RemoteConfig{ Name: "foo", - URL: url, + URLs: []string{url}, }) c.Assert(err, IsNil) diff --git a/storage/filesystem/config_test.go b/storage/filesystem/config_test.go index 1b812e6..4226b33 100644 --- a/storage/filesystem/config_test.go +++ b/storage/filesystem/config_test.go @@ -5,6 +5,7 @@ import ( "os" "github.com/src-d/go-git-fixtures" + "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" . "gopkg.in/check.v1" @@ -39,9 +40,8 @@ func (s *ConfigSuite) TestRemotes(c *C) { c.Assert(remotes, HasLen, 1) remote := remotes["origin"] c.Assert(remote.Name, Equals, "origin") - c.Assert(remote.URL, Equals, "https://github.com/git-fixtures/basic") - c.Assert(remote.Fetch, HasLen, 1) - c.Assert(remote.Fetch[0].String(), Equals, "+refs/heads/*:refs/remotes/origin/*") + c.Assert(remote.URLs, DeepEquals, []string{"https://github.com/git-fixtures/basic"}) + c.Assert(remote.Fetch, DeepEquals, []config.RefSpec{config.RefSpec("+refs/heads/*:refs/remotes/origin/*")}) } func (s *ConfigSuite) TearDownTest(c *C) { diff --git a/storage/test/storage_suite.go b/storage/test/storage_suite.go index 624dc57..bf93515 100644 --- a/storage/test/storage_suite.go +++ b/storage/test/storage_suite.go @@ -351,7 +351,7 @@ func (s *BaseStorageSuite) TestSetConfigAndConfig(c *C) { expected.Core.IsBare = true expected.Remotes["foo"] = &config.RemoteConfig{ Name: "foo", - URL: "http://foo/bar.git", + URLs: []string{"http://foo/bar.git"}, } err := s.Storer.SetConfig(expected) diff --git a/submodule.go b/submodule.go index b5de41f..fd3d173 100644 --- a/submodule.go +++ b/submodule.go @@ -130,7 +130,7 @@ func (s *Submodule) Repository() (*Repository, error) { _, err = r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.c.URL, + URLs: []string{s.c.URL}, }) return r, err diff --git a/worktree_test.go b/worktree_test.go index 10774a4..c14d3bc 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -37,7 +37,7 @@ func (s *WorktreeSuite) TestPullCheckout(c *C) { r, _ := Init(memory.NewStorage(), fs) r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) w, err := r.Worktree() @@ -115,7 +115,7 @@ func (s *WorktreeSuite) TestPullUpdateReferencesIfNeeded(c *C) { r, _ := Init(memory.NewStorage(), memfs.New()) r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) err := r.Fetch(&FetchOptions{}) @@ -173,7 +173,7 @@ func (s *WorktreeSuite) TestPullProgress(c *C) { r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: s.GetBasicLocalRepositoryURL(), + URLs: []string{s.GetBasicLocalRepositoryURL()}, }) w, err := r.Worktree() @@ -198,7 +198,7 @@ func (s *WorktreeSuite) TestPullProgressWithRecursion(c *C) { r, _ := PlainInit(dir, false) r.CreateRemote(&config.RemoteConfig{ Name: DefaultRemoteName, - URL: path, + URLs: []string{path}, }) w, err := r.Worktree() |