aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2017-02-13 23:59:49 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2017-02-13 23:59:49 +0100
commit65351f835dcaa4b50dd44bce7bf3f2e31582dadc (patch)
treec7c5750ace6769c3e983ef5414d1d7dd7e11f3b0
parentf8b5557875513c5b0aff24bb7b8e28f8f680976f (diff)
downloadgo-git-65351f835dcaa4b50dd44bce7bf3f2e31582dadc.tar.gz
Repository.Init now handles non-standard .git location
-rw-r--r--repository.go70
-rw-r--r--repository_test.go51
-rw-r--r--storage/filesystem/storage.go9
-rw-r--r--storage/filesystem/storage_test.go9
4 files changed, 135 insertions, 4 deletions
diff --git a/repository.go b/repository.go
index 2f5ff82..4c184ab 100644
--- a/repository.go
+++ b/repository.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"os"
+ "path/filepath"
"srcd.works/go-git.v4/config"
"srcd.works/go-git.v4/internal/revision"
@@ -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 {
+ 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 {
+ 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,
@@ -280,7 +347,6 @@ func (r *Repository) clone(o *CloneOptions) error {
}
if err := r.updateWorktree(); err != nil {
- fmt.Println("q", err)
return err
}
diff --git a/repository_test.go b/repository_test.go
index 84a7221..2c1d4a2 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -18,6 +18,7 @@ import (
. "gopkg.in/check.v1"
"srcd.works/go-billy.v1/memfs"
+ "srcd.works/go-billy.v1/osfs"
)
type RepositorySuite struct {
@@ -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)
@@ -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) {
@@ -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) {
diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go
index 27dd07f..9895507 100644
--- a/storage/filesystem/storage.go
+++ b/storage/filesystem/storage.go
@@ -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
@@ -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},
@@ -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
+}
diff --git a/storage/filesystem/storage_test.go b/storage/filesystem/storage_test.go
index e398d22..7300de7 100644
--- a/storage/filesystem/storage_test.go
+++ b/storage/filesystem/storage_test.go
@@ -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"
)
@@ -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)
+}