diff options
| author | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-06 21:36:29 +0200 |
|---|---|---|
| committer | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-06 21:36:29 +0200 |
| commit | ad7575e85ebf6332d324ca5997db18ea81065df4 (patch) | |
| tree | d2a2e46e2c0432d4b4437c562b4c70de4a6bebf0 /sync.go | |
| parent | 8b22a36d1c068f9baee68799b0c1f51ecb999e9d (diff) | |
| download | sourcewatch-ad7575e85ebf6332d324ca5997db18ea81065df4.tar.gz sourcewatch-ad7575e85ebf6332d324ca5997db18ea81065df4.zip | |
Implement nested .gitignore support with GitignoreStack
- Replaced go-gitignore with custom GitignoreStack that tracks
multiple .gitignore files hierarchically
- Patterns are processed in root-to-leaf order, last match wins
- Negation patterns in child dirs override parent ignores
- Patterns only apply within their directory scope (no leaking)
- Added 6 new tests for nested .gitignore:
- Scoped: patterns only affect own directory
- Dir-scoped: different dirs can ignore different things
- Negation override: child !pattern un-ignores parent's *.pattern
- Deep nesting: 3+ levels of .gitignore
- Parent scope doesn't leak to siblings
- All 35 tests passing
Diffstat (limited to 'sync.go')
| -rw-r--r-- | sync.go | 24 |
1 files changed, 14 insertions, 10 deletions
@@ -5,22 +5,19 @@ import ( "log" "os" "path/filepath" - "strings" - - ignore "github.com/sabhiram/go-gitignore" ) type FileMeta struct { - Size int64 - Mode os.FileMode - Symlink string + Size int64 + Mode os.FileMode + Symlink string } type Manifest struct { Files map[string]FileMeta } -func initialSync(hostDir, dataDir string, rules *ignore.GitIgnore, dryRun bool) (*Manifest, error) { +func initialSync(hostDir, dataDir string, stack *GitignoreStack, dryRun bool) (*Manifest, error) { manifest := &Manifest{Files: make(map[string]FileMeta)} err := filepath.Walk(hostDir, func(path string, info os.FileInfo, err error) error { @@ -37,11 +34,18 @@ func initialSync(hostDir, dataDir string, rules *ignore.GitIgnore, dryRun bool) return nil } - if relPath == ".git" || strings.HasPrefix(relPath, ".git"+string(filepath.Separator)) { - return filepath.SkipDir + if isGitDir(relPath) { + if info.IsDir() { + return filepath.SkipDir + } + return nil + } + + if info.IsDir() && hasGitignore(path) { + stack.Push(path) } - if rules.MatchesPath(relPath) { + if stack.IsIgnored(relPath) { if info.IsDir() { return filepath.SkipDir } |
