aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/config.go73
-rw-r--r--config/config_test.go41
-rw-r--r--config/modules.go19
-rw-r--r--config/refspec.go12
4 files changed, 113 insertions, 32 deletions
diff --git a/config/config.go b/config/config.go
index 866ae8e..259ebf9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -32,14 +32,19 @@ var (
// Config contains the repository configuration
// ftp://www.kernel.org/pub/software/scm/git/docs/git-config.html#FILES
type Config struct {
- // Core variables
Core struct {
// IsBare if true this repository is assumed to be bare and has no
- // working directory associated with it
+ // working directory associated with it.
IsBare bool
+ // Worktree is the path to the root of the working tree.
+ Worktree string
}
- // Remote list of repository remotes
+ // 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
+ // Submodules list of repository submodules, the key of the map is the name
+ // of the submodule, should equal to Submodule.Name.
+ Submodules map[string]*Submodule
// contains the raw information of a config file, the main goal is preserve
// the parsed information from the original format, to avoid missing
@@ -47,15 +52,16 @@ type Config struct {
raw *format.Config
}
-// NewConfig returns a new empty Config
+// NewConfig returns a new empty Config.
func NewConfig() *Config {
return &Config{
- Remotes: make(map[string]*RemoteConfig, 0),
- raw: format.New(),
+ Remotes: make(map[string]*RemoteConfig, 0),
+ Submodules: make(map[string]*Submodule, 0),
+ raw: format.New(),
}
}
-// Validate validates the fields and sets the default values
+// Validate validates the fields and sets the default values.
func (c *Config) Validate() error {
for name, r := range c.Remotes {
if r.Name != name {
@@ -71,14 +77,16 @@ func (c *Config) Validate() error {
}
const (
- remoteSection = "remote"
- coreSection = "core"
- fetchKey = "fetch"
- urlKey = "url"
- bareKey = "bare"
+ remoteSection = "remote"
+ submoduleSection = "submodule"
+ coreSection = "core"
+ fetchKey = "fetch"
+ urlKey = "url"
+ bareKey = "bare"
+ worktreeKey = "worktree"
)
-// Unmarshal parses a git-config file and stores it
+// Unmarshal parses a git-config file and stores it.
func (c *Config) Unmarshal(b []byte) error {
r := bytes.NewBuffer(b)
d := format.NewDecoder(r)
@@ -89,6 +97,7 @@ func (c *Config) Unmarshal(b []byte) error {
}
c.unmarshalCore()
+ c.unmarshalSubmodules()
return c.unmarshalRemotes()
}
@@ -97,6 +106,8 @@ func (c *Config) unmarshalCore() {
if s.Options.Get(bareKey) == "true" {
c.Core.IsBare = true
}
+
+ c.Core.Worktree = s.Options.Get(worktreeKey)
}
func (c *Config) unmarshalRemotes() error {
@@ -113,10 +124,21 @@ func (c *Config) unmarshalRemotes() error {
return nil
}
-// Marshal returns Config encoded as a git-config file
+func (c *Config) unmarshalSubmodules() {
+ s := c.raw.Section(submoduleSection)
+ for _, sub := range s.Subsections {
+ m := &Submodule{}
+ m.unmarshal(sub)
+
+ c.Submodules[m.Name] = m
+ }
+}
+
+// Marshal returns Config encoded as a git-config file.
func (c *Config) Marshal() ([]byte, error) {
c.marshalCore()
c.marshalRemotes()
+ c.marshalSubmodules()
buf := bytes.NewBuffer(nil)
if err := format.NewEncoder(buf).Encode(c.raw); err != nil {
@@ -129,6 +151,10 @@ func (c *Config) Marshal() ([]byte, error) {
func (c *Config) marshalCore() {
s := c.raw.Section(coreSection)
s.SetOption(bareKey, fmt.Sprintf("%t", c.Core.IsBare))
+
+ if c.Core.Worktree != "" {
+ s.SetOption(worktreeKey, c.Core.Worktree)
+ }
}
func (c *Config) marshalRemotes() {
@@ -142,7 +168,22 @@ func (c *Config) marshalRemotes() {
}
}
-// RemoteConfig contains the configuration for a given remote repository
+func (c *Config) marshalSubmodules() {
+ s := c.raw.Section(submoduleSection)
+ s.Subsections = make(format.Subsections, len(c.Submodules))
+
+ var i int
+ for _, r := range c.Submodules {
+ section := r.marshal()
+ // the submodule section at config is a subset of the .gitmodule file
+ // we should remove the non-valid options for the config file.
+ section.RemoveOption(pathKey)
+ s.Subsections[i] = section
+ i++
+ }
+}
+
+// RemoteConfig contains the configuration for a given remote repository.
type RemoteConfig struct {
// Name of the remote
Name string
@@ -156,7 +197,7 @@ type RemoteConfig struct {
raw *format.Subsection
}
-// Validate validates the fields and sets the default values
+// Validate validates the fields and sets the default values.
func (c *RemoteConfig) Validate() error {
if c.Name == "" {
return ErrRemoteConfigEmptyName
diff --git a/config/config_test.go b/config/config_test.go
index 2bcefe4..cfab36d 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -9,9 +9,14 @@ var _ = Suite(&ConfigSuite{})
func (s *ConfigSuite) TestUnmarshall(c *C) {
input := []byte(`[core]
bare = true
+ worktree = foo
[remote "origin"]
url = git@github.com:mcuadros/go-git.git
fetch = +refs/heads/*:refs/remotes/origin/*
+[submodule "qux"]
+ path = qux
+ url = https://github.com/foo/qux.git
+ branch = bar
[branch "master"]
remote = origin
merge = refs/heads/master
@@ -22,15 +27,51 @@ func (s *ConfigSuite) TestUnmarshall(c *C) {
c.Assert(err, IsNil)
c.Assert(cfg.Core.IsBare, Equals, true)
+ c.Assert(cfg.Core.Worktree, Equals, "foo")
c.Assert(cfg.Remotes, HasLen, 1)
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"].Fetch, DeepEquals, []RefSpec{"+refs/heads/*:refs/remotes/origin/*"})
+ 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")
+ c.Assert(cfg.Submodules["qux"].Branch, Equals, "bar")
+
+}
+
+func (s *ConfigSuite) TestMarshall(c *C) {
+ output := []byte(`[core]
+ bare = true
+ worktree = bar
+[remote "origin"]
+ url = git@github.com:mcuadros/go-git.git
+[submodule "qux"]
+ url = https://github.com/foo/qux.git
+`)
+
+ cfg := NewConfig()
+ cfg.Core.IsBare = true
+ cfg.Core.Worktree = "bar"
+ cfg.Remotes["origin"] = &RemoteConfig{
+ Name: "origin",
+ URL: "git@github.com:mcuadros/go-git.git",
+ }
+
+ cfg.Submodules["qux"] = &Submodule{
+ Name: "qux",
+ URL: "https://github.com/foo/qux.git",
+ }
+
+ b, err := cfg.Marshal()
+ c.Assert(err, IsNil)
+
+ c.Assert(string(b), Equals, string(output))
}
func (s *ConfigSuite) TestUnmarshallMarshall(c *C) {
input := []byte(`[core]
bare = true
+ worktree = foo
custom = ignored
[remote "origin"]
url = git@github.com:mcuadros/go-git.git
diff --git a/config/modules.go b/config/modules.go
index 4d98b16..3d01117 100644
--- a/config/modules.go
+++ b/config/modules.go
@@ -15,7 +15,7 @@ var (
// Modules defines the submodules properties, represents a .gitmodules file
// https://www.kernel.org/pub/software/scm/git/docs/gitmodules.html
type Modules struct {
- // Submodules is a map of submodules being the key the name of the submodule
+ // Submodules is a map of submodules being the key the name of the submodule.
Submodules map[string]*Submodule
raw *format.Config
@@ -30,12 +30,11 @@ func NewModules() *Modules {
}
const (
- submoduleSection = "submodule"
- pathKey = "path"
- branchKey = "branch"
+ pathKey = "path"
+ branchKey = "branch"
)
-// Unmarshal parses a git-config file and stores it
+// Unmarshal parses a git-config file and stores it.
func (m *Modules) Unmarshal(b []byte) error {
r := bytes.NewBuffer(b)
d := format.NewDecoder(r)
@@ -56,7 +55,7 @@ func (m *Modules) Unmarshal(b []byte) error {
return nil
}
-// Marshal returns Modules encoded as a git-config file
+// Marshal returns Modules encoded as a git-config file.
func (m *Modules) Marshal() ([]byte, error) {
s := m.raw.Section(submoduleSection)
s.Subsections = make(format.Subsections, len(m.Submodules))
@@ -75,12 +74,12 @@ func (m *Modules) Marshal() ([]byte, error) {
return buf.Bytes(), nil
}
-// Submodule defines a submodule
+// Submodule defines a submodule.
type Submodule struct {
// Name module name
Name string
// Path defines the path, relative to the top-level directory of the Git
- // working tree,
+ // working tree.
Path string
// URL defines a URL from which the submodule repository can be cloned.
URL string
@@ -89,11 +88,11 @@ type Submodule struct {
Branch string
// raw representation of the subsection, filled by marshal or unmarshal are
- // called
+ // called.
raw *format.Subsection
}
-// Validate validates the fields and sets the default values
+// Validate validates the fields and sets the default values.
func (m *Submodule) Validate() error {
if m.Path == "" {
return ErrModuleEmptyPath
diff --git a/config/refspec.go b/config/refspec.go
index dd68edc..9441df8 100644
--- a/config/refspec.go
+++ b/config/refspec.go
@@ -49,7 +49,7 @@ func (s RefSpec) Validate() error {
return ErrRefSpecMalformedWildcard
}
-// IsForceUpdate returns if update is allowed in non fast-forward merges
+// IsForceUpdate returns if update is allowed in non fast-forward merges.
func (s RefSpec) IsForceUpdate() bool {
if s[0] == refSpecForce[0] {
return true
@@ -67,7 +67,7 @@ func (s RefSpec) IsDelete() bool {
return false
}
-// Src return the src side
+// Src return the src side.
func (s RefSpec) Src() string {
spec := string(s)
start := strings.Index(spec, refSpecForce) + 1
@@ -76,7 +76,7 @@ func (s RefSpec) Src() string {
return spec[start:end]
}
-// Match match the given plumbing.ReferenceName against the source
+// Match match the given plumbing.ReferenceName against the source.
func (s RefSpec) Match(n plumbing.ReferenceName) bool {
if !s.IsWildcard() {
return s.matchExact(n)
@@ -85,7 +85,7 @@ func (s RefSpec) Match(n plumbing.ReferenceName) bool {
return s.matchGlob(n)
}
-// IsWildcard returns true if the RefSpec contains a wildcard
+// IsWildcard returns true if the RefSpec contains a wildcard.
func (s RefSpec) IsWildcard() bool {
return strings.Index(string(s), refSpecWildcard) != -1
}
@@ -110,7 +110,7 @@ func (s RefSpec) matchGlob(n plumbing.ReferenceName) bool {
strings.HasSuffix(name, suffix)
}
-// Dst returns the destination for the given remote reference
+// Dst returns the destination for the given remote reference.
func (s RefSpec) Dst(n plumbing.ReferenceName) plumbing.ReferenceName {
spec := string(s)
start := strings.Index(spec, refSpecSeparator) + 1
@@ -133,7 +133,7 @@ func (s RefSpec) String() string {
return string(s)
}
-// MatchAny returns true if any of the RefSpec match with the given ReferenceName
+// MatchAny returns true if any of the RefSpec match with the given ReferenceName.
func MatchAny(l []RefSpec, n plumbing.ReferenceName) bool {
for _, r := range l {
if r.Match(n) {