@@ -280,9 +280,9 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt,
280280
281281static int prepare_submodule_summary (struct rev_info * rev , const char * path ,
282282 struct commit * left , struct commit * right ,
283- int * fast_forward , int * fast_backward )
283+ struct commit_list * merge_bases )
284284{
285- struct commit_list * merge_bases , * list ;
285+ struct commit_list * list ;
286286
287287 init_revisions (rev , NULL );
288288 setup_revisions (0 , NULL , rev , NULL );
@@ -291,13 +291,6 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
291291 left -> object .flags |= SYMMETRIC_LEFT ;
292292 add_pending_object (rev , & left -> object , path );
293293 add_pending_object (rev , & right -> object , path );
294- merge_bases = get_merge_bases (left , right );
295- if (merge_bases ) {
296- if (merge_bases -> item == left )
297- * fast_forward = 1 ;
298- else if (merge_bases -> item == right )
299- * fast_backward = 1 ;
300- }
301294 for (list = merge_bases ; list ; list = list -> next ) {
302295 list -> item -> object .flags |= UNINTERESTING ;
303296 add_pending_object (rev , & list -> item -> object ,
@@ -335,43 +328,70 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f,
335328 strbuf_release (& sb );
336329}
337330
338- void show_submodule_summary (FILE * f , const char * path ,
331+ /* Helper function to display the submodule header line prior to the full
332+ * summary output. If it can locate the submodule objects directory it will
333+ * attempt to lookup both the left and right commits and put them into the
334+ * left and right pointers.
335+ */
336+ static void show_submodule_header (FILE * f , const char * path ,
339337 const char * line_prefix ,
340338 struct object_id * one , struct object_id * two ,
341339 unsigned dirty_submodule , const char * meta ,
342- const char * del , const char * add , const char * reset )
340+ const char * reset ,
341+ struct commit * * left , struct commit * * right ,
342+ struct commit_list * * merge_bases )
343343{
344- struct rev_info rev ;
345- struct commit * left = NULL , * right = NULL ;
346344 const char * message = NULL ;
347345 struct strbuf sb = STRBUF_INIT ;
348346 int fast_forward = 0 , fast_backward = 0 ;
349347
350- if (is_null_oid (two ))
351- message = "(submodule deleted)" ;
352- else if (add_submodule_odb (path ))
353- message = "(not initialized)" ;
354- else if (is_null_oid (one ))
355- message = "(new submodule)" ;
356- else if (!(left = lookup_commit_reference (one -> hash )) ||
357- !(right = lookup_commit_reference (two -> hash )))
358- message = "(commits not present)" ;
359- else if (prepare_submodule_summary (& rev , path , left , right ,
360- & fast_forward , & fast_backward ))
361- message = "(revision walker failed)" ;
362-
363348 if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED )
364349 fprintf (f , "%sSubmodule %s contains untracked content\n" ,
365350 line_prefix , path );
366351 if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED )
367352 fprintf (f , "%sSubmodule %s contains modified content\n" ,
368353 line_prefix , path );
369354
355+ if (is_null_oid (one ))
356+ message = "(new submodule)" ;
357+ else if (is_null_oid (two ))
358+ message = "(submodule deleted)" ;
359+
360+ if (add_submodule_odb (path )) {
361+ if (!message )
362+ message = "(not initialized)" ;
363+ goto output_header ;
364+ }
365+
366+ /*
367+ * Attempt to lookup the commit references, and determine if this is
368+ * a fast forward or fast backwards update.
369+ */
370+ * left = lookup_commit_reference (one -> hash );
371+ * right = lookup_commit_reference (two -> hash );
372+
373+ /*
374+ * Warn about missing commits in the submodule project, but only if
375+ * they aren't null.
376+ */
377+ if ((!is_null_oid (one ) && !* left ) ||
378+ (!is_null_oid (two ) && !* right ))
379+ message = "(commits not present)" ;
380+
381+ * merge_bases = get_merge_bases (* left , * right );
382+ if (* merge_bases ) {
383+ if ((* merge_bases )-> item == * left )
384+ fast_forward = 1 ;
385+ else if ((* merge_bases )-> item == * right )
386+ fast_backward = 1 ;
387+ }
388+
370389 if (!oidcmp (one , two )) {
371390 strbuf_release (& sb );
372391 return ;
373392 }
374393
394+ output_header :
375395 strbuf_addf (& sb , "%s%sSubmodule %s %s.." , line_prefix , meta , path ,
376396 find_unique_abbrev (one -> hash , DEFAULT_ABBREV ));
377397 if (!fast_backward && !fast_forward )
@@ -383,16 +403,45 @@ void show_submodule_summary(FILE *f, const char *path,
383403 strbuf_addf (& sb , "%s:%s\n" , fast_backward ? " (rewind)" : "" , reset );
384404 fwrite (sb .buf , sb .len , 1 , f );
385405
386- if (!message ) /* only NULL if we succeeded in setting up the walk */
387- print_submodule_summary (& rev , f , line_prefix , del , add , reset );
388- if (left )
389- clear_commit_marks (left , ~0 );
390- if (right )
391- clear_commit_marks (right , ~0 );
392-
393406 strbuf_release (& sb );
394407}
395408
409+ void show_submodule_summary (FILE * f , const char * path ,
410+ const char * line_prefix ,
411+ struct object_id * one , struct object_id * two ,
412+ unsigned dirty_submodule , const char * meta ,
413+ const char * del , const char * add , const char * reset )
414+ {
415+ struct rev_info rev ;
416+ struct commit * left = NULL , * right = NULL ;
417+ struct commit_list * merge_bases = NULL ;
418+
419+ show_submodule_header (f , path , line_prefix , one , two , dirty_submodule ,
420+ meta , reset , & left , & right , & merge_bases );
421+
422+ /*
423+ * If we don't have both a left and a right pointer, there is no
424+ * reason to try and display a summary. The header line should contain
425+ * all the information the user needs.
426+ */
427+ if (!left || !right )
428+ goto out ;
429+
430+ /* Treat revision walker failure the same as missing commits */
431+ if (prepare_submodule_summary (& rev , path , left , right , merge_bases )) {
432+ fprintf (f , "%s(revision walker failed)\n" , line_prefix );
433+ goto out ;
434+ }
435+
436+ print_submodule_summary (& rev , f , line_prefix , del , add , reset );
437+
438+ out :
439+ if (merge_bases )
440+ free_commit_list (merge_bases );
441+ clear_commit_marks (left , ~0 );
442+ clear_commit_marks (right , ~0 );
443+ }
444+
396445void set_config_fetch_recurse_submodules (int value )
397446{
398447 config_fetch_recurse_submodules = value ;
0 commit comments