aboutsummaryrefslogtreecommitdiffstats
path: root/sync.go
diff options
context:
space:
mode:
authorBernhard Guillon <Bernhard.Guillon@begu.org>2026-07-06 21:36:29 +0200
committerBernhard Guillon <Bernhard.Guillon@begu.org>2026-07-06 21:36:29 +0200
commitad7575e85ebf6332d324ca5997db18ea81065df4 (patch)
treed2a2e46e2c0432d4b4437c562b4c70de4a6bebf0 /sync.go
parent8b22a36d1c068f9baee68799b0c1f51ecb999e9d (diff)
downloadsourcewatch-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.go24
1 files changed, 14 insertions, 10 deletions
diff --git a/sync.go b/sync.go
index 293f20b..526e143 100644
--- a/sync.go
+++ b/sync.go
@@ -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
}