diff --git a/config/config.go b/config/config.go index 7d6ab5886..8a99e8da9 100644 --- a/config/config.go +++ b/config/config.go @@ -89,6 +89,13 @@ type Config struct { Window uint } + Init struct { + // DefaultBranch Allows overriding the default branch name + // e.g. when initializing a new repository or when cloning + // an empty repository. + DefaultBranch string + } + // Remotes list of repository remotes, the key of the map is the name // of the remote, should equal to RemoteConfig.Name. Remotes map[string]*RemoteConfig @@ -223,6 +230,7 @@ const ( userSection = "user" authorSection = "author" committerSection = "committer" + initSection = "init" fetchKey = "fetch" urlKey = "url" bareKey = "bare" @@ -233,6 +241,7 @@ const ( rebaseKey = "rebase" nameKey = "name" emailKey = "email" + defaultBranchKey = "defaultBranch" // DefaultPackWindow holds the number of previous objects used to // generate deltas. The value 10 is the same used by git command. @@ -251,6 +260,7 @@ func (c *Config) Unmarshal(b []byte) error { c.unmarshalCore() c.unmarshalUser() + c.unmarshalInit() if err := c.unmarshalPack(); err != nil { return err } @@ -344,6 +354,11 @@ func (c *Config) unmarshalBranches() error { return nil } +func (c *Config) unmarshalInit() { + s := c.Raw.Section(initSection) + c.Init.DefaultBranch = s.Options.Get(defaultBranchKey) +} + // Marshal returns Config encoded as a git-config file. func (c *Config) Marshal() ([]byte, error) { c.marshalCore() @@ -352,6 +367,7 @@ func (c *Config) Marshal() ([]byte, error) { c.marshalRemotes() c.marshalSubmodules() c.marshalBranches() + c.marshalInit() buf := bytes.NewBuffer(nil) if err := format.NewEncoder(buf).Encode(c.Raw); err != nil { @@ -475,6 +491,13 @@ func (c *Config) marshalBranches() { s.Subsections = newSubsections } +func (c *Config) marshalInit() { + s := c.Raw.Section(initSection) + if c.Init.DefaultBranch != "" { + s.SetOption(defaultBranchKey, c.Init.DefaultBranch) + } +} + // RemoteConfig contains the configuration for a given remote repository. type RemoteConfig struct { // Name of the remote diff --git a/config/config_test.go b/config/config_test.go index 5a88c191b..8108a94d8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "github.com/go-git/go-git/v5/plumbing" . "gopkg.in/check.v1" @@ -46,6 +47,8 @@ func (s *ConfigSuite) TestUnmarshal(c *C) { [branch "master"] remote = origin merge = refs/heads/master +[init] + defaultBranch = main `) cfg := NewConfig() @@ -77,6 +80,7 @@ func (s *ConfigSuite) TestUnmarshal(c *C) { c.Assert(cfg.Submodules["qux"].Branch, Equals, "bar") c.Assert(cfg.Branches["master"].Remote, Equals, "origin") c.Assert(cfg.Branches["master"].Merge, Equals, plumbing.ReferenceName("refs/heads/master")) + c.Assert(cfg.Init.DefaultBranch, Equals, "main") } func (s *ConfigSuite) TestMarshal(c *C) { @@ -99,12 +103,15 @@ func (s *ConfigSuite) TestMarshal(c *C) { [branch "master"] remote = origin merge = refs/heads/master +[init] + defaultBranch = main `) cfg := NewConfig() cfg.Core.IsBare = true cfg.Core.Worktree = "bar" cfg.Pack.Window = 20 + cfg.Init.DefaultBranch = "main" cfg.Remotes["origin"] = &RemoteConfig{ Name: "origin", URLs: []string{"git@github.com:mcuadros/go-git.git"}, @@ -315,3 +322,29 @@ func (s *ConfigSuite) TestRemoteConfigDefaultValues(c *C) { c.Assert(config.Raw, NotNil) c.Assert(config.Pack.Window, Equals, DefaultPackWindow) } + +func (s *ConfigSuite) TestLoadConfigLocalScope(c *C) { + cfg, err := LoadConfig(LocalScope) + c.Assert(err, NotNil) + c.Assert(cfg, IsNil) +} + +func (s *ConfigSuite) TestRemoveUrlOptions(c *C) { + buf := []byte(` +[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/*`) + + cfg := NewConfig() + err := cfg.Unmarshal(buf) + c.Assert(err, IsNil) + c.Assert(len(cfg.Remotes), Equals, 1) + cfg.Remotes["alt"].URLs = []string{} + + buf, err = cfg.Marshal() + if strings.Contains(string(buf), "url") { + c.Fatal("conifg should not contain any url sections") + } +}