36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package proc
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func detectGitInfo(cwd string) (string, string) {
|
|
if cwd == "" || cwd == "unknown" {
|
|
return "", ""
|
|
}
|
|
|
|
searchDir := cwd
|
|
for depth := 0; depth < 10; depth++ {
|
|
gitPath := filepath.Join(searchDir, ".git")
|
|
if fi, err := os.Stat(gitPath); err == nil {
|
|
gitDir := gitPath
|
|
if !fi.IsDir() {
|
|
// In a worktree or submodule, .git is a file holding a
|
|
// "gitdir: <path>" pointer to the real git directory.
|
|
gitDir = gitDirFromFile(gitPath, searchDir)
|
|
}
|
|
if gitDir != "" {
|
|
return filepath.Base(searchDir), gitBranchFromHEAD(gitDir)
|
|
}
|
|
}
|
|
|
|
parent := filepath.Dir(searchDir)
|
|
if parent == searchDir {
|
|
break
|
|
}
|
|
searchDir = parent
|
|
}
|
|
|
|
return "", ""
|
|
}
|
|
|
|
// gitDirFromFile parses the "gitdir: <path>" pointer in a .git file (used by
|
|
// worktrees and submodules) and returns the real git directory as an absolute
|
|
// path, or "" if it can't be read.
|
|
func gitDirFromFile(gitFile, baseDir string) string {
|
|
data, err := os.ReadFile(gitFile)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
for _, line := range strings.Split(string(data), "\n") {
|
|
rest, ok := strings.CutPrefix(strings.TrimSpace(line), "gitdir:")
|
|
if !ok {
|
|
continue
|
|
}
|
|
dir := strings.TrimSpace(rest)
|
|
if dir == "" {
|
|
return ""
|
|
}
|
|
if !filepath.IsAbs(dir) {
|
|
dir = filepath.Join(baseDir, dir)
|
|
}
|
|
return dir
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// gitBranchFromHEAD reads <gitDir>/HEAD and returns the checked-out branch name,
|
|
// or "" when HEAD is detached or unreadable.
|
|
func gitBranchFromHEAD(gitDir string) string {
|
|
head, err := os.ReadFile(filepath.Join(gitDir, "HEAD"))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
if ref, ok := strings.CutPrefix(strings.TrimSpace(string(head)), "ref: "); ok {
|
|
return strings.TrimPrefix(ref, "refs/heads/")
|
|
}
|
|
return ""
|
|
}
|