10 "github.com/git-lfs/git-lfs/git"
11 "github.com/git-lfs/git-lfs/tools"
12 "github.com/rubyist/tracerx"
16 LocalWorkingDir string
17 LocalGitDir string // parent of index / config / hooks etc
18 LocalGitStorageDir string // parent of objects/lfs (may be same as LocalGitDir but may not)
19 LocalReferenceDir string // alternative local media dir (relative to clone reference repo)
23 // Determins the LocalWorkingDir, LocalGitDir etc
24 func ResolveGitBasicDirs() {
26 LocalGitDir, LocalWorkingDir, err = git.GitAndRootDirs()
28 // Make sure we've fully evaluated symlinks, failure to do consistently
29 // can cause discrepancies
30 LocalGitDir = tools.ResolveSymlinks(LocalGitDir)
31 LocalWorkingDir = tools.ResolveSymlinks(LocalWorkingDir)
33 LocalGitStorageDir = resolveGitStorageDir(LocalGitDir)
34 LocalReferenceDir = resolveReferenceDir(LocalGitStorageDir)
38 tracerx.Printf("Error running 'git rev-parse': %s", errMsg)
39 if !strings.Contains(errMsg, "Not a git repository") {
40 fmt.Fprintf(os.Stderr, "Error: %s\n", errMsg)
45 func resolveReferenceDir(gitStorageDir string) string {
46 cloneReferencePath := filepath.Join(gitStorageDir, "objects", "info", "alternates")
47 if tools.FileExists(cloneReferencePath) {
48 buffer, err := ioutil.ReadFile(cloneReferencePath)
50 path := strings.TrimSpace(string(buffer[:]))
51 referenceLfsStoragePath := filepath.Join(filepath.Dir(path), "lfs", "objects")
52 if tools.DirExists(referenceLfsStoragePath) {
53 return referenceLfsStoragePath
60 // From a git dir, get the location that objects are to be stored (we will store lfs alongside)
61 // Sometimes there is an additional level of redirect on the .git folder by way of a commondir file
62 // before you find object storage, e.g. 'git worktree' uses this. It redirects to gitdir either by GIT_DIR
63 // (during setup) or .git/git-dir: (during use), but this only contains the index etc, the objects
64 // are found in another git dir via 'commondir'.
65 func resolveGitStorageDir(gitDir string) string {
66 commondirpath := filepath.Join(gitDir, "commondir")
67 if tools.FileExists(commondirpath) && !tools.DirExists(filepath.Join(gitDir, "objects")) {
68 // no git-dir: prefix in commondir
69 storage, err := processGitRedirectFile(commondirpath, "")
77 func processGitRedirectFile(file, prefix string) (string, error) {
78 data, err := ioutil.ReadFile(file)
83 contents := string(data)
86 if !strings.HasPrefix(contents, prefix) {
87 // Prefix required & not found
90 dir = strings.TrimSpace(contents[len(prefix):])
92 dir = strings.TrimSpace(contents)
95 if !filepath.IsAbs(dir) {
96 // The .git file contains a relative path.
97 // Create an absolute path based on the directory the .git file is located in.
98 dir = filepath.Join(filepath.Dir(file), dir)