From e97df9c8102c92701489cb2693294064f1488b4b Mon Sep 17 00:00:00 2001 From: Alec Lanter Date: Sat, 21 Jan 2023 16:10:02 -0600 Subject: [PATCH] fix(#971): parse submodule .git files instead of erroring Altered logic for detecting git directory. Instead of erroring on non-direcctory .git files, now parses the file and returns the linked gitdir. --- repository/gogit.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/repository/gogit.go b/repository/gogit.go index 93806026b13770de42a4bb0232a3692d89c293c6..18f7fb59d4cfc24bc9b70230387b0ef9d3c17aff 100644 --- a/repository/gogit.go +++ b/repository/gogit.go @@ -1,6 +1,7 @@ package repository import ( + "bufio" "bytes" "errors" "fmt" @@ -170,6 +171,28 @@ func detectGitPath(path string) (string, error) { fi, err := os.Stat(filepath.Join(path, ".git")) if err == nil { if !fi.IsDir() { + // See if our .git item is a dotfile that holds a submodule reference + dotfile, err := os.Open(fi.Name()) + if err != nil { + // Can't open" error + return "", fmt.Errorf(".git exists but is not a directory or a readable file: %w", err) + } + // We aren't going to defer the dotfile.Close, because we might keep looping, so we have to be sure to + // clean up before returning an error + reader := bufio.NewReader(dotfile) + line, _, err := reader.ReadLine() + if err != nil { + _ = dotfile.Close() + return "", fmt.Errorf(".git exists but is not a direcctory and cannot be read: %w", err) + } + dotContent := string(line) + if strings.HasPrefix(dotContent, "gitdir:") { + _ = dotfile.Close() + // This is a submodule parent path link. Strip the prefix, clean the string of whitespace just to + // be safe, and return + dotContent = strings.TrimSpace(dotContent[7:]) + return dotContent, nil + } return "", fmt.Errorf(".git exist but is not a directory") } return filepath.Join(path, ".git"), nil