@@ -364,7 +364,8 @@ static int match_pathspec_item(const struct index_state *istate,
364
364
return MATCHED_FNMATCH ;
365
365
366
366
/* 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 )) {
368
369
/* name is a literal prefix of the pathspec */
369
370
int offset = name [namelen - 1 ] == '/' ? 1 : 0 ;
370
371
if ((namelen < matchlen ) &&
@@ -401,6 +402,10 @@ static int match_pathspec_item(const struct index_state *istate,
401
402
}
402
403
403
404
/*
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
+ *
404
409
* Given a name and a list of pathspecs, returns the nature of the
405
410
* closest (i.e. most specific) match of the name to any of the
406
411
* pathspecs.
@@ -486,13 +491,12 @@ static int do_match_pathspec(const struct index_state *istate,
486
491
return retval ;
487
492
}
488
493
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 )
493
498
{
494
499
int positive , negative ;
495
- unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0 ;
496
500
positive = do_match_pathspec (istate , ps , name , namelen ,
497
501
prefix , seen , flags );
498
502
if (!(ps -> magic & PATHSPEC_EXCLUDE ) || !positive )
@@ -503,6 +507,16 @@ int match_pathspec(const struct index_state *istate,
503
507
return negative ? 0 : positive ;
504
508
}
505
509
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
+
506
520
/**
507
521
* Check if a submodule is a superset of the pathspec
508
522
*/
@@ -511,11 +525,11 @@ int submodule_path_match(const struct index_state *istate,
511
525
const char * submodule_name ,
512
526
char * seen )
513
527
{
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 );
519
533
return matched ;
520
534
}
521
535
@@ -1757,9 +1771,11 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1757
1771
* for matching patterns.
1758
1772
*/
1759
1773
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 );
1763
1779
if (!matches_how )
1764
1780
return path_none ;
1765
1781
}
@@ -2191,9 +2207,9 @@ static enum path_treatment treat_path(struct dir_struct *dir,
2191
2207
if (excluded )
2192
2208
return path_excluded ;
2193
2209
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 */ ))
2197
2213
return path_none ;
2198
2214
return path_untracked ;
2199
2215
}
0 commit comments