aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantiago M. Mola <santi@mola.io>2017-05-31 09:02:01 +0200
committerSantiago M. Mola <santi@mola.io>2017-06-01 18:02:26 +0200
commit88f88ea4cf5d44065edda8b06c2267a9dccea16e (patch)
treed940fd22f0110274c221ebd22391bc8716cc66bc
parent87d2475dd70169bbcb49a70d79ca6cfdff492c38 (diff)
downloadgo-git-88f88ea4cf5d44065edda8b06c2267a9dccea16e.tar.gz
storage/filesystem: call initialization explicitely, fixes #408
filesystem.Storage was initializing the gitdir (creating objects and refs) on NewStorage. But this should be done only on init and clone operations, not on open. Now there is a new interface storer.Initializer that storers can implement if they need any initialization step before init or clone. filesystem.Storage is one of such implementations. git.Init and git.Clone now call to the storer Init() method if it does implement it. Otherwise, it just ignores initialization.
-rw-r--r--plumbing/storer/storer.go8
-rw-r--r--repository.go13
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go2
-rw-r--r--storage/filesystem/storage.go10
-rw-r--r--storage/filesystem/storage_test.go19
5 files changed, 37 insertions, 15 deletions
diff --git a/plumbing/storer/storer.go b/plumbing/storer/storer.go
index 0b96c0e..863070d 100644
--- a/plumbing/storer/storer.go
+++ b/plumbing/storer/storer.go
@@ -5,3 +5,11 @@ type Storer interface {
EncodedObjectStorer
ReferenceStorer
}
+
+// Initializer should be implemented by storers that require to perform any
+// operation when creating a new repository (i.e. git init).
+type Initializer interface{
+ // Init performs initialization of the storer and returns the error, if
+ // any.
+ Init() error
+}
diff --git a/repository.go b/repository.go
index 76be660..35aae52 100644
--- a/repository.go
+++ b/repository.go
@@ -44,6 +44,10 @@ type Repository struct {
// 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 storage.Storer, worktree billy.Filesystem) (*Repository, error) {
+ if err := initStorer(s); err != nil {
+ return nil, err
+ }
+
r := newRepository(s, worktree)
_, err := r.Reference(plumbing.HEAD, false)
switch err {
@@ -67,6 +71,15 @@ func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {
return r, setWorktreeAndStoragePaths(r, worktree)
}
+func initStorer(s storer.Storer) error {
+ i, ok := s.(storer.Initializer)
+ if !ok {
+ return nil
+ }
+
+ return i.Init()
+}
+
func setWorktreeAndStoragePaths(r *Repository, worktree billy.Filesystem) error {
type fsBased interface {
Filesystem() billy.Filesystem
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go
index f9f4d79..1af64ab 100644
--- a/storage/filesystem/internal/dotgit/dotgit.go
+++ b/storage/filesystem/internal/dotgit/dotgit.go
@@ -231,7 +231,7 @@ func (d *DotGit) Objects() ([]plumbing.Hash, error) {
return objects, nil
}
-// Object return a fs.File poiting the object file, if exists
+// Object return a fs.File pointing the object file, if exists
func (d *DotGit) Object(h plumbing.Hash) (billy.File, error) {
hash := h.String()
file := d.fs.Join(objectsPath, hash[0:2], hash[2:40])
diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go
index dcb061d..af340d7 100644
--- a/storage/filesystem/storage.go
+++ b/storage/filesystem/storage.go
@@ -12,6 +12,7 @@ import (
// are not safe to use, see the NewStorage function below.
type Storage struct {
fs billy.Filesystem
+ dir *dotgit.DotGit
ObjectStorage
ReferenceStorage
@@ -24,10 +25,6 @@ type Storage struct {
// NewStorage returns a new Storage backed by a given `fs.Filesystem`
func NewStorage(fs billy.Filesystem) (*Storage, error) {
dir := dotgit.New(fs)
- if err := dir.Initialize(); err != nil {
- return nil, err
- }
-
o, err := newObjectStorage(dir)
if err != nil {
return nil, err
@@ -35,6 +32,7 @@ func NewStorage(fs billy.Filesystem) (*Storage, error) {
return &Storage{
fs: fs,
+ dir: dir,
ObjectStorage: o,
ReferenceStorage: ReferenceStorage{dir: dir},
@@ -49,3 +47,7 @@ func NewStorage(fs billy.Filesystem) (*Storage, error) {
func (s *Storage) Filesystem() billy.Filesystem {
return s.fs
}
+
+func (s *Storage) Init() error {
+ return s.dir.Initialize()
+}
diff --git a/storage/filesystem/storage_test.go b/storage/filesystem/storage_test.go
index 0127489..03d2e86 100644
--- a/storage/filesystem/storage_test.go
+++ b/storage/filesystem/storage_test.go
@@ -1,6 +1,7 @@
package filesystem
import (
+ "io/ioutil"
"testing"
"gopkg.in/src-d/go-git.v4/storage/test"
@@ -14,31 +15,29 @@ func Test(t *testing.T) { TestingT(t) }
type StorageSuite struct {
test.BaseStorageSuite
+ dir string
}
var _ = Suite(&StorageSuite{})
func (s *StorageSuite) SetUpTest(c *C) {
- storage, err := NewStorage(osfs.New(c.MkDir()))
+ s.dir = c.MkDir()
+ storage, err := NewStorage(osfs.New(s.dir))
c.Assert(err, IsNil)
s.BaseStorageSuite = test.NewBaseStorageSuite(storage)
}
-func (s *StorageSuite) TestNewStorage(c *C) {
+func (s *StorageSuite) TestFilesystem(c *C) {
fs := memfs.New()
storage, err := NewStorage(fs)
c.Assert(err, IsNil)
- c.Assert(storage, NotNil)
- _, err = fs.Stat("refs/tags")
- c.Assert(err, IsNil)
+ c.Assert(storage.Filesystem(), Equals, fs)
}
-func (s *StorageSuite) TestFilesystem(c *C) {
- fs := memfs.New()
- storage, err := NewStorage(fs)
+func (s *StorageSuite) TestNewStorageShouldNotAddAnyContentsToDir(c *C) {
+ fis, err := ioutil.ReadDir(s.dir)
c.Assert(err, IsNil)
-
- c.Assert(storage.Filesystem(), Equals, fs)
+ c.Assert(fis, HasLen, 0)
}