Download raw body.
ignored files can't handle trailing slashes
On 23-02-19 09:40PM, Stefan Sperling wrote: > On Sun, Feb 05, 2023 at 02:05:30PM +0000, Lucas wrote: > > Hello list, > > > > As I shared on IRC, when `got import -I dir/` is used, `dir/` is *not* > > ignored: fnmatch is called with the name in dirent's d_name, which > > doesn't include a trailing slash if the entry is of type directory. > > Do note that calling got_path_strip_trailing_slashes on `-I` argument > > is not an option: 'dir*/' can have some nasty side effects. The patch > > for regress/cmdline/import.sh below makes this explicit. > > > > Same can be observed for .{cvs,git}ignore. > > This patch fixes the same problem for 'got status'. ok? Nice, ok! > "return FNM_NOMATCH; /* XXX */" in the diff is because there is no way > to return struct got_error from within this function without further > refactoring. I think that is fine for now because paths longer than > PATH_MAX can probably not even be checked out, and such long patterns > will be very rare if they exist at all. Yes, agreed. I think this is fine. > make 'got status' ignore patterns with trailing slashes match on directories > > diff d0f874e072cfb4119033a71b9f162ae02eca44ab a6e726d31e2e25a79e7f5d4b6b747d2778b15c5d > commit - d0f874e072cfb4119033a71b9f162ae02eca44ab > commit + a6e726d31e2e25a79e7f5d4b6b747d2778b15c5d > blob - b6cc16e8e5a4b02bf33a4f2af21bc0fd0f58c4bd > blob + 06d9ba522ae0001bd8bb697df46c9c952023dd09 > --- got/got.1 > +++ got/got.1 > @@ -788,6 +788,9 @@ As an extension to > .Pa .gitignore > files in each traversed directory and will not display unversioned files > which match these patterns. > +Ignore patterns which end with a slash, > +.Dq / , > +will only match directories. > As an extension to > .Xr glob 7 > matching rules, > blob - 2d75c470b84a9c0f07ca7ccd39595267ab24fd49 > blob + a5e3af7acc609d51f0bd553fae407d173c3df895 > --- lib/worktree.c > +++ lib/worktree.c > @@ -3559,6 +3559,26 @@ match_ignores(struct got_pathlist_head *ignores, const > } > > static int > +match_path(const char *pattern, size_t pattern_len, const char *path, > + int flags) > +{ > + char buf[PATH_MAX]; > + > + /* > + * Trailing slashes signify directories. > + * Append a * to make such patterns conform to fnmatch rules. > + */ > + if (pattern_len > 0 && pattern[pattern_len - 1] == '/') { > + if (snprintf(buf, sizeof(buf), "%s*", pattern) >= sizeof(buf)) > + return FNM_NOMATCH; /* XXX */ > + > + return fnmatch(buf, path, flags); > + } > + > + return fnmatch(pattern, path, flags); > +} > + > +static int > match_ignores(struct got_pathlist_head *ignores, const char *path) > { > struct got_pathlist_entry *pe; > @@ -3569,14 +3589,15 @@ match_ignores(struct got_pathlist_head *ignores, const > struct got_pathlist_entry *pi; > > TAILQ_FOREACH(pi, ignorelist, entry) { > - const char *p, *pattern = pi->path; > + const char *p; > > - if (strncmp(pattern, "**/", 3) != 0) > + if (pi->path_len < 3 || > + strncmp(pi->path, "**/", 3) != 0) > continue; > - pattern += 3; > p = path; > while (*p) { > - if (fnmatch(pattern, p, > + if (match_path(pi->path + 3, > + pi->path_len - 3, p, > FNM_PATHNAME | FNM_LEADING_DIR)) { > /* Retry in next directory. */ > while (*p && *p != '/') > @@ -3601,11 +3622,11 @@ match_ignores(struct got_pathlist_head *ignores, const > struct got_pathlist_head *ignorelist = pe->data; > struct got_pathlist_entry *pi; > TAILQ_FOREACH(pi, ignorelist, entry) { > - const char *pattern = pi->path; > int flags = FNM_LEADING_DIR; > - if (strstr(pattern, "/**/") == NULL) > + if (strstr(pi->path, "/**/") == NULL) > flags |= FNM_PATHNAME; > - if (fnmatch(pattern, path, flags)) > + if (match_path(pi->path, pi->path_len, > + path, flags)) > continue; > return 1; > } > blob - f992b65b13667e8a421e2e410937179db7c27aac > blob + f2d3d5dfe1904cd50bfc165b2d05f293cb4fad5f > --- regress/cmdline/status.sh > +++ regress/cmdline/status.sh > @@ -709,17 +709,20 @@ test_status_gitignore_trailing_slashes() { > echo "unversioned file" > $testroot/wt/epsilon/bar > echo "unversioned file" > $testroot/wt/epsilon/boo > echo "unversioned file" > $testroot/wt/epsilon/moo > - echo "epsilon/" > $testroot/wt/.gitignore > + echo "unversioned file" > $testroot/wt/upsilon > > + # Match the directory epsilon but not the regular file upsilon > + echo "*psilon/" > $testroot/wt/.gitignore > + > echo '? .gitignore' > $testroot/stdout.expected > echo '? foo' >> $testroot/stdout.expected > + echo '? upsilon' >> $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 > - ret="xfail trailing slashes not matched" > + diff -u $testroot/stdout.expected $testroot/stdout > fi > test_done "$testroot" "$ret" > } > -- Mark Jamsek <fnc.bsdbox.org|got.bsdbox.org> GPG: F2FF 13DE 6A06 C471 CA80 E6E2 2930 DC66 86EE CF68
ignored files can't handle trailing slashes