@@ -521,6 +521,7 @@ void add_exclude(const char *string, const char *base,
521
521
x -> baselen = baselen ;
522
522
x -> flags = flags ;
523
523
x -> srcpos = srcpos ;
524
+ string_list_init (& x -> sticky_paths , 1 );
524
525
ALLOC_GROW (el -> excludes , el -> nr + 1 , el -> alloc );
525
526
el -> excludes [el -> nr ++ ] = x ;
526
527
x -> el = el ;
@@ -561,8 +562,10 @@ void clear_exclude_list(struct exclude_list *el)
561
562
{
562
563
int i ;
563
564
564
- for (i = 0 ; i < el -> nr ; i ++ )
565
+ for (i = 0 ; i < el -> nr ; i ++ ) {
566
+ string_list_clear (& el -> excludes [i ]-> sticky_paths , 0 );
565
567
free (el -> excludes [i ]);
568
+ }
566
569
free (el -> excludes );
567
570
free (el -> filebuf );
568
571
@@ -889,6 +892,44 @@ int match_pathname(const char *pathname, int pathlen,
889
892
WM_PATHNAME ) == 0 ;
890
893
}
891
894
895
+ static void add_sticky (struct exclude * exc , const char * pathname , int pathlen )
896
+ {
897
+ struct strbuf sb = STRBUF_INIT ;
898
+ int i ;
899
+
900
+ for (i = exc -> sticky_paths .nr - 1 ; i >= 0 ; i -- ) {
901
+ const char * sticky = exc -> sticky_paths .items [i ].string ;
902
+ int len = strlen (sticky );
903
+
904
+ if (pathlen < len && sticky [pathlen ] == '/' &&
905
+ !strncmp (pathname , sticky , pathlen ))
906
+ return ;
907
+ }
908
+
909
+ strbuf_add (& sb , pathname , pathlen );
910
+ string_list_append_nodup (& exc -> sticky_paths , strbuf_detach (& sb , NULL ));
911
+ }
912
+
913
+ static int match_sticky (struct exclude * exc , const char * pathname , int pathlen , int dtype )
914
+ {
915
+ int i ;
916
+
917
+ for (i = exc -> sticky_paths .nr - 1 ; i >= 0 ; i -- ) {
918
+ const char * sticky = exc -> sticky_paths .items [i ].string ;
919
+ int len = strlen (sticky );
920
+
921
+ if (pathlen == len && dtype == DT_DIR &&
922
+ !strncmp (pathname , sticky , len ))
923
+ return 1 ;
924
+
925
+ if (pathlen > len && pathname [len ] == '/' &&
926
+ !strncmp (pathname , sticky , len ))
927
+ return 1 ;
928
+ }
929
+
930
+ return 0 ;
931
+ }
932
+
892
933
/*
893
934
* Scan the given exclude list in reverse to see whether pathname
894
935
* should be ignored. The first match (i.e. the last on the list), if
@@ -914,6 +955,16 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
914
955
const char * exclude = x -> pattern ;
915
956
int prefix = x -> nowildcardlen ;
916
957
958
+ if (x -> sticky_paths .nr ) {
959
+ if (* dtype == DT_UNKNOWN )
960
+ * dtype = get_dtype (NULL , pathname , pathlen );
961
+ if (match_sticky (x , pathname , pathlen , * dtype )) {
962
+ exc = x ;
963
+ break ;
964
+ }
965
+ continue ;
966
+ }
967
+
917
968
if (x -> flags & EXC_FLAG_MUSTBEDIR ) {
918
969
if (* dtype == DT_UNKNOWN )
919
970
* dtype = get_dtype (NULL , pathname , pathlen );
@@ -947,9 +998,10 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
947
998
return NULL ;
948
999
}
949
1000
950
- trace_printf_key (& trace_exclude , "exclude: %.*s vs %s at line %d => %s\n" ,
1001
+ trace_printf_key (& trace_exclude , "exclude: %.*s vs %s at line %d => %s%s \n" ,
951
1002
pathlen , pathname , exc -> pattern , exc -> srcpos ,
952
- exc -> flags & EXC_FLAG_NEGATIVE ? "no" : "yes" );
1003
+ exc -> flags & EXC_FLAG_NEGATIVE ? "no" : "yes" ,
1004
+ exc -> sticky_paths .nr ? " (stuck)" : "" );
953
1005
return exc ;
954
1006
}
955
1007
@@ -2005,6 +2057,25 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
2005
2057
return root ;
2006
2058
}
2007
2059
2060
+ static void clear_sticky (struct dir_struct * dir )
2061
+ {
2062
+ struct exclude_list_group * g ;
2063
+ struct exclude_list * el ;
2064
+ struct exclude * x ;
2065
+ int i , j , k ;
2066
+
2067
+ for (i = EXC_CMDL ; i <= EXC_FILE ; i ++ ) {
2068
+ g = & dir -> exclude_list_group [i ];
2069
+ for (j = g -> nr - 1 ; j >= 0 ; j -- ) {
2070
+ el = & g -> el [j ];
2071
+ for (k = el -> nr - 1 ; 0 <= k ; k -- ) {
2072
+ x = el -> excludes [k ];
2073
+ string_list_clear (& x -> sticky_paths , 0 );
2074
+ }
2075
+ }
2076
+ }
2077
+ }
2078
+
2008
2079
int read_directory (struct dir_struct * dir , const char * path , int len , const struct pathspec * pathspec )
2009
2080
{
2010
2081
struct path_simplify * simplify ;
0 commit comments