Download raw body.
leading separators in ignore patterns
On Sat, May 17, 2025 at 01:38:23PM -0700, Evan Silberman wrote:
> I'm back with a patch.
>
> - Skip past leading slashes in ignore patterns. In gitignore(7), these
> trigger the behavior got has by default. Add regress test.
> - Lift documentation of ignore patterns to a subsection, referenced by
> the `add` and `status` docs.
> - Refine documentation of ignore patterns to discuss the extensions to
> glob(7) as a whole, and then list caveats relative to git(1) and
> cvs(1).
> - Add a file to the test worktree in the main gitignore regress test in
> order to register a known delta to gitignore(7) that was ambiguously
> documented previously: for the pattern a/**/foo, git will ignore
> a/foo, but got will not.
Thinking about is some more, you have convinced me that matching "/foo"
like "foo" won't hurt. Matched paths are relative to the work tree so
there is no point in trying to match a path in the root directory.
> The one change to worktree.c here originally happened in read_ignores()
> but I moved it to match_path() after further consideration. Not sure
> about my style here, is it unnecessary to use new locals for advancing
> the pattern pointer/decreasing the length?
I don't think it matters much. One reason in favour of local variables
is that it makes debugging a bit it easier because we can then always
see which values the arguments had when the function was entered.
> I note that `got import` references ignore patterns but the patterns
> given as -I params are not matched the same way. Maybe `got import`
> should respect .gitignore/.cvsignore?
Ideally, -I matching would use the same semantics as ignore files.
The reason that repository.c has its own copy of match_ignores() is likely
because I wanted to avoid a dependency of repository.c on worktree.c.
And then the 2 match_ignore() implementations grew out of sync over time.
Perhaps moving the implementation to lib/ignores.c and making both sides
call into that would be best. But let's deal with your current patch first.
> Happy to split this up a bit if it makes review easier, most of the
> diffstat is from the man page reworks.
I have one small suggestion for your patch. In any case, your patch
looks very good to me.
> /*
> + * For gitignore(7) compatibility, ignore leading slashes
> + */
> + if (len > 0 && pat[0] == '/') {
> + pat++;
> + len--;
> + }
If the above was a while-loop instead of an if-statement then you could
do the following in your test and the test would keep passing:
> +test_status_gitignore_leading_slashes() {
> + echo "/foo" > $testroot/wt/.gitignore
echo "//////nu" >> $testroot/wt/.gitignore
> + echo '? .gitignore' > $testroot/stdout.expected
> + echo '? epsilon/bar' >> $testroot/stdout.expected
> + echo '? epsilon/foo' >> $testroot/stdout.expected
> + echo '? epsilon/nu/baz' >> $testroot/stdout.expected
> + (cd $testroot/wt && got status > $testroot/stdout)
> +
> + cmp -s $testroot/stdout.expected $testroot/stdout
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + diff -u $testroot/stdout.expected $testroot/stdout
> + fi
> + test_done "$testroot" "$ret"
> +}
leading separators in ignore patterns