diff --git a/pkg/ignore/doc.go b/pkg/ignore/doc.go index a66066eb2..7c5708a92 100644 --- a/pkg/ignore/doc.go +++ b/pkg/ignore/doc.go @@ -63,6 +63,19 @@ Notable differences from .gitignore: - The globbing library is Go's 'filepath.Match', not fnmatch(3) - Trailing spaces are always ignored (there is no supported escape sequence) - The evaluation of escape sequences has not been tested for compatibility - - There is no support for '\!' as a special leading sequence. + - There is no support for '\\!' as a special leading sequence for files that begin with `!` + - The first filename match will determine if it is included or excluded, subsequent lines are ignored + +Example: + + # This is valid .gitignore syntax to only include Chart.yaml and values.yaml, but invalid for .helmignore + * + !Chart.yaml + !values.yaml + + # Instead, this syntax will work as .helmignore takes the first match per file + !Chart.yaml + !values.yaml + * */ package ignore // import "helm.sh/helm/v4/pkg/ignore" diff --git a/pkg/ignore/rules.go b/pkg/ignore/rules.go index 3511c2d40..f83cf8a8b 100644 --- a/pkg/ignore/rules.go +++ b/pkg/ignore/rules.go @@ -105,26 +105,19 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool { return false } - // For negative rules, we need to capture and return non-matches, - // and continue for matches. - if p.negate { - if p.mustDir && !fi.IsDir() { - return true - } - if !p.match(path, fi) { - return true - } - continue - } - // If the rule is looking for directories, and this is not a directory, // skip it. if p.mustDir && !fi.IsDir() { continue } + + // For negative rules, we need to capture and return non-matches, + // and continue for matches. if p.match(path, fi) { - return true + // if negate, then return false to "should I ignore" + return !p.negate } + } return false } diff --git a/pkg/ignore/rules_test.go b/pkg/ignore/rules_test.go index 9581cf09f..b1f071fed 100644 --- a/pkg/ignore/rules_test.go +++ b/pkg/ignore/rules_test.go @@ -113,10 +113,12 @@ func TestIgnore(t *testing.T) { {`helm.txt/`, "helm.txt", false}, // Negation tests - {`!helm.txt`, "helm.txt", false}, - {`!helm.txt`, "tiller.txt", true}, - {`!*.txt`, "cargo", true}, - {`!cargo/`, "mast/", true}, + {"!helm.txt\n*", "helm.txt", false}, + {"!helm.txt", "tiller.txt", false}, // Don't ignore files that match zero patterns + {"!helm.txt\n*", "tiller.txt", true}, + {"!*.txt\n*", "cargo", true}, + {"!cargo/\n*", "cargo", false}, + {"!cargo/\n*", "cargo/a.txt", true}, // Absolute path tests {`/a.txt`, "a.txt", true},