Fixed support for worktree

Issue is that during 'git worktree add', git uses GIT_DIR to locate the
worktree girder, which then resolves via commondir. When actually running
in the worktree, it follows .git/git-dir THEN commondir. Generalised so
this now works, and introduced LocalGitStorageDir.
This commit is contained in:
Steve Streeting 2015-07-31 12:17:50 +01:00
parent 416950783e
commit 66ebac22a7
4 changed files with 49 additions and 19 deletions

@ -83,7 +83,7 @@ func doFsck() (bool, error) {
continue
}
badDir := filepath.Join(lfs.LocalGitDir, "lfs", "bad")
badDir := filepath.Join(lfs.LocalGitStorageDir, "lfs", "bad")
if err := os.MkdirAll(badDir, 0755); err != nil {
return false, err
}

@ -25,6 +25,7 @@ var (
UserAgent string
LocalWorkingDir string
LocalGitDir string
LocalGitStorageDir string // parent of objects/lfs (may be same as LocalGitDir but may not)
LocalMediaDir string
LocalLogDir string
checkedTempDir string
@ -69,13 +70,16 @@ func ObjectExistsOfSize(sha string, size int64) bool {
func Environ() []string {
osEnviron := os.Environ()
env := make([]string, 6, len(osEnviron)+6)
env[0] = fmt.Sprintf("LocalWorkingDir=%s", LocalWorkingDir)
env[1] = fmt.Sprintf("LocalGitDir=%s", LocalGitDir)
env[2] = fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir)
env[3] = fmt.Sprintf("TempDir=%s", TempDir)
env[4] = fmt.Sprintf("ConcurrentTransfers=%d", Config.ConcurrentTransfers())
env[5] = fmt.Sprintf("BatchTransfer=%v", Config.BatchTransfer())
env := make([]string, 7, len(osEnviron)+7)
env = append(env,
fmt.Sprintf("LocalWorkingDir=%s", LocalWorkingDir),
fmt.Sprintf("LocalGitDir=%s", LocalGitDir),
fmt.Sprintf("LocalGitStorageDir=%s", LocalGitStorageDir),
fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir),
fmt.Sprintf("TempDir=%s", TempDir),
fmt.Sprintf("ConcurrentTransfers=%d", Config.ConcurrentTransfers()),
fmt.Sprintf("BatchTransfer=%v", Config.BatchTransfer()),
)
for _, e := range osEnviron {
if !strings.Contains(e, "GIT_") {
@ -99,9 +103,10 @@ func init() {
LocalWorkingDir, LocalGitDir, err = resolveGitDir()
if err == nil {
LocalMediaDir = filepath.Join(LocalGitDir, "lfs", "objects")
LocalGitStorageDir = resolveGitStorageDir(LocalGitDir)
LocalMediaDir = filepath.Join(LocalGitStorageDir, "lfs", "objects") // objects across all worktrees
LocalLogDir = filepath.Join(LocalMediaDir, "logs")
TempDir = filepath.Join(LocalGitDir, "lfs", "tmp")
TempDir = filepath.Join(LocalGitDir, "lfs", "tmp") // temp files per worktree
if err := os.MkdirAll(LocalMediaDir, localMediaDirPerms); err != nil {
panic(fmt.Errorf("Error trying to create objects directory in '%s': %s", LocalMediaDir, err))
@ -257,16 +262,24 @@ func processGitRedirectFile(file, prefix string) (string, error) {
dir = filepath.Join(filepath.Dir(file), dir)
}
// Finally, check the contents of dir; if it contains a "commondir" file and
// not an "objects" dir, then this is probably a worktree link (see man git-worktree)
// The commondir file points to the actual location
commondirpath := filepath.Join(dir, "commondir")
if FileExists(commondirpath) && !DirExists(filepath.Join(dir, "objects")) {
// no git-dir: prefix in commondir
return processGitRedirectFile(commondirpath, "")
return dir, nil
}
return dir, nil
// From a git dir, get the location that objects are to be stored (we will store lfs alongside)
// Sometimes there is an additional level of redirect on the .git folder by way of a commondir file
// before you find object storage, e.g. 'git worktree' uses this. It redirects to gitdir either by GIT_DIR
// (during setup) or .git/git-dir: (during use), but this only contains the index etc, the objects
// are found in another git dir via 'commondir'.
func resolveGitStorageDir(gitDir string) string {
commondirpath := filepath.Join(gitDir, "commondir")
if FileExists(commondirpath) && !DirExists(filepath.Join(gitDir, "objects")) {
// no git-dir: prefix in commondir
storage, err := processGitRedirectFile(commondirpath, "")
if err == nil {
return storage
}
}
return gitDir
}
const (

@ -13,6 +13,7 @@ begin_test "env with no remote"
expected=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -37,6 +38,7 @@ begin_test "env with origin remote"
Endpoint=$GITSERVER/$reponame.git/info/lfs
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -68,6 +70,7 @@ Endpoint=$GITSERVER/env-origin-remote.git/info/lfs
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -97,6 +100,7 @@ begin_test "env with other remote"
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -129,6 +133,7 @@ Endpoint=http://foo/bar
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -163,6 +168,7 @@ Endpoint=http://foo/bar
Endpoint (other)=http://custom/other
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -199,6 +205,7 @@ Endpoint=http://foo/bar
Endpoint (other)=http://custom/other
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=5
@ -235,6 +242,7 @@ begin_test "env with .gitconfig"
Endpoint=http://foobar:8080/
LocalWorkingDir=$TRASHDIR/$reponame
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=5
@ -265,6 +273,7 @@ begin_test "env with environment variables"
expected=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame/a/b
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -290,6 +299,7 @@ $(GIT_DIR=$gitDir GIT_WORK_TREE=$workTree env | grep "^GIT")
expected5=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame/a/b
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -302,6 +312,7 @@ $(GIT_DIR=$gitDir GIT_WORK_TREE=a/b env | grep "^GIT")
expected6=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame/a/b
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -315,6 +326,7 @@ $(GIT_WORK_TREE=a/b env | grep "^GIT")
expected7=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame/a/b
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3
@ -328,6 +340,7 @@ $(GIT_DIR=$gitDir env | grep "^GIT")
expected8=$(printf "%s\n%s\n
LocalWorkingDir=$TRASHDIR/$reponame/a/b
LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$LocalGitDir
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=3

@ -43,6 +43,7 @@ begin_test "submodule env"
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
grep "LocalWorkingDir=$TRASHDIR/repo$" env.log
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
@ -53,6 +54,7 @@ begin_test "submodule env"
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
grep "LocalWorkingDir=$" env.log
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
@ -63,6 +65,7 @@ begin_test "submodule env"
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
@ -73,6 +76,7 @@ begin_test "submodule env"
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
)