@@ -387,8 +387,24 @@ struct merge_options_internal {
387387
388388 /* call_depth: recursion level counter for merging merge bases */
389389 int call_depth ;
390+
391+ /* field that holds submodule conflict information */
392+ struct string_list conflicted_submodules ;
393+ };
394+
395+ struct conflicted_submodule_item {
396+ char * abbrev ;
397+ int flag ;
390398};
391399
400+ static void conflicted_submodule_item_free (void * util , const char * str )
401+ {
402+ struct conflicted_submodule_item * item = util ;
403+
404+ free (item -> abbrev );
405+ free (item );
406+ }
407+
392408struct version_info {
393409 struct object_id oid ;
394410 unsigned short mode ;
@@ -517,6 +533,7 @@ enum conflict_and_info_types {
517533 CONFLICT_SUBMODULE_NOT_INITIALIZED ,
518534 CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE ,
519535 CONFLICT_SUBMODULE_MAY_HAVE_REWINDS ,
536+ CONFLICT_SUBMODULE_NULL_MERGE_BASE ,
520537
521538 /* Keep this entry _last_ in the list */
522539 NB_CONFLICT_TYPES ,
@@ -570,6 +587,8 @@ static const char *type_short_descriptions[] = {
570587 "CONFLICT (submodule history not available)" ,
571588 [CONFLICT_SUBMODULE_MAY_HAVE_REWINDS ] =
572589 "CONFLICT (submodule may have rewinds)" ,
590+ [CONFLICT_SUBMODULE_NULL_MERGE_BASE ] =
591+ "CONFLICT (submodule lacks merge base)"
573592};
574593
575594struct logical_conflict_info {
@@ -686,6 +705,9 @@ static void clear_or_reinit_internal_opts(struct merge_options_internal *opti,
686705
687706 mem_pool_discard (& opti -> pool , 0 );
688707
708+ string_list_clear_func (& opti -> conflicted_submodules ,
709+ conflicted_submodule_item_free );
710+
689711 /* Clean out callback_data as well. */
690712 FREE_AND_NULL (renames -> callback_data );
691713 renames -> callback_data_nr = renames -> callback_data_alloc = 0 ;
@@ -1744,24 +1766,32 @@ static int merge_submodule(struct merge_options *opt,
17441766
17451767 int i ;
17461768 int search = !opt -> priv -> call_depth ;
1769+ int sub_not_initialized = 1 ;
1770+ int sub_flag = CONFLICT_SUBMODULE_FAILED_TO_MERGE ;
17471771
17481772 /* store fallback answer in result in case we fail */
17491773 oidcpy (result , opt -> priv -> call_depth ? o : a );
17501774
17511775 /* we can not handle deletion conflicts */
1752- if (is_null_oid (o ))
1753- return 0 ;
1754- if (is_null_oid (a ))
1755- return 0 ;
1756- if (is_null_oid (b ))
1757- return 0 ;
1776+ if (is_null_oid (a ) || is_null_oid (b ))
1777+ BUG ("submodule deleted on one side; this should be handled outside of merge_submodule()" );
17581778
1759- if (repo_submodule_init (& subrepo , opt -> repo , path , null_oid ())) {
1779+ if ((sub_not_initialized = repo_submodule_init (& subrepo ,
1780+ opt -> repo , path , null_oid ()))) {
17601781 path_msg (opt , CONFLICT_SUBMODULE_NOT_INITIALIZED , 0 ,
17611782 path , NULL , NULL , NULL ,
17621783 _ ("Failed to merge submodule %s (not checked out)" ),
17631784 path );
1764- return 0 ;
1785+ sub_flag = CONFLICT_SUBMODULE_NOT_INITIALIZED ;
1786+ goto cleanup ;
1787+ }
1788+
1789+ if (is_null_oid (o )) {
1790+ path_msg (opt , CONFLICT_SUBMODULE_NULL_MERGE_BASE , 0 ,
1791+ path , NULL , NULL , NULL ,
1792+ _ ("Failed to merge submodule %s (no merge base)" ),
1793+ path );
1794+ goto cleanup ;
17651795 }
17661796
17671797 if (!(commit_o = lookup_commit_reference (& subrepo , o )) ||
@@ -1771,6 +1801,7 @@ static int merge_submodule(struct merge_options *opt,
17711801 path , NULL , NULL , NULL ,
17721802 _ ("Failed to merge submodule %s (commits not present)" ),
17731803 path );
1804+ sub_flag = CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE ;
17741805 goto cleanup ;
17751806 }
17761807
@@ -1849,7 +1880,23 @@ static int merge_submodule(struct merge_options *opt,
18491880
18501881 object_array_clear (& merges );
18511882cleanup :
1852- repo_clear (& subrepo );
1883+ if (!opt -> priv -> call_depth && !ret ) {
1884+ struct string_list * csub = & opt -> priv -> conflicted_submodules ;
1885+ struct conflicted_submodule_item * util ;
1886+ const char * abbrev ;
1887+
1888+ util = xmalloc (sizeof (* util ));
1889+ util -> flag = sub_flag ;
1890+ util -> abbrev = NULL ;
1891+ if (!sub_not_initialized ) {
1892+ abbrev = repo_find_unique_abbrev (& subrepo , b , DEFAULT_ABBREV );
1893+ util -> abbrev = xstrdup (abbrev );
1894+ }
1895+ string_list_append (csub , path )-> util = util ;
1896+ }
1897+
1898+ if (!sub_not_initialized )
1899+ repo_clear (& subrepo );
18531900 return ret ;
18541901}
18551902
@@ -4434,6 +4481,63 @@ static int record_conflicted_index_entries(struct merge_options *opt)
44344481 return errs ;
44354482}
44364483
4484+ static void print_submodule_conflict_suggestion (struct string_list * csub ) {
4485+ struct string_list_item * item ;
4486+ struct strbuf msg = STRBUF_INIT ;
4487+ struct strbuf tmp = STRBUF_INIT ;
4488+ struct strbuf subs = STRBUF_INIT ;
4489+
4490+ if (!csub -> nr )
4491+ return ;
4492+
4493+ strbuf_add_separated_string_list (& subs , " " , csub );
4494+ for_each_string_list_item (item , csub ) {
4495+ struct conflicted_submodule_item * util = item -> util ;
4496+
4497+ /*
4498+ * NEEDSWORK: The steps to resolve these errors deserve a more
4499+ * detailed explanation than what is currently printed below.
4500+ */
4501+ if (util -> flag == CONFLICT_SUBMODULE_NOT_INITIALIZED ||
4502+ util -> flag == CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE )
4503+ continue ;
4504+
4505+ /*
4506+ * TRANSLATORS: This is a line of advice to resolve a merge
4507+ * conflict in a submodule. The first argument is the submodule
4508+ * name, and the second argument is the abbreviated id of the
4509+ * commit that needs to be merged. For example:
4510+ * - go to submodule (mysubmodule), and either merge commit abc1234"
4511+ */
4512+ strbuf_addf (& tmp , _ (" - go to submodule (%s), and either merge commit %s\n"
4513+ " or update to an existing commit which has merged those changes\n" ),
4514+ item -> string , util -> abbrev );
4515+ }
4516+
4517+ /*
4518+ * TRANSLATORS: This is a detailed message for resolving submodule
4519+ * conflicts. The first argument is string containing one step per
4520+ * submodule. The second is a space-separated list of submodule names.
4521+ */
4522+ strbuf_addf (& msg ,
4523+ _ ("Recursive merging with submodules currently only supports trivial cases.\n"
4524+ "Please manually handle the merging of each conflicted submodule.\n"
4525+ "This can be accomplished with the following steps:\n"
4526+ "%s"
4527+ " - come back to superproject and run:\n\n"
4528+ " git add %s\n\n"
4529+ " to record the above merge or update\n"
4530+ " - resolve any other conflicts in the superproject\n"
4531+ " - commit the resulting index in the superproject\n" ),
4532+ tmp .buf , subs .buf );
4533+
4534+ printf ("%s" , msg .buf );
4535+
4536+ strbuf_release (& subs );
4537+ strbuf_release (& tmp );
4538+ strbuf_release (& msg );
4539+ }
4540+
44374541void merge_display_update_messages (struct merge_options * opt ,
44384542 int detailed ,
44394543 struct merge_result * result )
@@ -4483,6 +4587,8 @@ void merge_display_update_messages(struct merge_options *opt,
44834587 }
44844588 string_list_clear (& olist , 0 );
44854589
4590+ print_submodule_conflict_suggestion (& opti -> conflicted_submodules );
4591+
44864592 /* Also include needed rename limit adjustment now */
44874593 diff_warn_rename_limit ("merge.renamelimit" ,
44884594 opti -> renames .needed_limit , 0 );
@@ -4684,6 +4790,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
46844790 trace2_region_enter ("merge" , "allocate/init" , opt -> repo );
46854791 if (opt -> priv ) {
46864792 clear_or_reinit_internal_opts (opt -> priv , 1 );
4793+ string_list_init_nodup (& opt -> priv -> conflicted_submodules );
46874794 trace2_region_leave ("merge" , "allocate/init" , opt -> repo );
46884795 return ;
46894796 }
0 commit comments