Initial stab at worktree support
This commit is contained in:
parent
cc0bf4194b
commit
416950783e
60
lfs/lfs.go
60
lfs/lfs.go
@ -64,11 +64,7 @@ func LocalMediaPath(sha string) (string, error) {
|
||||
|
||||
func ObjectExistsOfSize(sha string, size int64) bool {
|
||||
path := localMediaPathNoCreate(sha)
|
||||
stat, err := os.Stat(path)
|
||||
if err == nil && size == stat.Size() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return FileExistsOfSize(path, size)
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
@ -153,7 +149,7 @@ func resolveGitDir() (string, string, error) {
|
||||
}
|
||||
|
||||
if workTree != "" {
|
||||
return processWorkTree(gitDirR, workTree)
|
||||
return processWorkTreeVar(gitDirR, workTree)
|
||||
}
|
||||
|
||||
return workTreeR, gitDirR, nil
|
||||
@ -161,7 +157,7 @@ func resolveGitDir() (string, string, error) {
|
||||
|
||||
func processGitDirVar(gitDir, workTree string) (string, string, error) {
|
||||
if workTree != "" {
|
||||
return processWorkTree(gitDir, workTree)
|
||||
return processWorkTreeVar(gitDir, workTree)
|
||||
}
|
||||
|
||||
// See `core.worktree` in `man git-config`:
|
||||
@ -177,7 +173,7 @@ func processGitDirVar(gitDir, workTree string) (string, string, error) {
|
||||
return wd, gitDir, nil
|
||||
}
|
||||
|
||||
func processWorkTree(gitDir, workTree string) (string, string, error) {
|
||||
func processWorkTreeVar(gitDir, workTree string) (string, string, error) {
|
||||
// See `core.worktree` in `man git-config`:
|
||||
// “The value [of core.worktree, GIT_WORK_TREE, or --work-tree] can be an absolute path
|
||||
// or relative to the path to the .git directory, which is either specified
|
||||
@ -234,37 +230,43 @@ func resolveDotGitFile(file string) (string, string, error) {
|
||||
}
|
||||
|
||||
func processDotGitFile(file string) (string, error) {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return processGitRedirectFile(file, gitPtrPrefix)
|
||||
}
|
||||
|
||||
data := make([]byte, 512)
|
||||
n, err := f.Read(data)
|
||||
func processGitRedirectFile(file, prefix string) (string, error) {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
contents := string(data[0:n])
|
||||
|
||||
if !strings.HasPrefix(contents, gitPtrPrefix) {
|
||||
// The `.git` file has no entry telling us about gitdir.
|
||||
return "", nil
|
||||
contents := string(data)
|
||||
var dir string
|
||||
if len(prefix) > 0 {
|
||||
if !strings.HasPrefix(contents, prefix) {
|
||||
// Prefix required & not found
|
||||
return "", nil
|
||||
}
|
||||
dir = strings.TrimSpace(contents[len(prefix):])
|
||||
} else {
|
||||
dir = strings.TrimSpace(contents)
|
||||
}
|
||||
|
||||
dir := strings.TrimSpace(strings.Split(contents, gitPtrPrefix)[1])
|
||||
|
||||
if filepath.IsAbs(dir) {
|
||||
// The .git file contains an absolute path.
|
||||
return dir, nil
|
||||
if !filepath.IsAbs(dir) {
|
||||
// The .git file contains a relative path.
|
||||
// Create an absolute path based on the directory the .git file is located in.
|
||||
dir = filepath.Join(filepath.Dir(file), dir)
|
||||
}
|
||||
|
||||
// The .git file contains a relative path.
|
||||
// Create an absolute path based on the directory the .git file is located in.
|
||||
absDir := 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 absDir, nil
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
const (
|
||||
|
33
lfs/util.go
33
lfs/util.go
@ -275,3 +275,36 @@ func ConvertCwdFilesRelativeToRepo(cwdchan <-chan string) (<-chan string, error)
|
||||
func IsWindows() bool {
|
||||
return GetPlatform() == PlatformWindows
|
||||
}
|
||||
|
||||
// Determine if a file/dir exists, returns IsDir() results too
|
||||
func FileOrDirExists(path string) (exists bool, isDir bool) {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false, false
|
||||
} else {
|
||||
return true, fi.IsDir()
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if a file (NOT dir) exists
|
||||
func FileExists(path string) bool {
|
||||
ret, isDir := FileOrDirExists(path)
|
||||
return ret && !isDir
|
||||
}
|
||||
|
||||
// Determine if a dir (NOT file) exists
|
||||
func DirExists(path string) bool {
|
||||
ret, isDir := FileOrDirExists(path)
|
||||
return ret && isDir
|
||||
}
|
||||
|
||||
// Determine if a file exists and is of a specific size
|
||||
func FileExistsOfSize(path string, sz int64) bool {
|
||||
fi, err := os.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return !fi.IsDir() && fi.Size() == sz
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user