2121#include "parse-options.h"
2222
2323static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF ;
24- static struct string_list changed_submodule_paths = STRING_LIST_INIT_DUP ;
24+ static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP ;
2525static int initialized_fetch_ref_tips ;
2626static struct oid_array ref_tips_before_fetch ;
2727static struct oid_array ref_tips_after_fetch ;
@@ -674,11 +674,11 @@ const struct submodule *submodule_from_ce(const struct cache_entry *ce)
674674}
675675
676676static struct oid_array * submodule_commits (struct string_list * submodules ,
677- const char * path )
677+ const char * name )
678678{
679679 struct string_list_item * item ;
680680
681- item = string_list_insert (submodules , path );
681+ item = string_list_insert (submodules , name );
682682 if (item -> util )
683683 return (struct oid_array * ) item -> util ;
684684
@@ -687,39 +687,67 @@ static struct oid_array *submodule_commits(struct string_list *submodules,
687687 return (struct oid_array * ) item -> util ;
688688}
689689
690+ struct collect_changed_submodules_cb_data {
691+ struct string_list * changed ;
692+ const struct object_id * commit_oid ;
693+ };
694+
695+ /*
696+ * this would normally be two functions: default_name_from_path() and
697+ * path_from_default_name(). Since the default name is the same as
698+ * the submodule path we can get away with just one function which only
699+ * checks whether there is a submodule in the working directory at that
700+ * location.
701+ */
702+ static const char * default_name_or_path (const char * path_or_name )
703+ {
704+ int error_code ;
705+
706+ if (!is_submodule_populated_gently (path_or_name , & error_code ))
707+ return NULL ;
708+
709+ return path_or_name ;
710+ }
711+
690712static void collect_changed_submodules_cb (struct diff_queue_struct * q ,
691713 struct diff_options * options ,
692714 void * data )
693715{
716+ struct collect_changed_submodules_cb_data * me = data ;
717+ struct string_list * changed = me -> changed ;
718+ const struct object_id * commit_oid = me -> commit_oid ;
694719 int i ;
695- struct string_list * changed = data ;
696720
697721 for (i = 0 ; i < q -> nr ; i ++ ) {
698722 struct diff_filepair * p = q -> queue [i ];
699723 struct oid_array * commits ;
724+ const struct submodule * submodule ;
725+ const char * name ;
726+
700727 if (!S_ISGITLINK (p -> two -> mode ))
701728 continue ;
702729
703- if (S_ISGITLINK (p -> one -> mode )) {
704- /*
705- * NEEDSWORK: We should honor the name configured in
706- * the .gitmodules file of the commit we are examining
707- * here to be able to correctly follow submodules
708- * being moved around.
709- */
710- commits = submodule_commits (changed , p -> two -> path );
711- oid_array_append (commits , & p -> two -> oid );
712- } else {
713- /* Submodule is new or was moved here */
714- /*
715- * NEEDSWORK: When the .git directories of submodules
716- * live inside the superprojects .git directory some
717- * day we should fetch new submodules directly into
718- * that location too when config or options request
719- * that so they can be checked out from there.
720- */
721- continue ;
730+ submodule = submodule_from_path (commit_oid , p -> two -> path );
731+ if (submodule )
732+ name = submodule -> name ;
733+ else {
734+ name = default_name_or_path (p -> two -> path );
735+ /* make sure name does not collide with existing one */
736+ submodule = submodule_from_name (commit_oid , name );
737+ if (submodule ) {
738+ warning ("Submodule in commit %s at path: "
739+ "'%s' collides with a submodule named "
740+ "the same. Skipping it." ,
741+ oid_to_hex (commit_oid ), name );
742+ name = NULL ;
743+ }
722744 }
745+
746+ if (!name )
747+ continue ;
748+
749+ commits = submodule_commits (changed , name );
750+ oid_array_append (commits , & p -> two -> oid );
723751 }
724752}
725753
@@ -742,11 +770,14 @@ static void collect_changed_submodules(struct string_list *changed,
742770
743771 while ((commit = get_revision (& rev ))) {
744772 struct rev_info diff_rev ;
773+ struct collect_changed_submodules_cb_data data ;
774+ data .changed = changed ;
775+ data .commit_oid = & commit -> object .oid ;
745776
746777 init_revisions (& diff_rev , NULL );
747778 diff_rev .diffopt .output_format |= DIFF_FORMAT_CALLBACK ;
748779 diff_rev .diffopt .format_callback = collect_changed_submodules_cb ;
749- diff_rev .diffopt .format_callback_data = changed ;
780+ diff_rev .diffopt .format_callback_data = & data ;
750781 diff_tree_combined_merge (commit , 1 , & diff_rev );
751782 }
752783
@@ -894,7 +925,7 @@ int find_unpushed_submodules(struct oid_array *commits,
894925 const char * remotes_name , struct string_list * needs_pushing )
895926{
896927 struct string_list submodules = STRING_LIST_INIT_DUP ;
897- struct string_list_item * submodule ;
928+ struct string_list_item * name ;
898929 struct argv_array argv = ARGV_ARRAY_INIT ;
899930
900931 /* argv.argv[0] will be ignored by setup_revisions */
@@ -905,9 +936,19 @@ int find_unpushed_submodules(struct oid_array *commits,
905936
906937 collect_changed_submodules (& submodules , & argv );
907938
908- for_each_string_list_item (submodule , & submodules ) {
909- struct oid_array * commits = submodule -> util ;
910- const char * path = submodule -> string ;
939+ for_each_string_list_item (name , & submodules ) {
940+ struct oid_array * commits = name -> util ;
941+ const struct submodule * submodule ;
942+ const char * path = NULL ;
943+
944+ submodule = submodule_from_name (& null_oid , name -> string );
945+ if (submodule )
946+ path = submodule -> path ;
947+ else
948+ path = default_name_or_path (name -> string );
949+
950+ if (!path )
951+ continue ;
911952
912953 if (submodule_needs_pushing (path , commits ))
913954 string_list_insert (needs_pushing , path );
@@ -1065,7 +1106,7 @@ static void calculate_changed_submodule_paths(void)
10651106{
10661107 struct argv_array argv = ARGV_ARRAY_INIT ;
10671108 struct string_list changed_submodules = STRING_LIST_INIT_DUP ;
1068- const struct string_list_item * item ;
1109+ const struct string_list_item * name ;
10691110
10701111 /* No need to check if there are no submodules configured */
10711112 if (!submodule_from_path (NULL , NULL ))
@@ -1080,16 +1121,26 @@ static void calculate_changed_submodule_paths(void)
10801121
10811122 /*
10821123 * Collect all submodules (whether checked out or not) for which new
1083- * commits have been recorded upstream in "changed_submodule_paths ".
1124+ * commits have been recorded upstream in "changed_submodule_names ".
10841125 */
10851126 collect_changed_submodules (& changed_submodules , & argv );
10861127
1087- for_each_string_list_item (item , & changed_submodules ) {
1088- struct oid_array * commits = item -> util ;
1089- const char * path = item -> string ;
1128+ for_each_string_list_item (name , & changed_submodules ) {
1129+ struct oid_array * commits = name -> util ;
1130+ const struct submodule * submodule ;
1131+ const char * path = NULL ;
1132+
1133+ submodule = submodule_from_name (& null_oid , name -> string );
1134+ if (submodule )
1135+ path = submodule -> path ;
1136+ else
1137+ path = default_name_or_path (name -> string );
1138+
1139+ if (!path )
1140+ continue ;
10901141
10911142 if (!submodule_has_commits (path , commits ))
1092- string_list_append (& changed_submodule_paths , path );
1143+ string_list_append (& changed_submodule_names , name -> string );
10931144 }
10941145
10951146 free_submodules_oids (& changed_submodules );
@@ -1136,6 +1187,31 @@ struct submodule_parallel_fetch {
11361187};
11371188#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
11381189
1190+ static int get_fetch_recurse_config (const struct submodule * submodule ,
1191+ struct submodule_parallel_fetch * spf )
1192+ {
1193+ if (spf -> command_line_option != RECURSE_SUBMODULES_DEFAULT )
1194+ return spf -> command_line_option ;
1195+
1196+ if (submodule ) {
1197+ char * key ;
1198+ const char * value ;
1199+
1200+ int fetch_recurse = submodule -> fetch_recurse ;
1201+ key = xstrfmt ("submodule.%s.fetchRecurseSubmodules" , submodule -> name );
1202+ if (!repo_config_get_string_const (the_repository , key , & value )) {
1203+ fetch_recurse = parse_fetch_recurse_submodules_arg (key , value );
1204+ }
1205+ free (key );
1206+
1207+ if (fetch_recurse != RECURSE_SUBMODULES_NONE )
1208+ /* local config overrules everything except commandline */
1209+ return fetch_recurse ;
1210+ }
1211+
1212+ return spf -> default_option ;
1213+ }
1214+
11391215static int get_next_submodule (struct child_process * cp ,
11401216 struct strbuf * err , void * data , void * * task_cb )
11411217{
@@ -1149,49 +1225,35 @@ static int get_next_submodule(struct child_process *cp,
11491225 const struct cache_entry * ce = active_cache [spf -> count ];
11501226 const char * git_dir , * default_argv ;
11511227 const struct submodule * submodule ;
1228+ struct submodule default_submodule = SUBMODULE_INIT ;
11521229
11531230 if (!S_ISGITLINK (ce -> ce_mode ))
11541231 continue ;
11551232
11561233 submodule = submodule_from_path (& null_oid , ce -> name );
1157-
1158- default_argv = "yes" ;
1159- if (spf -> command_line_option == RECURSE_SUBMODULES_DEFAULT ) {
1160- int fetch_recurse = RECURSE_SUBMODULES_NONE ;
1161-
1162- if (submodule ) {
1163- char * key ;
1164- const char * value ;
1165-
1166- fetch_recurse = submodule -> fetch_recurse ;
1167- key = xstrfmt ("submodule.%s.fetchRecurseSubmodules" , submodule -> name );
1168- if (!repo_config_get_string_const (the_repository , key , & value )) {
1169- fetch_recurse = parse_fetch_recurse_submodules_arg (key , value );
1170- }
1171- free (key );
1234+ if (!submodule ) {
1235+ const char * name = default_name_or_path (ce -> name );
1236+ if (name ) {
1237+ default_submodule .path = default_submodule .name = name ;
1238+ submodule = & default_submodule ;
11721239 }
1240+ }
11731241
1174- if (fetch_recurse != RECURSE_SUBMODULES_NONE ) {
1175- if (fetch_recurse == RECURSE_SUBMODULES_OFF )
1176- continue ;
1177- if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND ) {
1178- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1179- continue ;
1180- default_argv = "on-demand" ;
1181- }
1182- } else {
1183- if (spf -> default_option == RECURSE_SUBMODULES_OFF )
1184- continue ;
1185- if (spf -> default_option == RECURSE_SUBMODULES_ON_DEMAND ) {
1186- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1187- continue ;
1188- default_argv = "on-demand" ;
1189- }
1190- }
1191- } else if (spf -> command_line_option == RECURSE_SUBMODULES_ON_DEMAND ) {
1192- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1242+ switch (get_fetch_recurse_config (submodule , spf ))
1243+ {
1244+ default :
1245+ case RECURSE_SUBMODULES_DEFAULT :
1246+ case RECURSE_SUBMODULES_ON_DEMAND :
1247+ if (!submodule || !unsorted_string_list_lookup (& changed_submodule_names ,
1248+ submodule -> name ))
11931249 continue ;
11941250 default_argv = "on-demand" ;
1251+ break ;
1252+ case RECURSE_SUBMODULES_ON :
1253+ default_argv = "yes" ;
1254+ break ;
1255+ case RECURSE_SUBMODULES_OFF :
1256+ continue ;
11951257 }
11961258
11971259 strbuf_addf (& submodule_path , "%s/%s" , spf -> work_tree , ce -> name );
@@ -1282,7 +1344,7 @@ int fetch_populated_submodules(const struct argv_array *options,
12821344
12831345 argv_array_clear (& spf .args );
12841346out :
1285- string_list_clear (& changed_submodule_paths , 1 );
1347+ string_list_clear (& changed_submodule_names , 1 );
12861348 return spf .result ;
12871349}
12881350
0 commit comments