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 );
@@ -1149,11 +1200,19 @@ static int get_next_submodule(struct child_process *cp,
11491200 const struct cache_entry * ce = active_cache [spf -> count ];
11501201 const char * git_dir , * default_argv ;
11511202 const struct submodule * submodule ;
1203+ struct submodule default_submodule = SUBMODULE_INIT ;
11521204
11531205 if (!S_ISGITLINK (ce -> ce_mode ))
11541206 continue ;
11551207
11561208 submodule = submodule_from_path (& null_oid , ce -> name );
1209+ if (!submodule ) {
1210+ const char * name = default_name_or_path (ce -> name );
1211+ if (name ) {
1212+ default_submodule .path = default_submodule .name = name ;
1213+ submodule = & default_submodule ;
1214+ }
1215+ }
11571216
11581217 default_argv = "yes" ;
11591218 if (spf -> command_line_option == RECURSE_SUBMODULES_DEFAULT ) {
@@ -1175,21 +1234,24 @@ static int get_next_submodule(struct child_process *cp,
11751234 if (fetch_recurse == RECURSE_SUBMODULES_OFF )
11761235 continue ;
11771236 if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND ) {
1178- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1237+ if (!unsorted_string_list_lookup (& changed_submodule_names ,
1238+ submodule -> name ))
11791239 continue ;
11801240 default_argv = "on-demand" ;
11811241 }
11821242 } else {
11831243 if (spf -> default_option == RECURSE_SUBMODULES_OFF )
11841244 continue ;
11851245 if (spf -> default_option == RECURSE_SUBMODULES_ON_DEMAND ) {
1186- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1246+ if (!unsorted_string_list_lookup (& changed_submodule_names ,
1247+ submodule -> name ))
11871248 continue ;
11881249 default_argv = "on-demand" ;
11891250 }
11901251 }
11911252 } else if (spf -> command_line_option == RECURSE_SUBMODULES_ON_DEMAND ) {
1192- if (!unsorted_string_list_lookup (& changed_submodule_paths , ce -> name ))
1253+ if (!unsorted_string_list_lookup (& changed_submodule_names ,
1254+ submodule -> name ))
11931255 continue ;
11941256 default_argv = "on-demand" ;
11951257 }
@@ -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