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
70 changes: 68 additions & 2 deletions repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"

"srcd.works/go-git.v4/config"
"srcd.works/go-git.v4/internal/revision"
Expand Down Expand Up @@ -57,9 +58,75 @@ func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) {

if worktree == nil {
r.setIsBare(true)
return r, nil
}

return r, nil
return r, setWorktreeAndStoragePaths(r, worktree)
}

func setWorktreeAndStoragePaths(r *Repository, worktree billy.Filesystem) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Capitalize tree in the function name.

type fsBased interface {
Filesystem() billy.Filesystem
}

// .git file is only created if the storage is file based and the file
// system is osfs.OS
fs, isFSBased := r.Storer.(fsBased)
if !isFSBased {
return nil
}

_, isOS := fs.Filesystem().(*osfs.OS)
if !isOS {
return nil
}

if err := createDotGitFile(worktree, fs.Filesystem()); err != nil {
return err
}

return setConfigWorktree(r, worktree, fs.Filesystem())
}

func createDotGitFile(worktree, storage billy.Filesystem) error {
path, err := filepath.Rel(worktree.Base(), storage.Base())
if err != nil {
path = storage.Base()
}

if path == ".git" {
// not needed, since the folder is the default place
return nil
}

f, err := worktree.Create(".git")
if err != nil {
return err
}

defer f.Close()
_, err = fmt.Fprintf(f, "gitdir: %s\n", path)
return err
}

func setConfigWorktree(r *Repository, worktree, storage billy.Filesystem) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Capitalize tree in function name.

path, err := filepath.Rel(storage.Base(), worktree.Base())
if err != nil {
path = worktree.Base()
}

if path == ".." {
// not needed, since the folder is the default place
return nil
}

cfg, err := r.Storer.Config()
if err != nil {
return err
}

cfg.Core.Worktree = path
return r.Storer.SetConfig(cfg)
}

// Open opens a git repository using the given Storer and worktree filesystem,
Expand Down Expand Up @@ -280,7 +347,6 @@ func (r *Repository) clone(o *CloneOptions) error {
}

if err := r.updateWorktree(); err != nil {
fmt.Println("q", err)
return err
}

Expand Down
51 changes: 49 additions & 2 deletions repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

. "gopkg.in/check.v1"
"srcd.works/go-billy.v1/memfs"
"srcd.works/go-billy.v1/osfs"
)

type RepositorySuite struct {
Expand All @@ -36,6 +37,52 @@ func (s *RepositorySuite) TestInit(c *C) {
c.Assert(cfg.Core.IsBare, Equals, false)
}

func (s *RepositorySuite) TestInitNonStandardDotGit(c *C) {
dir, err := ioutil.TempDir("", "init-non-standard")
c.Assert(err, IsNil)
c.Assert(os.RemoveAll(dir), IsNil)

fs := osfs.New(dir)
storage, err := filesystem.NewStorage(fs.Dir("storage"))
c.Assert(err, IsNil)

r, err := Init(storage, fs.Dir("worktree"))
c.Assert(err, IsNil)
c.Assert(r, NotNil)

f, err := fs.Open("worktree/.git")
c.Assert(err, IsNil)

all, err := ioutil.ReadAll(f)
c.Assert(err, IsNil)
c.Assert(string(all), Equals, "gitdir: ../storage\n")

cfg, err := r.Config()
c.Assert(err, IsNil)
c.Assert(cfg.Core.Worktree, Equals, "../worktree")
}

func (s *RepositorySuite) TestInitStandardDotGit(c *C) {
dir, err := ioutil.TempDir("", "init-standard")
c.Assert(err, IsNil)
c.Assert(os.RemoveAll(dir), IsNil)

fs := osfs.New(dir)
storage, err := filesystem.NewStorage(fs.Dir(".git"))
c.Assert(err, IsNil)

r, err := Init(storage, fs)
c.Assert(err, IsNil)
c.Assert(r, NotNil)

l, err := fs.ReadDir(".git")
c.Assert(len(l) > 0, Equals, true)

cfg, err := r.Config()
c.Assert(err, IsNil)
c.Assert(cfg.Core.Worktree, Equals, "")
}

func (s *RepositorySuite) TestInitBare(c *C) {
r, err := Init(memory.NewStorage(), nil)
c.Assert(err, IsNil)
Expand Down Expand Up @@ -306,7 +353,7 @@ func (s *RepositorySuite) TestCloneDeep(c *C) {

fi, err := fs.ReadDir("")
c.Assert(err, IsNil)
c.Assert(fi, HasLen, 9)
c.Assert(fi, HasLen, 8)
}

func (s *RepositorySuite) TestCloneConfig(c *C) {
Expand Down Expand Up @@ -431,7 +478,7 @@ func (s *RepositorySuite) TestPullCheckout(c *C) {

fi, err := fs.ReadDir("")
c.Assert(err, IsNil)
c.Assert(fi, HasLen, 9)
c.Assert(fi, HasLen, 8)
}

func (s *RepositorySuite) TestCloneWithProgress(c *C) {
Expand Down
9 changes: 9 additions & 0 deletions storage/filesystem/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
// standard git format (this is, the .git directory). Zero values of this type
// are not safe to use, see the NewStorage function below.
type Storage struct {
fs billy.Filesystem

ObjectStorage
ReferenceStorage
IndexStorage
Expand All @@ -28,6 +30,8 @@ func NewStorage(fs billy.Filesystem) (*Storage, error) {
}

return &Storage{
fs: fs,

ObjectStorage: o,
ReferenceStorage: ReferenceStorage{dir: dir},
IndexStorage: IndexStorage{dir: dir},
Expand All @@ -36,3 +40,8 @@ func NewStorage(fs billy.Filesystem) (*Storage, error) {
ModuleStorage: ModuleStorage{dir: dir},
}, nil
}

// Filesystem returns the underlying filesystem
func (s *Storage) Filesystem() billy.Filesystem {
return s.fs
}
9 changes: 9 additions & 0 deletions storage/filesystem/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"srcd.works/go-git.v4/storage/test"

. "gopkg.in/check.v1"
"srcd.works/go-billy.v1/memfs"
"srcd.works/go-billy.v1/osfs"
)

Expand All @@ -23,3 +24,11 @@ func (s *StorageSuite) SetUpTest(c *C) {

s.BaseStorageSuite = test.NewBaseStorageSuite(storage)
}

func (s *StorageSuite) TestFilesystem(c *C) {
fs := memfs.New()
storage, err := NewStorage(fs)
c.Assert(err, IsNil)

c.Assert(storage.Filesystem(), Equals, fs)
}