Skip to content

New("") silently loads .gitignore from CWD — unexpected for programmatic-only usage #7

@qraveh

Description

@qraveh

Summary

gitignore.New("") auto-loads patterns from the process working directory's .gitignore, .git/info/exclude, and the global excludes file. When callers only intend to use AddPatterns for programmatic rules, the filesystem-loaded patterns silently contaminate the matcher.

Reproduction

package main

import (
    "fmt"
    "os"
    "github.com/git-pkgs/gitignore"
)

func main() {
    // Create .gitignore in CWD that excludes *.exe
    os.WriteFile(".gitignore", []byte("*.exe\n"), 0644)
    defer os.Remove(".gitignore")

    // Create matcher with ONLY *.tmp as a rule
    m := gitignore.New("")
    m.AddPatterns([]byte("*.tmp"), "")

    // Expect false — we never added *.exe
    fmt.Println(m.MatchPath("test.exe", false)) // prints: true
}

Expected behavior

When a caller passes root="" and only adds patterns via AddPatterns, the matcher should only match against the explicitly added patterns.

Actual behavior

New("") resolves "" as the CWD and loads:

  1. Global git excludes (core.excludesfile)
  2. .git/info/exclude from CWD
  3. .gitignore from CWD

These filesystem-sourced patterns are invisible to the caller and cannot be distinguished from programmatic patterns.

Impact

In our project (SelectiveMirror), this caused the filter engine to silently inherit .gitignore rules from the repository, producing ~30 false-positive "excluded file" reports. Files that were correctly synced to a remote were misclassified as "leaks" and would have been deleted by the cleanup routine.

Suggested fix

Either:

  1. Skip filesystem loading when root is empty — treat New("") as equivalent to &Matcher{} (no filesystem patterns)
  2. Add a constructor that skips filesystem loading — e.g. NewEmpty() or NewProgrammatic() that only creates a bare matcher for AddPatterns use

Workaround

We replaced gitignore.New("") with &gitignore.Matcher{} (zero-value struct), which creates a matcher without loading any filesystem patterns. AddPatterns works correctly on this bare struct.

Version

github.com/git-pkgs/gitignore v1.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions