@@ -364,7 +364,8 @@ static int match_pathspec_item(const struct index_state *istate,
364364 return MATCHED_FNMATCH ;
365365
366366 /* Perform checks to see if "name" is a leading string of the pathspec */
367- if (flags & DO_MATCH_LEADING_PATHSPEC ) {
367+ if ( (flags & DO_MATCH_LEADING_PATHSPEC ) &&
368+ !(flags & DO_MATCH_EXCLUDE )) {
368369 /* name is a literal prefix of the pathspec */
369370 int offset = name [namelen - 1 ] == '/' ? 1 : 0 ;
370371 if ((namelen < matchlen ) &&
@@ -401,6 +402,10 @@ static int match_pathspec_item(const struct index_state *istate,
401402}
402403
403404/*
405+ * do_match_pathspec() is meant to ONLY be called by
406+ * match_pathspec_with_flags(); calling it directly risks pathspecs
407+ * like ':!unwanted_path' being ignored.
408+ *
404409 * Given a name and a list of pathspecs, returns the nature of the
405410 * closest (i.e. most specific) match of the name to any of the
406411 * pathspecs.
@@ -486,13 +491,12 @@ static int do_match_pathspec(const struct index_state *istate,
486491 return retval ;
487492}
488493
489- int match_pathspec (const struct index_state * istate ,
490- const struct pathspec * ps ,
491- const char * name , int namelen ,
492- int prefix , char * seen , int is_dir )
494+ static int match_pathspec_with_flags (const struct index_state * istate ,
495+ const struct pathspec * ps ,
496+ const char * name , int namelen ,
497+ int prefix , char * seen , unsigned flags )
493498{
494499 int positive , negative ;
495- unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0 ;
496500 positive = do_match_pathspec (istate , ps , name , namelen ,
497501 prefix , seen , flags );
498502 if (!(ps -> magic & PATHSPEC_EXCLUDE ) || !positive )
@@ -503,6 +507,16 @@ int match_pathspec(const struct index_state *istate,
503507 return negative ? 0 : positive ;
504508}
505509
510+ int match_pathspec (const struct index_state * istate ,
511+ const struct pathspec * ps ,
512+ const char * name , int namelen ,
513+ int prefix , char * seen , int is_dir )
514+ {
515+ unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0 ;
516+ return match_pathspec_with_flags (istate , ps , name , namelen ,
517+ prefix , seen , flags );
518+ }
519+
506520/**
507521 * Check if a submodule is a superset of the pathspec
508522 */
@@ -511,11 +525,11 @@ int submodule_path_match(const struct index_state *istate,
511525 const char * submodule_name ,
512526 char * seen )
513527{
514- int matched = do_match_pathspec (istate , ps , submodule_name ,
515- strlen (submodule_name ),
516- 0 , seen ,
517- DO_MATCH_DIRECTORY |
518- DO_MATCH_LEADING_PATHSPEC );
528+ int matched = match_pathspec_with_flags (istate , ps , submodule_name ,
529+ strlen (submodule_name ),
530+ 0 , seen ,
531+ DO_MATCH_DIRECTORY |
532+ DO_MATCH_LEADING_PATHSPEC );
519533 return matched ;
520534}
521535
@@ -1757,9 +1771,11 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
17571771 * for matching patterns.
17581772 */
17591773 if (pathspec && !excluded ) {
1760- matches_how = do_match_pathspec (istate , pathspec , dirname , len ,
1761- 0 /* prefix */ , NULL /* seen */ ,
1762- DO_MATCH_LEADING_PATHSPEC );
1774+ matches_how = match_pathspec_with_flags (istate , pathspec ,
1775+ dirname , len ,
1776+ 0 /* prefix */ ,
1777+ NULL /* seen */ ,
1778+ DO_MATCH_LEADING_PATHSPEC );
17631779 if (!matches_how )
17641780 return path_none ;
17651781 }
@@ -2191,9 +2207,9 @@ static enum path_treatment treat_path(struct dir_struct *dir,
21912207 if (excluded )
21922208 return path_excluded ;
21932209 if (pathspec &&
2194- !do_match_pathspec (istate , pathspec , path -> buf , path -> len ,
2195- 0 /* prefix */ , NULL /* seen */ ,
2196- 0 /* flags */ ))
2210+ !match_pathspec (istate , pathspec , path -> buf , path -> len ,
2211+ 0 /* prefix */ , NULL /* seen */ ,
2212+ 0 /* is_dir */ ))
21972213 return path_none ;
21982214 return path_untracked ;
21992215 }
0 commit comments