Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Submodules init and update #270

Merged
merged 12 commits into from
Feb 21, 2017
5 changes: 3 additions & 2 deletions _examples/clone/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ func main() {
Info("git clone %s %s", url, directory)

r, err := git.PlainClone(directory, false, &git.CloneOptions{
URL: url,
Depth: 1,
URL: url,
RecursiveSubmodules: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change name to imperative: RecurseSubmodules.

Depth: 1,
})

CheckIfError(err)
Expand Down
19 changes: 1 addition & 18 deletions common.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
package git

import (
"strings"

"srcd.works/go-git.v4/config"
"srcd.works/go-git.v4/plumbing/storer"
)

// Storer is a generic storage of objects, references and any information
// related to a particular repository. The package srcd.works/go-git.v4/storage
// contains two implementation a filesystem base implementation (such as `.git`)
// and a memory implementations being ephemeral
type Storer interface {
storer.EncodedObjectStorer
storer.ReferenceStorer
storer.ShallowStorer
storer.IndexStorer
config.ConfigStorer
}
import "strings"

// countLines returns the number of lines in a string à la git, this is
// The newline character is assumed to be '\n'. The empty string
Expand Down
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
// It is highly extensible, we have been following the open/close principle in
// its design to facilitate extensions, mainly focusing the efforts on the
// persistence of the objects.
package git
package git // import "srcd.works/go-git.v4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup

4 changes: 4 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type CloneOptions struct {
SingleBranch bool
// Limit fetching to the specified number of commits
Depth int
// RecursiveSubmodules after the clone is created, initialize all submodules
// within, using their default settings. This option is ignored if the
// cloned repository does not have a worktree
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end the paragraph with a full stop.

RecursiveSubmodules bool
// Progress is where the human readable information sent by the server is
// stored, if nil nothing is stored and the capability (if supported)
// no-progress, is sent to the server to avoid send this information
Expand Down
9 changes: 6 additions & 3 deletions remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"srcd.works/go-git.v4/plumbing/storer"
"srcd.works/go-git.v4/plumbing/transport"
"srcd.works/go-git.v4/plumbing/transport/client"
"srcd.works/go-git.v4/storage"
"srcd.works/go-git.v4/storage/memory"
"srcd.works/go-git.v4/utils/ioutil"
)
Expand All @@ -25,10 +26,10 @@ var NoErrAlreadyUpToDate = errors.New("already up-to-date")
// Remote represents a connection to a remote repository
type Remote struct {
c *config.RemoteConfig
s Storer
s storage.Storer
}

func newRemote(s Storer, c *config.RemoteConfig) *Remote {
func newRemote(s storage.Storer, c *config.RemoteConfig) *Remote {
return &Remote{s: s, c: c}
}

Expand Down Expand Up @@ -321,7 +322,9 @@ func getHaves(localRefs storer.ReferenceStorer) ([]plumbing.Hash, error) {
return haves, nil
}

func getWants(spec []config.RefSpec, localStorer Storer, remoteRefs storer.ReferenceStorer) ([]plumbing.Hash, error) {
func getWants(
spec []config.RefSpec, localStorer storage.Storer, remoteRefs storer.ReferenceStorer,
) ([]plumbing.Hash, error) {
wantTags := true
for _, s := range spec {
if !s.IsWildcard() {
Expand Down
3 changes: 2 additions & 1 deletion remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"srcd.works/go-git.v4/config"
"srcd.works/go-git.v4/plumbing"
"srcd.works/go-git.v4/plumbing/storer"
"srcd.works/go-git.v4/storage"
"srcd.works/go-git.v4/storage/filesystem"
"srcd.works/go-git.v4/storage/memory"

Expand Down Expand Up @@ -126,7 +127,7 @@ func (s *RemoteSuite) TestFetchWithProgress(c *C) {
}

type mockPackfileWriter struct {
Storer
storage.Storer
PackfileWriterCalled bool
}

Expand Down
40 changes: 29 additions & 11 deletions repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"srcd.works/go-git.v4/plumbing"
"srcd.works/go-git.v4/plumbing/object"
"srcd.works/go-git.v4/plumbing/storer"
"srcd.works/go-git.v4/storage"
"srcd.works/go-git.v4/storage/filesystem"

"srcd.works/go-billy.v1"
Expand All @@ -29,7 +30,7 @@ var (

// Repository represents a git repository
type Repository struct {
Storer Storer
Storer storage.Storer

r map[string]*Remote
wt billy.Filesystem
Expand All @@ -38,7 +39,7 @@ type Repository struct {
// Init creates an empty git repository, based on the given Storer and worktree.
// The worktree Filesystem is optional, if nil a bare repository is created. If
// the given storer is not empty ErrRepositoryAlreadyExists is returned
func Init(s Storer, worktree billy.Filesystem) (*Repository, error) {
func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
r := newRepository(s, worktree)
_, err := r.Reference(plumbing.HEAD, false)
switch err {
Expand Down Expand Up @@ -66,7 +67,7 @@ func Init(s Storer, worktree billy.Filesystem) (*Repository, error) {
// The worktree can be nil when the repository being opened is bare, if the
// repository is a normal one (not bare) and worktree is nil the err
// ErrWorktreeNotProvided is returned
func Open(s Storer, worktree billy.Filesystem) (*Repository, error) {
func Open(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
_, err := s.Reference(plumbing.HEAD)
if err == plumbing.ErrReferenceNotFound {
return nil, ErrRepositoryNotExists
Expand All @@ -91,7 +92,7 @@ func Open(s Storer, worktree billy.Filesystem) (*Repository, error) {
// Clone a repository into the given Storer and worktree Filesystem with the
// given options, if worktree is nil a bare repository is created. If the given
// storer is not empty ErrRepositoryAlreadyExists is returned
func Clone(s Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error) {
func Clone(s storage.Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error) {
r, err := Init(s, worktree)
if err != nil {
return nil, err
Expand Down Expand Up @@ -159,7 +160,7 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)
return r, r.clone(o)
}

func newRepository(s Storer, worktree billy.Filesystem) *Repository {
func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {
return &Repository{
Storer: s,
wt: worktree,
Expand Down Expand Up @@ -247,12 +248,6 @@ func (r *Repository) clone(o *CloneOptions) error {
return err
}

// marks the repository as bare in the config, until we have Worktree, all
// the repository are bare
if err := r.setIsBare(true); err != nil {
return err
}

c := &config.RemoteConfig{
Name: o.RemoteName,
URL: o.URL,
Expand All @@ -270,11 +265,13 @@ func (r *Repository) clone(o *CloneOptions) error {
Progress: o.Progress,
})
if err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line.

return err
}

head, err := storer.ResolveReference(remoteRefs, o.ReferenceName)
if err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line.

return err
}

Expand All @@ -283,12 +280,33 @@ func (r *Repository) clone(o *CloneOptions) error {
}

if err := r.updateWorktree(); err != nil {
fmt.Println("q", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover?

return err
}

if o.RecursiveSubmodules && r.wt != nil {
if err := r.initSubmodules(); err != nil {
return err
}
}

return r.updateRemoteConfig(remote, o, c, head)
}

func (r *Repository) initSubmodules() error {
w, err := r.Worktree()
if err != nil {
return err
}

s, err := w.Submodules()
if err != nil {
return err
}

return s.Init()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have a recursive flag, so the init can be done recursively?

}

func (r *Repository) cloneRefSpec(o *CloneOptions,
c *config.RemoteConfig) []config.RefSpec {

Expand Down
18 changes: 4 additions & 14 deletions repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,26 +516,21 @@ func (s *RepositorySuite) TestPullProgress(c *C) {
}

func (s *RepositorySuite) TestPullAdd(c *C) {
path := fixtures.Basic().One().Worktree().Base()
path := fixtures.Basic().ByTag("worktree").One().Worktree().Base()

r, _ := Init(memory.NewStorage(), nil)
err := r.clone(&CloneOptions{
r, err := Clone(memory.NewStorage(), nil, &CloneOptions{
URL: fmt.Sprintf("file://%s", filepath.Join(path, ".git")),
})

c.Assert(err, IsNil)

storage := r.Storer.(*memory.Storage)
c.Assert(storage.Objects, HasLen, 31)
c.Assert(storage.Objects, HasLen, 28)

branch, err := r.Reference("refs/heads/master", false)
c.Assert(err, IsNil)
c.Assert(branch.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")

branch, err = r.Reference("refs/remotes/origin/branch", false)
c.Assert(err, IsNil)
c.Assert(branch.Hash().String(), Equals, "e8d3ffab552895c19b9fcf7aa264d277cde33881")

ExecuteOnPath(c, path,
"touch foo",
"git add foo",
Expand All @@ -546,16 +541,11 @@ func (s *RepositorySuite) TestPullAdd(c *C) {
c.Assert(err, IsNil)

// the commit command has introduced a new commit, tree and blob
c.Assert(storage.Objects, HasLen, 34)
c.Assert(storage.Objects, HasLen, 31)

branch, err = r.Reference("refs/heads/master", false)
c.Assert(err, IsNil)
c.Assert(branch.Hash().String(), Not(Equals), "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")

// the commit command, was in the local branch, so the remote should be read ok
branch, err = r.Reference("refs/remotes/origin/branch", false)
c.Assert(err, IsNil)
c.Assert(branch.Hash().String(), Equals, "e8d3ffab552895c19b9fcf7aa264d277cde33881")
}

func (s *RepositorySuite) TestPushToEmptyRepository(c *C) {
Expand Down
13 changes: 9 additions & 4 deletions storage/filesystem/internal/dotgit/dotgit.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ const (
configPath = "config"
indexPath = "index"
shallowPath = "shallow"

objectsPath = "objects"
packPath = "pack"
refsPath = "refs"
modulePath = "module"
objectsPath = "objects"
packPath = "pack"
refsPath = "refs"

packExt = ".pack"
idxExt = ".idx"
Expand Down Expand Up @@ -390,6 +390,11 @@ func (d *DotGit) readReferenceFile(refsPath, refFile string) (ref *plumbing.Refe
return plumbing.NewReferenceFromStrings(refFile, line), nil
}

// Module return a billy.Filesystem poiting to the module folder
func (d *DotGit) Module(name string) billy.Filesystem {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return d.fs.Dir(d.fs.Join(modulePath, name))
}

func isHex(s string) bool {
for _, b := range []byte(s) {
if isNum(b) {
Expand Down
14 changes: 14 additions & 0 deletions storage/filesystem/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package filesystem

import (
"srcd.works/go-git.v4/storage"
"srcd.works/go-git.v4/storage/filesystem/internal/dotgit"
)

type ModuleStorage struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this type?, can we just make dotgit implement storage.ModuleStorer instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the pattern we are using. I prefer keep dotgit isolate

dir *dotgit.DotGit
}

func (s *ModuleStorage) Module(name string) (storage.Storer, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests and comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is already covered by the tests. And the documentation is on the interface as in the other methods

return NewStorage(s.dir.Module(name))
}
2 changes: 2 additions & 0 deletions storage/filesystem/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Storage struct {
IndexStorage
ShallowStorage
ConfigStorage
ModuleStorage
}

// NewStorage returns a new Storage backed by a given `fs.Filesystem`
Expand All @@ -32,5 +33,6 @@ func NewStorage(fs billy.Filesystem) (*Storage, error) {
IndexStorage: IndexStorage{dir: dir},
ShallowStorage: ShallowStorage{dir: dir},
ConfigStorage: ConfigStorage{dir: dir},
ModuleStorage: ModuleStorage{dir: dir},
}, nil
}
13 changes: 13 additions & 0 deletions storage/memory/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"srcd.works/go-git.v4/plumbing"
"srcd.works/go-git.v4/plumbing/format/index"
"srcd.works/go-git.v4/plumbing/storer"
"srcd.works/go-git.v4/storage"
)

var ErrUnsupportedObjectType = fmt.Errorf("unsupported object type")
Expand All @@ -22,6 +23,7 @@ type Storage struct {
ShallowStorage
IndexStorage
ReferenceStorage
ModuleStorage
}

// NewStorage returns a new Storage base on memory
Expand All @@ -37,6 +39,7 @@ func NewStorage() *Storage {
Blobs: make(map[plumbing.Hash]plumbing.EncodedObject, 0),
Tags: make(map[plumbing.Hash]plumbing.EncodedObject, 0),
},
ModuleStorage: make(ModuleStorage, 0),
}
}

Expand Down Expand Up @@ -227,3 +230,13 @@ func (s *ShallowStorage) SetShallow(commits []plumbing.Hash) error {
func (s ShallowStorage) Shallow() ([]plumbing.Hash, error) {
return s, nil
}

type ModuleStorage map[string]*Storage

func (s ModuleStorage) Module(name string) (storage.Storer, error) {
if _, ok := s[name]; !ok {
s[name] = NewStorage()
}

return s[name], nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't look up twice in the map, use a variable to store the results of the first lookup.

}
23 changes: 23 additions & 0 deletions storage/storer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package storage

import (
"srcd.works/go-git.v4/config"
"srcd.works/go-git.v4/plumbing/storer"
)

// Storer is a generic storage of objects, references and any information
// related to a particular repository. The package srcd.works/go-git.v4/storage
// contains two implementation a filesystem base implementation (such as `.git`)
// and a memory implementations being ephemeral
type Storer interface {
storer.EncodedObjectStorer
storer.ReferenceStorer
storer.ShallowStorer
storer.IndexStorer
config.ConfigStorer
ModuleStorer
}

type ModuleStorer interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be explained, What if the module doesn't exists?

Module(name string) (Storer, error)
}
Loading