diff --git a/config/config.go b/config/config.go index 5d2cc0ad..61bf87d7 100644 --- a/config/config.go +++ b/config/config.go @@ -6,14 +6,18 @@ import ( "fmt" "os" "path/filepath" + "strings" "sync" + "github.com/git-lfs/git-lfs/fs" "github.com/git-lfs/git-lfs/git" "github.com/git-lfs/git-lfs/tools" + "github.com/rubyist/tracerx" ) var ( ShowConfigWarnings = false + LocalReferenceDir string // alternative local media dir (relative to clone reference repo) defaultRemote = "origin" gitConfigWarningPrefix = "lfs." ) @@ -33,7 +37,7 @@ type Configuration struct { // version. gitConfig *git.Configuration - fs *fs + fs *fs.Filesystem CurrentRemote string @@ -174,18 +178,15 @@ func (c *Configuration) InRepo() bool { } func (c *Configuration) LocalWorkingDir() string { - c.ResolveGitBasicDirs() - return c.fs.WorkingDir + return c.Filesystem().WorkingDir } func (c *Configuration) LocalGitDir() string { - c.ResolveGitBasicDirs() - return c.fs.GitDir + return c.Filesystem().GitDir } func (c *Configuration) LocalGitStorageDir() string { - c.ResolveGitBasicDirs() - return c.fs.GitStorageDir + return c.Filesystem().GitStorageDir } func (c *Configuration) LocalReferenceDir() string { @@ -193,8 +194,7 @@ func (c *Configuration) LocalReferenceDir() string { } func (c *Configuration) LocalLogDir() string { - c.ResolveGitBasicDirs() - return c.fs.LogDir + return c.Filesystem().LogDir } func (c *Configuration) SetLocalLogDir(s string) { @@ -254,13 +254,30 @@ func (c *Configuration) UnsetGitLocalKey(file, key string) (string, error) { return c.gitConfig.UnsetLocalKey(file, key) } -func (c *Configuration) ResolveGitBasicDirs() { +func (c *Configuration) Filesystem() *fs.Filesystem { c.loading.Lock() defer c.loading.Unlock() if c.fs == nil { - c.fs = resolveGitBasicDirs() + gitdir, workdir, err := git.GitAndRootDirs() + if err != nil { + errMsg := err.Error() + tracerx.Printf("Error running 'git rev-parse': %s", errMsg) + if !strings.Contains(errMsg, "Not a git repository") { + fmt.Fprintf(os.Stderr, "Error: %s\n", errMsg) + } + c.fs = &fs.Filesystem{} + } else { + c.fs = fs.New(gitdir, workdir, "") + LocalReferenceDir = c.fs.ReferenceDir + } } + + return c.fs +} + +func (c *Configuration) ResolveGitBasicDirs() { + c.Filesystem() } // loadGitConfig is a temporary measure to support legacy behavior dependent on diff --git a/config/filesystem.go b/fs/fs.go similarity index 67% rename from config/filesystem.go rename to fs/fs.go index 39687f91..0e530477 100644 --- a/config/filesystem.go +++ b/fs/fs.go @@ -1,61 +1,44 @@ -package config +package fs import ( - "fmt" "io/ioutil" - "os" "path/filepath" "strings" - "github.com/git-lfs/git-lfs/git" "github.com/git-lfs/git-lfs/tools" - "github.com/rubyist/tracerx" ) -var ( - LocalReferenceDir string // alternative local media dir (relative to clone reference repo) -) - -type fs struct { +type Filesystem struct { WorkingDir string - GitDir string // parent of index / config / hooks etc - GitStorageDir string // parent of objects/lfs (may be same as LocalGitDir but may not) + GitDir string // parent of index / config / hooks etc. Default: ".git" + GitStorageDir string // parent of objects/lfs (may be same as GitDir but may not) + LFSStorageDir string // parent of lfs objects and tmp dirs. Default: ".git/lfs" ReferenceDir string // alternative local media dir (relative to clone reference repo) LogDir string } -func (f *fs) InRepo() bool { +func (f *Filesystem) InRepo() bool { if f == nil { return false } return len(f.GitDir) > 0 } -// Determins the LocalWorkingDir, LocalGitDir etc -func resolveGitBasicDirs() *fs { - localGitDir, localWorkingDir, err := git.GitAndRootDirs() - if err != nil { - errMsg := err.Error() - tracerx.Printf("Error running 'git rev-parse': %s", errMsg) - if !strings.Contains(errMsg, "Not a git repository") { - fmt.Fprintf(os.Stderr, "Error: %s\n", errMsg) - } - return &fs{} - } - +// New initializes a new *Filesystem with the given directories. gitdir is the +// path to the bare repo, workdir is the path to the repository working +// directory, and lfsdir is the optional path to the `.git/lfs` directory. +func New(gitdir, workdir, lfsdir string) *Filesystem { // Make sure we've fully evaluated symlinks, failure to do consistently // can cause discrepancies - localGitDir = tools.ResolveSymlinks(localGitDir) - localWorkingDir = tools.ResolveSymlinks(localWorkingDir) - localGitStorageDir := resolveGitStorageDir(localGitDir) - LocalReferenceDir = resolveReferenceDir(localGitStorageDir) - - return &fs{ - GitDir: localGitDir, - WorkingDir: localWorkingDir, - GitStorageDir: localGitStorageDir, - ReferenceDir: LocalReferenceDir, + fs := &Filesystem{ + GitDir: tools.ResolveSymlinks(gitdir), + WorkingDir: tools.ResolveSymlinks(workdir), } + + fs.GitStorageDir = resolveGitStorageDir(fs.GitDir) + fs.ReferenceDir = resolveReferenceDir(fs.GitStorageDir) + + return fs } func resolveReferenceDir(gitStorageDir string) string {