package scanner import ( "os" "path/filepath" "git.membo.co.uk/dtomlinson/gitlocal/internal/git" ) // FindNestedGitRepos recursively scans rootPath for nested .git and .gitlocal directories // and returns a list of absolute paths to directories containing .git or .gitlocal // It skips the root repo's .git/.gitlocal directory if one exists func FindNestedGitRepos(rootPath string) ([]string, error) { var repos []string // Get absolute path absRoot, err := filepath.Abs(rootPath) if err != nil { return nil, err } // Check if root itself is a git repo (either .git or .gitlocal) rootIsGitRepo := git.IsGitRepo(absRoot) || git.IsGitLocalRepo(absRoot) rootGitPath := filepath.Join(absRoot, git.GitDir) rootGitLocalPath := filepath.Join(absRoot, git.GitLocalDir) err = filepath.Walk(absRoot, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // Skip if not a directory if !info.IsDir() { return nil } // Skip if this is the root's .git or .gitlocal directory if rootIsGitRepo && (path == rootGitPath || path == rootGitLocalPath) { return filepath.SkipDir } // Check if this directory is named .git or .gitlocal if info.Name() == git.GitDir || info.Name() == git.GitLocalDir { // Get the parent directory (the actual repo path) repoPath := filepath.Dir(path) repos = append(repos, repoPath) // Skip descending into .git/.gitlocal directory return filepath.SkipDir } return nil }) if err != nil { return nil, err } return repos, nil }