@@ -545,17 +545,35 @@ enum conflict_and_info_types {
545545 CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE ,
546546 CONFLICT_SUBMODULE_MAY_HAVE_REWINDS ,
547547 CONFLICT_SUBMODULE_NULL_MERGE_BASE ,
548- CONFLICT_SUBMODULE_CORRUPT ,
548+
549+ /* INSERT NEW ENTRIES HERE */
550+
551+ /*
552+ * Keep this entry after all regular conflict and info types; only
553+ * errors (failures causing immediate abort of the merge) should
554+ * come after this.
555+ */
556+ NB_REGULAR_CONFLICT_TYPES ,
557+
558+ /*
559+ * Something is seriously wrong; cannot even perform merge;
560+ * Keep this group _last_ other than NB_TOTAL_TYPES
561+ */
562+ ERROR_SUBMODULE_CORRUPT ,
563+ ERROR_THREEWAY_CONTENT_MERGE_FAILED ,
564+ ERROR_OBJECT_WRITE_FAILED ,
565+ ERROR_OBJECT_READ_FAILED ,
566+ ERROR_OBJECT_NOT_A_BLOB ,
549567
550568 /* Keep this entry _last_ in the list */
551- NB_CONFLICT_TYPES ,
569+ NB_TOTAL_TYPES ,
552570};
553571
554572/*
555573 * Short description of conflict type, relied upon by external tools.
556574 *
557575 * We can add more entries, but DO NOT change any of these strings. Also,
558- * Order MUST match conflict_info_and_types.
576+ * please ensure the order matches what is used in conflict_info_and_types.
559577 */
560578static const char * type_short_descriptions [] = {
561579 /*** "Simple" conflicts and informational messages ***/
@@ -599,8 +617,18 @@ static const char *type_short_descriptions[] = {
599617 "CONFLICT (submodule may have rewinds)" ,
600618 [CONFLICT_SUBMODULE_NULL_MERGE_BASE ] =
601619 "CONFLICT (submodule lacks merge base)" ,
602- [CONFLICT_SUBMODULE_CORRUPT ] =
603- "CONFLICT (submodule corrupt)"
620+
621+ /* Something is seriously wrong; cannot even perform merge */
622+ [ERROR_SUBMODULE_CORRUPT ] =
623+ "ERROR (submodule corrupt)" ,
624+ [ERROR_THREEWAY_CONTENT_MERGE_FAILED ] =
625+ "ERROR (three-way content merge failed)" ,
626+ [ERROR_OBJECT_WRITE_FAILED ] =
627+ "ERROR (object write failed)" ,
628+ [ERROR_OBJECT_READ_FAILED ] =
629+ "ERROR (object read failed)" ,
630+ [ERROR_OBJECT_NOT_A_BLOB ] =
631+ "ERROR (object is not a blob)" ,
604632};
605633
606634struct logical_conflict_info {
@@ -764,7 +792,8 @@ static void path_msg(struct merge_options *opt,
764792
765793 /* Sanity checks */
766794 assert (omittable_hint ==
767- !starts_with (type_short_descriptions [type ], "CONFLICT" ) ||
795+ (!starts_with (type_short_descriptions [type ], "CONFLICT" ) &&
796+ !starts_with (type_short_descriptions [type ], "ERROR" )) ||
768797 type == CONFLICT_DIR_RENAME_SUGGESTED );
769798 if (opt -> record_conflict_msgs_as_headers && omittable_hint )
770799 return ; /* Do not record mere hints in headers */
@@ -1819,9 +1848,9 @@ static int merge_submodule(struct merge_options *opt,
18191848 /* check whether both changes are forward */
18201849 ret2 = repo_in_merge_bases (& subrepo , commit_o , commit_a );
18211850 if (ret2 < 0 ) {
1822- path_msg (opt , CONFLICT_SUBMODULE_CORRUPT , 0 ,
1851+ path_msg (opt , ERROR_SUBMODULE_CORRUPT , 0 ,
18231852 path , NULL , NULL , NULL ,
1824- _ ("Failed to merge submodule %s "
1853+ _ ("error: failed to merge submodule %s "
18251854 "(repository corrupt)" ),
18261855 path );
18271856 ret = -1 ;
@@ -1830,9 +1859,9 @@ static int merge_submodule(struct merge_options *opt,
18301859 if (ret2 > 0 )
18311860 ret2 = repo_in_merge_bases (& subrepo , commit_o , commit_b );
18321861 if (ret2 < 0 ) {
1833- path_msg (opt , CONFLICT_SUBMODULE_CORRUPT , 0 ,
1862+ path_msg (opt , ERROR_SUBMODULE_CORRUPT , 0 ,
18341863 path , NULL , NULL , NULL ,
1835- _ ("Failed to merge submodule %s "
1864+ _ ("error: failed to merge submodule %s "
18361865 "(repository corrupt)" ),
18371866 path );
18381867 ret = -1 ;
@@ -1850,9 +1879,9 @@ static int merge_submodule(struct merge_options *opt,
18501879 /* Case #1: a is contained in b or vice versa */
18511880 ret2 = repo_in_merge_bases (& subrepo , commit_a , commit_b );
18521881 if (ret2 < 0 ) {
1853- path_msg (opt , CONFLICT_SUBMODULE_CORRUPT , 0 ,
1882+ path_msg (opt , ERROR_SUBMODULE_CORRUPT , 0 ,
18541883 path , NULL , NULL , NULL ,
1855- _ ("Failed to merge submodule %s "
1884+ _ ("error: failed to merge submodule %s "
18561885 "(repository corrupt)" ),
18571886 path );
18581887 ret = -1 ;
@@ -1869,9 +1898,9 @@ static int merge_submodule(struct merge_options *opt,
18691898 }
18701899 ret2 = repo_in_merge_bases (& subrepo , commit_b , commit_a );
18711900 if (ret2 < 0 ) {
1872- path_msg (opt , CONFLICT_SUBMODULE_CORRUPT , 0 ,
1901+ path_msg (opt , ERROR_SUBMODULE_CORRUPT , 0 ,
18731902 path , NULL , NULL , NULL ,
1874- _ ("Failed to merge submodule %s "
1903+ _ ("error: failed to merge submodule %s "
18751904 "(repository corrupt)" ),
18761905 path );
18771906 ret = -1 ;
@@ -1903,9 +1932,9 @@ static int merge_submodule(struct merge_options *opt,
19031932 & merges );
19041933 switch (parent_count ) {
19051934 case -1 :
1906- path_msg (opt , CONFLICT_SUBMODULE_CORRUPT , 0 ,
1935+ path_msg (opt , ERROR_SUBMODULE_CORRUPT , 0 ,
19071936 path , NULL , NULL , NULL ,
1908- _ ("Failed to merge submodule %s "
1937+ _ ("error: failed to merge submodule %s "
19091938 "(repository corrupt)" ),
19101939 path );
19111940 ret = -1 ;
@@ -2111,7 +2140,7 @@ static int handle_content_merge(struct merge_options *opt,
21112140 * merges, which happens for example with rename/rename(2to1) and
21122141 * rename/add conflicts.
21132142 */
2114- unsigned clean = 1 ;
2143+ int clean = 1 ;
21152144
21162145 /*
21172146 * handle_content_merge() needs both files to be of the same type, i.e.
@@ -2175,25 +2204,37 @@ static int handle_content_merge(struct merge_options *opt,
21752204 pathnames , extra_marker_size ,
21762205 & result_buf );
21772206
2178- if ((merge_status < 0 ) || !result_buf .ptr )
2179- ret = error (_ ("failed to execute internal merge" ));
2207+ if ((merge_status < 0 ) || !result_buf .ptr ) {
2208+ path_msg (opt , ERROR_THREEWAY_CONTENT_MERGE_FAILED , 0 ,
2209+ pathnames [0 ], pathnames [1 ], pathnames [2 ], NULL ,
2210+ _ ("error: failed to execute internal merge for %s" ),
2211+ path );
2212+ ret = -1 ;
2213+ }
21802214
21812215 if (!ret &&
21822216 write_object_file (result_buf .ptr , result_buf .size ,
2183- OBJ_BLOB , & result -> oid ))
2184- ret = error (_ ("unable to add %s to database" ), path );
2185-
2217+ OBJ_BLOB , & result -> oid )) {
2218+ path_msg (opt , ERROR_OBJECT_WRITE_FAILED , 0 ,
2219+ pathnames [0 ], pathnames [1 ], pathnames [2 ], NULL ,
2220+ _ ("error: unable to add %s to database" ), path );
2221+ ret = -1 ;
2222+ }
21862223 free (result_buf .ptr );
2224+
21872225 if (ret )
21882226 return -1 ;
2189- clean &= (merge_status == 0 );
2227+ if (merge_status > 0 )
2228+ clean = 0 ;
21902229 path_msg (opt , INFO_AUTO_MERGING , 1 , path , NULL , NULL , NULL ,
21912230 _ ("Auto-merging %s" ), path );
21922231 } else if (S_ISGITLINK (a -> mode )) {
21932232 int two_way = ((S_IFMT & o -> mode ) != (S_IFMT & a -> mode ));
21942233 clean = merge_submodule (opt , pathnames [0 ],
21952234 two_way ? null_oid () : & o -> oid ,
21962235 & a -> oid , & b -> oid , & result -> oid );
2236+ if (clean < 0 )
2237+ return -1 ;
21972238 if (opt -> priv -> call_depth && two_way && !clean ) {
21982239 result -> mode = o -> mode ;
21992240 oidcpy (& result -> oid , & o -> oid );
@@ -3559,18 +3600,27 @@ static int sort_dirs_next_to_their_children(const char *one, const char *two)
35593600 return c1 - c2 ;
35603601}
35613602
3562- static int read_oid_strbuf (const struct object_id * oid ,
3563- struct strbuf * dst )
3603+ static int read_oid_strbuf (struct merge_options * opt ,
3604+ const struct object_id * oid ,
3605+ struct strbuf * dst ,
3606+ const char * path )
35643607{
35653608 void * buf ;
35663609 enum object_type type ;
35673610 unsigned long size ;
35683611 buf = repo_read_object_file (the_repository , oid , & type , & size );
3569- if (!buf )
3570- return error (_ ("cannot read object %s" ), oid_to_hex (oid ));
3612+ if (!buf ) {
3613+ path_msg (opt , ERROR_OBJECT_READ_FAILED , 0 ,
3614+ path , NULL , NULL , NULL ,
3615+ _ ("error: cannot read object %s" ), oid_to_hex (oid ));
3616+ return -1 ;
3617+ }
35713618 if (type != OBJ_BLOB ) {
35723619 free (buf );
3573- return error (_ ("object %s is not a blob" ), oid_to_hex (oid ));
3620+ path_msg (opt , ERROR_OBJECT_NOT_A_BLOB , 0 ,
3621+ path , NULL , NULL , NULL ,
3622+ _ ("error: object %s is not a blob" ), oid_to_hex (oid ));
3623+ return -1 ;
35743624 }
35753625 strbuf_attach (dst , buf , size , size + 1 );
35763626 return 0 ;
@@ -3594,8 +3644,8 @@ static int blob_unchanged(struct merge_options *opt,
35943644 if (oideq (& base -> oid , & side -> oid ))
35953645 return 1 ;
35963646
3597- if (read_oid_strbuf (& base -> oid , & basebuf ) ||
3598- read_oid_strbuf (& side -> oid , & sidebuf ))
3647+ if (read_oid_strbuf (opt , & base -> oid , & basebuf , path ) ||
3648+ read_oid_strbuf (opt , & side -> oid , & sidebuf , path ))
35993649 goto error_return ;
36003650 /*
36013651 * Note: binary | is used so that both renormalizations are
@@ -4645,6 +4695,7 @@ void merge_display_update_messages(struct merge_options *opt,
46454695 struct hashmap_iter iter ;
46464696 struct strmap_entry * e ;
46474697 struct string_list olist = STRING_LIST_INIT_NODUP ;
4698+ FILE * o = stdout ;
46484699
46494700 if (opt -> record_conflict_msgs_as_headers )
46504701 BUG ("Either display conflict messages or record them as headers, not both" );
@@ -4661,32 +4712,42 @@ void merge_display_update_messages(struct merge_options *opt,
46614712 }
46624713 string_list_sort (& olist );
46634714
4715+ /* Print to stderr if we hit errors rather than just conflicts */
4716+ if (result -> clean < 0 )
4717+ o = stderr ;
4718+
46644719 /* Iterate over the items, printing them */
46654720 for (int path_nr = 0 ; path_nr < olist .nr ; ++ path_nr ) {
46664721 struct string_list * conflicts = olist .items [path_nr ].util ;
46674722 for (int i = 0 ; i < conflicts -> nr ; i ++ ) {
46684723 struct logical_conflict_info * info =
46694724 conflicts -> items [i ].util ;
46704725
4726+ /* On failure, ignore regular conflict types */
4727+ if (result -> clean < 0 &&
4728+ info -> type < NB_REGULAR_CONFLICT_TYPES )
4729+ continue ;
4730+
46714731 if (detailed ) {
4672- printf ( "%lu" , (unsigned long )info -> paths .nr );
4673- putchar ('\0' );
4732+ fprintf ( o , "%lu" , (unsigned long )info -> paths .nr );
4733+ fputc ('\0' , o );
46744734 for (int n = 0 ; n < info -> paths .nr ; n ++ ) {
4675- fputs (info -> paths .v [n ], stdout );
4676- putchar ('\0' );
4735+ fputs (info -> paths .v [n ], o );
4736+ fputc ('\0' , o );
46774737 }
4678- fputs (type_short_descriptions [info -> type ],
4679- stdout );
4680- putchar ('\0' );
4738+ fputs (type_short_descriptions [info -> type ], o );
4739+ fputc ('\0' , o );
46814740 }
4682- puts (conflicts -> items [i ].string );
4741+ fputs (conflicts -> items [i ].string , o );
4742+ fputc ('\n' , o );
46834743 if (detailed )
4684- putchar ('\0' );
4744+ fputc ('\0' , o );
46854745 }
46864746 }
46874747 string_list_clear (& olist , 0 );
46884748
4689- print_submodule_conflict_suggestion (& opti -> conflicted_submodules );
4749+ if (result -> clean >= 0 )
4750+ print_submodule_conflict_suggestion (& opti -> conflicted_submodules );
46904751
46914752 /* Also include needed rename limit adjustment now */
46924753 diff_warn_rename_limit ("merge.renamelimit" ,
@@ -5002,6 +5063,26 @@ static void merge_check_renames_reusable(struct merge_result *result,
50025063
50035064/*** Function Grouping: merge_incore_*() and their internal variants ***/
50045065
5066+ static void move_opt_priv_to_result_priv (struct merge_options * opt ,
5067+ struct merge_result * result )
5068+ {
5069+ /*
5070+ * opt->priv and result->priv are a bit weird. opt->priv contains
5071+ * information that we can re-use in subsequent merge operations to
5072+ * enable our cached renames optimization. The best way to provide
5073+ * that to subsequent merges is putting it in result->priv.
5074+ * However, putting it directly there would mean retrofitting lots
5075+ * of functions in this file to also take a merge_result pointer,
5076+ * which is ugly and annoying. So, we just make sure at the end of
5077+ * the merge (the outer merge if there are internal recursive ones)
5078+ * to move it.
5079+ */
5080+ assert (opt -> priv && !result -> priv );
5081+ result -> priv = opt -> priv ;
5082+ result -> _properly_initialized = RESULT_INITIALIZED ;
5083+ opt -> priv = NULL ;
5084+ }
5085+
50055086/*
50065087 * Originally from merge_trees_internal(); heavily adapted, though.
50075088 */
@@ -5032,6 +5113,7 @@ static void merge_ort_nonrecursive_internal(struct merge_options *opt,
50325113 oid_to_hex (& side1 -> object .oid ),
50335114 oid_to_hex (& side2 -> object .oid ));
50345115 result -> clean = -1 ;
5116+ move_opt_priv_to_result_priv (opt , result );
50355117 return ;
50365118 }
50375119 trace2_region_leave ("merge" , "collect_merge_info" , opt -> repo );
@@ -5062,11 +5144,8 @@ static void merge_ort_nonrecursive_internal(struct merge_options *opt,
50625144 /* existence of conflicted entries implies unclean */
50635145 result -> clean &= strmap_empty (& opt -> priv -> conflicted );
50645146 }
5065- if (!opt -> priv -> call_depth ) {
5066- result -> priv = opt -> priv ;
5067- result -> _properly_initialized = RESULT_INITIALIZED ;
5068- opt -> priv = NULL ;
5069- }
5147+ if (!opt -> priv -> call_depth || result -> clean < 0 )
5148+ move_opt_priv_to_result_priv (opt , result );
50705149}
50715150
50725151/*
0 commit comments