aboutsummaryrefslogtreecommitdiffstats
path: root/repository.go
diff options
context:
space:
mode:
authorSantiago M. Mola <santi@mola.io>2017-04-21 15:00:22 +0200
committerSantiago M. Mola <santi@mola.io>2017-04-27 11:00:51 +0200
commit4060f60af044ce085a097e12bf19cb3fdd123076 (patch)
treeaf10cdadc9adad7a5cb31e05e958d3b9078aec03 /repository.go
parent64cd72debb2a94a49de5ffd3c3a6bfd626df7340 (diff)
downloadgo-git-4060f60af044ce085a097e12bf19cb3fdd123076.tar.gz
add support for .git as file, fixes #348
Diffstat (limited to 'repository.go')
-rw-r--r--repository.go64
1 files changed, 55 insertions, 9 deletions
diff --git a/repository.go b/repository.go
index bb59afe..8a7b348 100644
--- a/repository.go
+++ b/repository.go
@@ -3,8 +3,10 @@ package git
import (
"errors"
"fmt"
+ stdioutil "io/ioutil"
"os"
"path/filepath"
+ "strings"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/internal/revision"
@@ -13,6 +15,7 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
+ "gopkg.in/src-d/go-git.v4/utils/ioutil"
"gopkg.in/src-d/go-billy.v2"
"gopkg.in/src-d/go-billy.v2/osfs"
@@ -193,26 +196,69 @@ func PlainInit(path string, isBare bool) (*Repository, error) {
// repository is bare or a normal one. If the path doesn't contain a valid
// repository ErrRepositoryNotExists is returned
func PlainOpen(path string) (*Repository, error) {
- var wt, dot billy.Filesystem
+ dot, wt, err := dotGitToFilesystems(path)
+ if err != nil {
+ return nil, err
+ }
+
+ s, err := filesystem.NewStorage(dot)
+ if err != nil {
+ return nil, err
+ }
+ return Open(s, wt)
+}
+
+func dotGitToFilesystems(path string) (dot, wt billy.Filesystem, err error) {
fs := osfs.New(path)
- if _, err := fs.Stat(".git"); err != nil {
+ fi, err := fs.Stat(".git")
+ if err != nil {
if !os.IsNotExist(err) {
- return nil, err
+ return nil, nil, err
}
- dot = fs
- } else {
- wt = fs
- dot = fs.Dir(".git")
+ return fs, nil, nil
}
- s, err := filesystem.NewStorage(dot)
+ if fi.IsDir() {
+ return fs.Dir(".git"), fs, nil
+ }
+
+ dot, err = dotGitFileToFilesystem(fs)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return dot, fs, nil
+}
+
+func dotGitFileToFilesystem(fs billy.Filesystem) (billy.Filesystem, error) {
+ var err error
+
+ f, err := fs.Open(".git")
if err != nil {
return nil, err
}
+ defer ioutil.CheckClose(f, &err)
- return Open(s, wt)
+ b, err := stdioutil.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+
+ line := string(b)
+ const prefix = "gitdir: "
+ if !strings.HasPrefix(line, prefix) {
+ return nil, fmt.Errorf(".git file has no %s prefix", prefix)
+ }
+
+ gitdir := line[len(prefix):]
+ gitdir = strings.TrimSpace(gitdir)
+ if filepath.IsAbs(gitdir) {
+ return osfs.New(gitdir), nil
+ }
+
+ return fs.Dir(gitdir), err
}
// PlainClone a repository into the path with the given options, isBare defines