The core question is finally answerable: does a rule-set ignore a path? A plain pattern with no slash floats - it matches the file's basename at any depth. Today Ignored answers for these floating patterns.
Make a slash-free pattern match a path's basename at any depth.
Now the payoff: Ignored(path, isDir) reports whether the rule-set ignores a
given path. The simplest and most common gitignore rule is a pattern with no
slash in it, like *.log or build. Such a pattern floats: it matches the
path’s basename - the last segment - no matter how deep the path is. So *.log
ignores a.log and dir/a.log and x/y/z.log alike, because in each the final
segment ends in .log.
Because a floating pattern only ever looks at one segment, you match it with
matchSegment - the single-segment engine from the first two chapters, reused
untouched. Pull the basename off the path and test each rule against it; ignored if
any rule matches. The isDir argument is here from the start because a coming
lesson needs it, but today it is unused. This is the whole engine in miniature;
anchoring, directories, and negation each refine how a rule matches from here.
func (g *Gitignore) Ignored(path string, isDir bool) bool {base := pathif i := strings.LastIndex(path, "/"); i >= 0 {base = path[i+1:] // the final path segment}for _, r := range g.rules {if matchSegment(r.Pattern, base) { return true }}return false}