aboutsummaryrefslogtreecommitdiffstats
path: root/repository.go
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2018-03-14 16:32:48 +0000
committerDaniel Martí <mvdan@mvdan.cc>2018-04-03 16:14:07 +0100
commit5e8e011f6537e6822350a16a243db5802d4151e6 (patch)
tree2c27503469c0e5fb5ae6028819d20df673a2ab76 /repository.go
parent247cf690745dfd67ccd9f0c07878e6dd85e6c9ed (diff)
downloadgo-git-5e8e011f6537e6822350a16a243db5802d4151e6.tar.gz
add PlainOpen variant to find .git in parent dirs
This is the git tool's behavior that people are used to; if one runs a git command in a repository's subdirectory, git still works. Fixes #765. Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Diffstat (limited to 'repository.go')
-rw-r--r--repository.go38
1 files changed, 32 insertions, 6 deletions
diff --git a/repository.go b/repository.go
index 4ea51f5..53c545c 100644
--- a/repository.go
+++ b/repository.go
@@ -225,7 +225,14 @@ 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) {
- dot, wt, err := dotGitToOSFilesystems(path)
+ return PlainOpenWithOptions(path, &PlainOpenOptions{})
+}
+
+// PlainOpen opens a git repository from the given path. It detects if the
+// repository is bare or a normal one. If the path doesn't contain a valid
+// repository ErrRepositoryNotExists is returned
+func PlainOpenWithOptions(path string, o *PlainOpenOptions) (*Repository, error) {
+ dot, wt, err := dotGitToOSFilesystems(path, o.DetectDotGit)
if err != nil {
return nil, err
}
@@ -246,14 +253,33 @@ func PlainOpen(path string) (*Repository, error) {
return Open(s, wt)
}
-func dotGitToOSFilesystems(path string) (dot, wt billy.Filesystem, err error) {
- fs := osfs.New(path)
- fi, err := fs.Stat(".git")
- if err != nil {
+func dotGitToOSFilesystems(path string, detect bool) (dot, wt billy.Filesystem, err error) {
+ if path, err = filepath.Abs(path); err != nil {
+ return nil, nil, err
+ }
+ var fs billy.Filesystem
+ var fi os.FileInfo
+ for {
+ fs = osfs.New(path)
+ fi, err = fs.Stat(".git")
+ if err == nil {
+ // no error; stop
+ break
+ }
if !os.IsNotExist(err) {
+ // unknown error; stop
return nil, nil, err
}
-
+ if detect {
+ // try its parent as long as we haven't reached
+ // the root dir
+ if dir := filepath.Dir(path); dir != path {
+ path = dir
+ continue
+ }
+ }
+ // not detecting via parent dirs and the dir does not exist;
+ // stop
return fs, nil, nil
}