4747#include "csum-file.h"
4848#include "promisor-remote.h"
4949#include "hook.h"
50+ #include "submodule.h"
51+ #include "submodule-config.h"
52+ #include "advice.h"
5053
5154/* Mask for the name length in ce_flags in the on-disk index */
5255
@@ -3889,9 +3892,12 @@ void overlay_tree_on_index(struct index_state *istate,
38893892
38903893struct update_callback_data {
38913894 struct index_state * index ;
3895+ struct repository * repo ;
3896+ struct pathspec * pathspec ;
38923897 int include_sparse ;
38933898 int flags ;
38943899 int add_errors ;
3900+ int ignored_too ;
38953901};
38963902
38973903static int fix_unmerged_status (struct diff_filepair * p ,
@@ -3915,8 +3921,68 @@ static int fix_unmerged_status(struct diff_filepair *p,
39153921 return DIFF_STATUS_MODIFIED ;
39163922}
39173923
3924+ static int skip_submodule (const char * path ,
3925+ struct repository * repo ,
3926+ struct pathspec * pathspec ,
3927+ int ignored_too )
3928+ {
3929+ struct stat st ;
3930+ const struct submodule * sub ;
3931+ int pathspec_matches = 0 ;
3932+ int ps_i ;
3933+ char * norm_pathspec = NULL ;
3934+
3935+ /* Only consider if path is a directory */
3936+ if (lstat (path , & st ) || !S_ISDIR (st .st_mode ))
3937+ return 0 ;
3938+
3939+ /* Check if it's a submodule with ignore=all */
3940+ sub = submodule_from_path (repo , null_oid (the_hash_algo ), path );
3941+ if (!sub || !sub -> name || !sub -> ignore || strcmp (sub -> ignore , "all" ))
3942+ return 0 ;
3943+
3944+ trace_printf ("ignore=all: %s\n" , path );
3945+ trace_printf ("pathspec %s\n" , (pathspec && pathspec -> nr )
3946+ ? "has pathspec"
3947+ : "no pathspec" );
3948+
3949+ /* Check if submodule path is explicitly mentioned in pathspec */
3950+ if (pathspec ) {
3951+ for (ps_i = 0 ; ps_i < pathspec -> nr ; ps_i ++ ) {
3952+ const char * m = pathspec -> items [ps_i ].match ;
3953+ if (!m )
3954+ continue ;
3955+ norm_pathspec = xstrdup (m );
3956+ strip_dir_trailing_slashes (norm_pathspec );
3957+ if (!strcmp (path , norm_pathspec )) {
3958+ pathspec_matches = 1 ;
3959+ FREE_AND_NULL (norm_pathspec );
3960+ break ;
3961+ }
3962+ FREE_AND_NULL (norm_pathspec );
3963+ }
3964+ }
3965+
3966+ /* If explicitly matched and forced, allow adding */
3967+ if (pathspec_matches ) {
3968+ if (ignored_too && ignored_too > 0 ) {
3969+ trace_printf ("Add submodule due to --force: %s\n" , path );
3970+ return 0 ;
3971+ } else {
3972+ advise_if_enabled (ADVICE_ADD_IGNORED_FILE ,
3973+ _ ("Skipping submodule due to ignore=all: %s\n"
3974+ "Use --force if you really want to add the submodule." ), path );
3975+ return 1 ;
3976+ }
3977+ }
3978+
3979+ /* No explicit pathspec match -> skip silently */
3980+ trace_printf ("Pathspec to submodule does not match explicitly: %s\n" , path );
3981+ return 1 ;
3982+ }
3983+
39183984static void update_callback (struct diff_queue_struct * q ,
3919- struct diff_options * opt UNUSED , void * cbdata )
3985+ struct diff_options * opt UNUSED , void * cbdata )
39203986{
39213987 int i ;
39223988 struct update_callback_data * data = cbdata ;
@@ -3926,14 +3992,19 @@ static void update_callback(struct diff_queue_struct *q,
39263992 const char * path = p -> one -> path ;
39273993
39283994 if (!data -> include_sparse &&
3929- !path_in_sparse_checkout (path , data -> index ))
3995+ !path_in_sparse_checkout (path , data -> index ))
39303996 continue ;
39313997
39323998 switch (fix_unmerged_status (p , data )) {
39333999 default :
39344000 die (_ ("unexpected diff status %c" ), p -> status );
39354001 case DIFF_STATUS_MODIFIED :
39364002 case DIFF_STATUS_TYPE_CHANGED :
4003+ if (skip_submodule (path , data -> repo ,
4004+ data -> pathspec ,
4005+ data -> ignored_too ))
4006+ continue ;
4007+
39374008 if (add_file_to_index (data -> index , path , data -> flags )) {
39384009 if (!(data -> flags & ADD_CACHE_IGNORE_ERRORS ))
39394010 die (_ ("updating files failed" ));
@@ -3954,7 +4025,7 @@ static void update_callback(struct diff_queue_struct *q,
39544025
39554026int add_files_to_cache (struct repository * repo , const char * prefix ,
39564027 const struct pathspec * pathspec , char * ps_matched ,
3957- int include_sparse , int flags )
4028+ int include_sparse , int flags , int ignored_too )
39584029{
39594030 struct odb_transaction * transaction ;
39604031 struct update_callback_data data ;
@@ -3964,6 +4035,9 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
39644035 data .index = repo -> index ;
39654036 data .include_sparse = include_sparse ;
39664037 data .flags = flags ;
4038+ data .repo = repo ;
4039+ data .ignored_too = ignored_too ;
4040+ data .pathspec = (struct pathspec * )pathspec ;
39674041
39684042 repo_init_revisions (repo , & rev , prefix );
39694043 setup_revisions (0 , NULL , & rev , NULL );
0 commit comments