findChildRepos returns subdirectories that are git repositories, excluding any that are listed in the parent's .gitignore.
(root string)
| 1433 | // findChildRepos returns subdirectories that are git repositories, |
| 1434 | // excluding any that are listed in the parent's .gitignore. |
| 1435 | func findChildRepos(root string) []string { |
| 1436 | entries, err := os.ReadDir(root) |
| 1437 | if err != nil { |
| 1438 | return nil |
| 1439 | } |
| 1440 | |
| 1441 | // Check which directories are git-ignored using git check-ignore |
| 1442 | // This is more reliable than parsing .gitignore ourselves since it |
| 1443 | // handles all gitignore semantics (negation, nested, global, etc.) |
| 1444 | var candidates []string |
| 1445 | for _, e := range entries { |
| 1446 | if !e.IsDir() || strings.HasPrefix(e.Name(), ".") { |
| 1447 | continue |
| 1448 | } |
| 1449 | if _, err := os.Stat(filepath.Join(root, e.Name(), ".git")); err == nil { |
| 1450 | candidates = append(candidates, e.Name()) |
| 1451 | } |
| 1452 | } |
| 1453 | |
| 1454 | if len(candidates) == 0 { |
| 1455 | return nil |
| 1456 | } |
| 1457 | |
| 1458 | // Use git check-ignore to filter out ignored directories. |
| 1459 | // In non-git parents this silently fails and nothing is filtered, |
| 1460 | // which is correct — .gitignore is a git concept. |
| 1461 | args := append([]string{"check-ignore", "--"}, candidates...) |
| 1462 | cmd := exec.Command("git", args...) |
| 1463 | cmd.Dir = root |
| 1464 | out, _ := cmd.Output() |
| 1465 | ignored := make(map[string]bool) |
| 1466 | for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") { |
| 1467 | if line != "" { |
| 1468 | ignored[line] = true |
| 1469 | } |
| 1470 | } |
| 1471 | |
| 1472 | var repos []string |
| 1473 | for _, name := range candidates { |
| 1474 | if !ignored[name] { |
| 1475 | repos = append(repos, name) |
| 1476 | } |
| 1477 | } |
| 1478 | return repos |
| 1479 | } |
| 1480 | |
| 1481 | // hookSessionStartMultiRepo handles meta-repos containing multiple child repos. |
| 1482 | // Output is capped to MaxContextOutputBytes to prevent context blowup. |
no outgoing calls