@@ -3887,6 +3887,7 @@ struct update_callback_data {
38873887 int flags ;
38883888 int ignored_too ;
38893889 int add_errors ;
3890+ struct pathspec * pathspec ;
38903891};
38913892
38923893static int fix_unmerged_status (struct diff_filepair * p ,
@@ -3920,26 +3921,51 @@ static void update_callback(struct diff_queue_struct *q,
39203921 struct diff_filepair * p = q -> queue [i ];
39213922 const char * path = p -> one -> path ;
39223923
3923- trace_printf ("File '%s'\n" , path );
3924-
39253924 if (!data -> include_sparse &&
39263925 !path_in_sparse_checkout (path , data -> index ))
39273926 continue ;
39283927
39293928 switch (fix_unmerged_status (p , data )) {
39303929 default :
39313930 die (_ ("unexpected diff status %c" ), p -> status );
3932- case DIFF_STATUS_MODIFIED :
3933- trace_printf ("diff modified '%s'\n" , path );
3931+ case DIFF_STATUS_MODIFIED : {
39343932 const struct submodule * sub = submodule_from_path (data -> repo , null_oid (the_hash_algo ), path );
3935- if ( sub && sub -> name && sub -> ignore && strcmp (sub -> ignore , "all" ) == 0 ) {
3936- trace_printf ("ignore=all %s\n" , path );
3937- if ( data -> ignored_too && data -> ignored_too > 0 ) {
3938- trace_printf ("Adding submodule even ignore=all is due to --force|-f: %s\n" , path );
3933+ if (sub && sub -> name && sub -> ignore && !strcmp (sub -> ignore , "all" )) {
3934+ int pathspec_matches = 0 ;
3935+ char * norm_pathspec = NULL ;
3936+ int ps_i ;
3937+ trace_printf ("ignore=all %s\n" , path );
3938+ trace_printf ("pathspec %s\n" ,
3939+ (data -> pathspec && data -> pathspec -> nr ) ? "has pathspec" : "no pathspec" );
3940+ /* Safely scan all pathspec items (q->nr may exceed pathspec->nr). */
3941+ if (data -> pathspec ) {
3942+ for (ps_i = 0 ; ps_i < data -> pathspec -> nr ; ps_i ++ ) {
3943+ const char * m = data -> pathspec -> items [ps_i ].match ;
3944+ if (!m )
3945+ continue ;
3946+ norm_pathspec = xstrdup (m );
3947+ strip_dir_trailing_slashes (norm_pathspec );
3948+ if (!strcmp (path , norm_pathspec )) {
3949+ pathspec_matches = 1 ;
3950+ free (norm_pathspec );
3951+ norm_pathspec = NULL ;
3952+ break ;
3953+ }
3954+ free (norm_pathspec );
3955+ norm_pathspec = NULL ;
3956+ }
3957+ }
3958+ if (pathspec_matches ) {
3959+ if (data -> ignored_too && data -> ignored_too > 0 ) {
3960+ trace_printf ("Forcing add of submodule ignored=all due to --force: %s\n" , path );
3961+ } else {
3962+ printf ("Skipping submodule due to ignore=all: %s\n" , path );
3963+ printf (" Use -f|--force if you really want to add the update to the index.\n" );
3964+ continue ;
3965+ }
39393966 } else {
3940- trace_printf ("Skipping submodule with ignore=all: %s\n" , path );
3941- trace_printf (" Use -f if you really want to add them." );
3942- /* Skip this path (submodule ignored) and move on to next diff pair */
3967+ /* No explicit pathspec match -> skip silently (or with trace). */
3968+ trace_printf ("pathspec does not match %s\n" , path );
39433969 continue ;
39443970 }
39453971 }
@@ -3949,6 +3975,7 @@ static void update_callback(struct diff_queue_struct *q,
39493975 data -> add_errors ++ ;
39503976 }
39513977 break ;
3978+ }
39523979 case DIFF_STATUS_DELETED :
39533980 if (data -> flags & ADD_CACHE_IGNORE_REMOVAL )
39543981 break ;
@@ -3972,8 +3999,9 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
39723999 data .index = repo -> index ;
39734000 data .include_sparse = include_sparse ;
39744001 data .flags = flags ;
3975- trace_printf ("DEBUG ignored_too=%d\n" , ignored_too );
39764002 data .ignored_too = ignored_too ;
4003+ data .pathspec = (struct pathspec * )pathspec ;
4004+
39774005
39784006 repo_init_revisions (repo , & rev , prefix );
39794007 setup_revisions (0 , NULL , & rev , NULL );
0 commit comments