aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/branch.go71
-rw-r--r--config/branch_test.go76
-rw-r--r--config/config.go66
-rw-r--r--config/config_test.go76
-rw-r--r--repository.go79
-rw-r--r--repository_test.go146
6 files changed, 507 insertions, 7 deletions
diff --git a/config/branch.go b/config/branch.go
new file mode 100644
index 0000000..e18073c
--- /dev/null
+++ b/config/branch.go
@@ -0,0 +1,71 @@
+package config
+
+import (
+ "errors"
+
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ format "gopkg.in/src-d/go-git.v4/plumbing/format/config"
+)
+
+var (
+ errBranchEmptyName = errors.New("branch config: empty name")
+ errBranchInvalidMerge = errors.New("branch config: invalid merge")
+)
+
+// Branch contains information on the
+// local branches and which remote to track
+type Branch struct {
+ // Name of branch
+ Name string
+ // Remote name of remote to track
+ Remote string
+ // Merge is the local refspec for the branch
+ Merge plumbing.ReferenceName
+
+ raw *format.Subsection
+}
+
+// Validate validates fields of branch
+func (b *Branch) Validate() error {
+ if b.Name == "" {
+ return errBranchEmptyName
+ }
+
+ if b.Merge != "" && !b.Merge.IsBranch() {
+ return errBranchInvalidMerge
+ }
+
+ return nil
+}
+
+func (b *Branch) marshal() *format.Subsection {
+ if b.raw == nil {
+ b.raw = &format.Subsection{}
+ }
+
+ b.raw.Name = b.Name
+
+ if b.Remote == "" {
+ b.raw.RemoveOption(remoteSection)
+ } else {
+ b.raw.SetOption(remoteSection, b.Remote)
+ }
+
+ if b.Merge == "" {
+ b.raw.RemoveOption(mergeKey)
+ } else {
+ b.raw.SetOption(mergeKey, string(b.Merge))
+ }
+
+ return b.raw
+}
+
+func (b *Branch) unmarshal(s *format.Subsection) error {
+ b.raw = s
+
+ b.Name = b.raw.Name
+ b.Remote = b.raw.Options.Get(remoteSection)
+ b.Merge = plumbing.ReferenceName(b.raw.Options.Get(mergeKey))
+
+ return b.Validate()
+}
diff --git a/config/branch_test.go b/config/branch_test.go
new file mode 100644
index 0000000..d74122e
--- /dev/null
+++ b/config/branch_test.go
@@ -0,0 +1,76 @@
+package config
+
+import (
+ . "gopkg.in/check.v1"
+ "gopkg.in/src-d/go-git.v4/plumbing"
+)
+
+type BranchSuite struct{}
+
+var _ = Suite(&BranchSuite{})
+
+func (b *BranchSuite) TestValidateName(c *C) {
+ goodBranch := Branch{
+ Name: "master",
+ Remote: "some_remote",
+ Merge: "refs/heads/master",
+ }
+ badBranch := Branch{
+ Remote: "some_remote",
+ Merge: "refs/heads/master",
+ }
+ c.Assert(goodBranch.Validate(), IsNil)
+ c.Assert(badBranch.Validate(), NotNil)
+}
+
+func (b *BranchSuite) TestValidateMerge(c *C) {
+ goodBranch := Branch{
+ Name: "master",
+ Remote: "some_remote",
+ Merge: "refs/heads/master",
+ }
+ badBranch := Branch{
+ Name: "master",
+ Remote: "some_remote",
+ Merge: "blah",
+ }
+ c.Assert(goodBranch.Validate(), IsNil)
+ c.Assert(badBranch.Validate(), NotNil)
+}
+
+func (b *BranchSuite) TestMarshall(c *C) {
+ expected := []byte(`[core]
+ bare = false
+[branch "branch-tracking-on-clone"]
+ remote = fork
+ merge = refs/heads/branch-tracking-on-clone
+`)
+
+ cfg := NewConfig()
+ cfg.Branches["branch-tracking-on-clone"] = &Branch{
+ Name: "branch-tracking-on-clone",
+ Remote: "fork",
+ Merge: plumbing.ReferenceName("refs/heads/branch-tracking-on-clone"),
+ }
+
+ actual, err := cfg.Marshal()
+ c.Assert(err, IsNil)
+ c.Assert(string(actual), Equals, string(expected))
+}
+
+func (b *BranchSuite) TestUnmarshall(c *C) {
+ input := []byte(`[core]
+ bare = false
+[branch "branch-tracking-on-clone"]
+ remote = fork
+ merge = refs/heads/branch-tracking-on-clone
+`)
+
+ cfg := NewConfig()
+ err := cfg.Unmarshal(input)
+ c.Assert(err, IsNil)
+ branch := cfg.Branches["branch-tracking-on-clone"]
+ c.Assert(branch.Name, Equals, "branch-tracking-on-clone")
+ c.Assert(branch.Remote, Equals, "fork")
+ c.Assert(branch.Merge, Equals, plumbing.ReferenceName("refs/heads/branch-tracking-on-clone"))
+}
diff --git a/config/config.go b/config/config.go
index 87a847d..c730015 100644
--- a/config/config.go
+++ b/config/config.go
@@ -25,7 +25,7 @@ type ConfigStorer interface {
}
var (
- ErrInvalid = errors.New("config invalid remote")
+ ErrInvalid = errors.New("config invalid key in remote or branch")
ErrRemoteConfigNotFound = errors.New("remote config not found")
ErrRemoteConfigEmptyURL = errors.New("remote config: empty URL")
ErrRemoteConfigEmptyName = errors.New("remote config: empty name")
@@ -55,7 +55,9 @@ type Config struct {
// 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
-
+ // Branches list of branches, the key is the branch name and should
+ // equal Branch.Name
+ Branches map[string]*Branch
// Raw contains the raw information of a config file. The main goal is
// preserve the parsed information from the original format, to avoid
// dropping unsupported fields.
@@ -67,6 +69,7 @@ func NewConfig() *Config {
config := &Config{
Remotes: make(map[string]*RemoteConfig),
Submodules: make(map[string]*Submodule),
+ Branches: make(map[string]*Branch),
Raw: format.New(),
}
@@ -87,12 +90,23 @@ func (c *Config) Validate() error {
}
}
+ for name, b := range c.Branches {
+ if b.Name != name {
+ return ErrInvalid
+ }
+
+ if err := b.Validate(); err != nil {
+ return err
+ }
+ }
+
return nil
}
const (
remoteSection = "remote"
submoduleSection = "submodule"
+ branchSection = "branch"
coreSection = "core"
packSection = "pack"
fetchKey = "fetch"
@@ -100,6 +114,7 @@ const (
bareKey = "bare"
worktreeKey = "worktree"
windowKey = "window"
+ mergeKey = "merge"
// DefaultPackWindow holds the number of previous objects used to
// generate deltas. The value 10 is the same used by git command.
@@ -121,6 +136,11 @@ func (c *Config) Unmarshal(b []byte) error {
return err
}
c.unmarshalSubmodules()
+
+ if err := c.unmarshalBranches(); err != nil {
+ return err
+ }
+
return c.unmarshalRemotes()
}
@@ -172,12 +192,27 @@ func (c *Config) unmarshalSubmodules() {
}
}
+func (c *Config) unmarshalBranches() error {
+ bs := c.Raw.Section(branchSection)
+ for _, sub := range bs.Subsections {
+ b := &Branch{}
+
+ if err := b.unmarshal(sub); err != nil {
+ return err
+ }
+
+ c.Branches[b.Name] = b
+ }
+ return nil
+}
+
// Marshal returns Config encoded as a git-config file.
func (c *Config) Marshal() ([]byte, error) {
c.marshalCore()
c.marshalPack()
c.marshalRemotes()
c.marshalSubmodules()
+ c.marshalBranches()
buf := bytes.NewBuffer(nil)
if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
@@ -245,6 +280,33 @@ func (c *Config) marshalSubmodules() {
}
}
+func (c *Config) marshalBranches() {
+ s := c.Raw.Section(branchSection)
+ newSubsections := make(format.Subsections, 0, len(c.Branches))
+ added := make(map[string]bool)
+ for _, subsection := range s.Subsections {
+ if branch, ok := c.Branches[subsection.Name]; ok {
+ newSubsections = append(newSubsections, branch.marshal())
+ added[subsection.Name] = true
+ }
+ }
+
+ branchNames := make([]string, 0, len(c.Branches))
+ for name := range c.Branches {
+ branchNames = append(branchNames, name)
+ }
+
+ sort.Strings(branchNames)
+
+ for _, name := range branchNames {
+ if !added[name] {
+ newSubsections = append(newSubsections, c.Branches[name].marshal())
+ }
+ }
+
+ s.Subsections = newSubsections
+}
+
// 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 1f120c0..5cd713e 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -1,6 +1,9 @@
package config
-import . "gopkg.in/check.v1"
+import (
+ . "gopkg.in/check.v1"
+ "gopkg.in/src-d/go-git.v4/plumbing"
+)
type ConfigSuite struct{}
@@ -47,7 +50,8 @@ func (s *ConfigSuite) TestUnmarshall(c *C) {
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")
-
+ c.Assert(cfg.Branches["master"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["master"].Merge, Equals, plumbing.ReferenceName("refs/heads/master"))
}
func (s *ConfigSuite) TestMarshall(c *C) {
@@ -65,6 +69,9 @@ func (s *ConfigSuite) TestMarshall(c *C) {
url = git@github.com:mcuadros/go-git.git
[submodule "qux"]
url = https://github.com/foo/qux.git
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
`)
cfg := NewConfig()
@@ -87,6 +94,12 @@ func (s *ConfigSuite) TestMarshall(c *C) {
URL: "https://github.com/foo/qux.git",
}
+ cfg.Branches["master"] = &Branch{
+ Name: "master",
+ Remote: "origin",
+ Merge: "refs/heads/master",
+ }
+
b, err := cfg.Marshal()
c.Assert(err, IsNil)
@@ -118,6 +131,29 @@ func (s *ConfigSuite) TestUnmarshallMarshall(c *C) {
c.Assert(string(output), DeepEquals, string(input))
}
+func (s *ConfigSuite) TestValidateConfig(c *C) {
+ config := &Config{
+ Remotes: map[string]*RemoteConfig{
+ "bar": {
+ Name: "bar",
+ URLs: []string{"http://foo/bar"},
+ },
+ },
+ Branches: map[string]*Branch{
+ "bar": {
+ Name: "bar",
+ },
+ "foo": {
+ Name: "foo",
+ Remote: "origin",
+ Merge: plumbing.ReferenceName("refs/heads/foo"),
+ },
+ },
+ }
+
+ c.Assert(config.Validate(), IsNil)
+}
+
func (s *ConfigSuite) TestValidateInvalidRemote(c *C) {
config := &Config{
Remotes: map[string]*RemoteConfig{
@@ -128,7 +164,7 @@ func (s *ConfigSuite) TestValidateInvalidRemote(c *C) {
c.Assert(config.Validate(), Equals, ErrRemoteConfigEmptyURL)
}
-func (s *ConfigSuite) TestValidateInvalidKey(c *C) {
+func (s *ConfigSuite) TestValidateInvalidRemoteKey(c *C) {
config := &Config{
Remotes: map[string]*RemoteConfig{
"bar": {Name: "foo"},
@@ -157,10 +193,44 @@ func (s *ConfigSuite) TestRemoteConfigValidateDefault(c *C) {
c.Assert(fetch[0].String(), Equals, "+refs/heads/*:refs/remotes/foo/*")
}
+func (s *ConfigSuite) TestValidateInvalidBranchKey(c *C) {
+ config := &Config{
+ Branches: map[string]*Branch{
+ "foo": {
+ Name: "bar",
+ Remote: "origin",
+ Merge: plumbing.ReferenceName("refs/heads/bar"),
+ },
+ },
+ }
+
+ c.Assert(config.Validate(), Equals, ErrInvalid)
+}
+
+func (s *ConfigSuite) TestValidateInvalidBranch(c *C) {
+ config := &Config{
+ Branches: map[string]*Branch{
+ "bar": {
+ Name: "bar",
+ Remote: "origin",
+ Merge: plumbing.ReferenceName("refs/heads/bar"),
+ },
+ "foo": {
+ Name: "foo",
+ Remote: "origin",
+ Merge: plumbing.ReferenceName("baz"),
+ },
+ },
+ }
+
+ c.Assert(config.Validate(), Equals, errBranchInvalidMerge)
+}
+
func (s *ConfigSuite) TestRemoteConfigDefaultValues(c *C) {
config := NewConfig()
c.Assert(config.Remotes, HasLen, 0)
+ c.Assert(config.Branches, HasLen, 0)
c.Assert(config.Submodules, HasLen, 0)
c.Assert(config.Raw, NotNil)
c.Assert(config.Pack.Window, Equals, DefaultPackWindow)
diff --git a/repository.go b/repository.go
index 53c545c..35780e2 100644
--- a/repository.go
+++ b/repository.go
@@ -25,11 +25,15 @@ import (
)
var (
+ // ErrBranchExists an error stating the specified branch already exists
+ ErrBranchExists = errors.New("branch already exists")
+ // ErrBranchNotFound an error stating the specified branch does not exist
+ ErrBranchNotFound = errors.New("branch not found")
ErrInvalidReference = errors.New("invalid reference, should be a tag or a branch")
ErrRepositoryNotExists = errors.New("repository does not exist")
ErrRepositoryAlreadyExists = errors.New("repository already exists")
ErrRemoteNotFound = errors.New("remote not found")
- ErrRemoteExists = errors.New("remote already exists ")
+ ErrRemoteExists = errors.New("remote already exists")
ErrWorktreeNotProvided = errors.New("worktree should be provided")
ErrIsBareRepository = errors.New("worktree not available in a bare repository")
ErrUnableToResolveCommit = errors.New("unable to resolve commit")
@@ -428,6 +432,55 @@ func (r *Repository) DeleteRemote(name string) error {
return r.Storer.SetConfig(cfg)
}
+// Branch return a Branch if exists
+func (r *Repository) Branch(name string) (*config.Branch, error) {
+ cfg, err := r.Storer.Config()
+ if err != nil {
+ return nil, err
+ }
+
+ b, ok := cfg.Branches[name]
+ if !ok {
+ return nil, ErrBranchNotFound
+ }
+
+ return b, nil
+}
+
+// CreateBranch creates a new Branch
+func (r *Repository) CreateBranch(c *config.Branch) error {
+ if err := c.Validate(); err != nil {
+ return err
+ }
+
+ cfg, err := r.Storer.Config()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := cfg.Branches[c.Name]; ok {
+ return ErrBranchExists
+ }
+
+ cfg.Branches[c.Name] = c
+ return r.Storer.SetConfig(cfg)
+}
+
+// DeleteBranch delete a Branch from the repository and delete the config
+func (r *Repository) DeleteBranch(name string) error {
+ cfg, err := r.Storer.Config()
+ if err != nil {
+ return err
+ }
+
+ if _, ok := cfg.Branches[name]; !ok {
+ return ErrBranchNotFound
+ }
+
+ delete(cfg.Branches, name)
+ return r.Storer.SetConfig(cfg)
+}
+
func (r *Repository) resolveToCommitHash(h plumbing.Hash) (plumbing.Hash, error) {
obj, err := r.Storer.EncodedObject(plumbing.AnyObject, h)
if err != nil {
@@ -501,7 +554,29 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
}
}
- return r.updateRemoteConfigIfNeeded(o, c, ref)
+ if err := r.updateRemoteConfigIfNeeded(o, c, ref); err != nil {
+ return err
+ }
+
+ if ref.Name().IsBranch() {
+ branchRef := ref.Name()
+ branchName := strings.Split(string(branchRef), "refs/heads/")[1]
+
+ b := &config.Branch{
+ Name: branchName,
+ Merge: branchRef,
+ }
+ if o.RemoteName == "" {
+ b.Remote = "origin"
+ } else {
+ b.Remote = o.RemoteName
+ }
+ if err := r.CreateBranch(b); err != nil {
+ return err
+ }
+ }
+
+ return nil
}
const (
diff --git a/repository_test.go b/repository_test.go
index 4765a53..c98e2ac 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -244,6 +244,119 @@ func (s *RepositorySuite) TestDeleteRemote(c *C) {
c.Assert(alt, IsNil)
}
+func (s *RepositorySuite) TestCreateBranchAndBranch(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err := r.CreateBranch(testBranch)
+
+ c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(len(cfg.Branches), Equals, 1)
+ branch := cfg.Branches["foo"]
+ c.Assert(branch.Name, Equals, testBranch.Name)
+ c.Assert(branch.Remote, Equals, testBranch.Remote)
+ c.Assert(branch.Merge, Equals, testBranch.Merge)
+
+ branch, err = r.Branch("foo")
+ c.Assert(err, IsNil)
+ c.Assert(branch.Name, Equals, testBranch.Name)
+ c.Assert(branch.Remote, Equals, testBranch.Remote)
+ c.Assert(branch.Merge, Equals, testBranch.Merge)
+}
+
+func (s *RepositorySuite) TestCreateBranchUnmarshal(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+
+ expected := []byte(`[core]
+ bare = true
+[remote "foo"]
+ url = http://foo/foo.git
+ fetch = +refs/heads/*:refs/remotes/foo/*
+[branch "foo"]
+ remote = origin
+ merge = refs/heads/foo
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
+`)
+
+ _, err := r.CreateRemote(&config.RemoteConfig{
+ Name: "foo",
+ URLs: []string{"http://foo/foo.git"},
+ })
+ c.Assert(err, IsNil)
+ testBranch1 := &config.Branch{
+ Name: "master",
+ Remote: "origin",
+ Merge: "refs/heads/master",
+ }
+ testBranch2 := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err = r.CreateBranch(testBranch1)
+ err = r.CreateBranch(testBranch2)
+
+ c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ marshaled, err := cfg.Marshal()
+ c.Assert(string(expected), Equals, string(marshaled))
+}
+
+func (s *RepositorySuite) TestBranchInvalid(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ branch, err := r.Branch("foo")
+
+ c.Assert(err, NotNil)
+ c.Assert(branch, IsNil)
+}
+
+func (s *RepositorySuite) TestCreateBranchInvalid(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.CreateBranch(&config.Branch{})
+
+ c.Assert(err, NotNil)
+
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err = r.CreateBranch(testBranch)
+ c.Assert(err, IsNil)
+ err = r.CreateBranch(testBranch)
+ c.Assert(err, NotNil)
+}
+
+func (s *RepositorySuite) TestDeleteBranch(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err := r.CreateBranch(testBranch)
+
+ c.Assert(err, IsNil)
+
+ err = r.DeleteBranch("foo")
+ c.Assert(err, IsNil)
+
+ b, err := r.Branch("foo")
+ c.Assert(err, Equals, ErrBranchNotFound)
+ c.Assert(b, IsNil)
+
+ err = r.DeleteBranch("foo")
+ c.Assert(err, Equals, ErrBranchNotFound)
+}
+
func (s *RepositorySuite) TestPlainInit(c *C) {
dir, err := ioutil.TempDir("", "plain-init")
c.Assert(err, IsNil)
@@ -447,6 +560,10 @@ func (s *RepositorySuite) TestPlainClone(c *C) {
remotes, err := r.Remotes()
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
}
func (s *RepositorySuite) TestPlainCloneContext(c *C) {
@@ -480,6 +597,7 @@ func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {
cfg, err := r.Config()
c.Assert(err, IsNil)
c.Assert(cfg.Remotes, HasLen, 1)
+ c.Assert(cfg.Branches, HasLen, 1)
c.Assert(cfg.Submodules, HasLen, 2)
}
@@ -615,6 +733,8 @@ func (s *RepositorySuite) TestCloneConfig(c *C) {
c.Assert(cfg.Remotes, HasLen, 1)
c.Assert(cfg.Remotes["origin"].Name, Equals, "origin")
c.Assert(cfg.Remotes["origin"].URLs, HasLen, 1)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
}
func (s *RepositorySuite) TestCloneSingleBranchAndNonHEAD(c *C) {
@@ -636,6 +756,13 @@ func (s *RepositorySuite) TestCloneSingleBranchAndNonHEAD(c *C) {
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["branch"].Name, Equals, "branch")
+ c.Assert(cfg.Branches["branch"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["branch"].Merge, Equals, plumbing.ReferenceName("refs/heads/branch"))
+
head, err = r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -672,6 +799,13 @@ func (s *RepositorySuite) TestCloneSingleBranch(c *C) {
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
+ c.Assert(cfg.Branches["master"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["master"].Merge, Equals, plumbing.ReferenceName("refs/heads/master"))
+
head, err = r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -698,6 +832,10 @@ func (s *RepositorySuite) TestCloneDetachedHEAD(c *C) {
})
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -721,6 +859,10 @@ func (s *RepositorySuite) TestCloneDetachedHEADAndShallow(c *C) {
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -742,6 +884,10 @@ func (s *RepositorySuite) TestCloneDetachedHEADAnnotatedTag(c *C) {
})
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)