Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ For repos with nested `.gitignore` files, `NewFromDirectory` walks the tree and
m := gitignore.NewFromDirectory("/path/to/repo")
```

You can also add patterns manually:
To create a matcher with only programmatic patterns (no filesystem loading), pass an empty root:

```go
m := gitignore.New("")
m.AddPatterns([]byte("*.tmp\n"), "")
```

You can also add patterns to any matcher manually:

```go
m.AddFromFile("/path/to/repo/src/.gitignore", "src")
Expand Down
8 changes: 7 additions & 1 deletion gitignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,16 @@ func (m *Matcher) Errors() []PatternError {
// patterns override earlier ones.
//
// The root parameter should be the repository working directory
// (containing .git/).
// (containing .git/). If root is empty, no filesystem patterns are
// loaded and the returned Matcher is empty. Use AddPatterns or
// AddFromFile to add patterns programmatically.
func New(root string) *Matcher {
m := &Matcher{}

if root == "" {
return m
}

// Read global excludes (lowest priority)
if gef := globalExcludesFile(); gef != "" {
if data, err := os.ReadFile(gef); err == nil {
Expand Down
33 changes: 33 additions & 0 deletions gitignore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2490,3 +2490,36 @@ func TestAddPatterns(t *testing.T) {
}
}
}

func TestNewEmptyRootSkipsFilesystem(t *testing.T) {
// Create a temporary directory with a .gitignore that excludes *.exe
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("*.exe\n"), 0644); err != nil {
t.Fatal(err)
}

// Change to that directory so CWD has a .gitignore
orig, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if err := os.Chdir(dir); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := os.Chdir(orig); err != nil {
t.Logf("failed to restore working directory: %v", err)
}
})

// New("") should not load any filesystem patterns
m := gitignore.New("")
m.AddPatterns([]byte("*.tmp"), "")

if m.MatchPath("test.exe", false) {
t.Error("New(\"\") should not load .gitignore from CWD, but *.exe matched")
}
if !m.MatchPath("test.tmp", false) {
t.Error("AddPatterns(*.tmp) should still work after New(\"\")")
}
}