@@ -81,6 +81,8 @@ static int read_patches(const char *range, struct string_list *list,
8181 finish_command (& cp );
8282 return -1 ;
8383 }
84+ if (finish_command (& cp ))
85+ return -1 ;
8486
8587 line = contents .buf ;
8688 size = contents .len ;
@@ -98,10 +100,10 @@ static int read_patches(const char *range, struct string_list *list,
98100 if (get_oid (p , & util -> oid )) {
99101 error (_ ("could not parse commit '%s'" ), p );
100102 free (util );
103+ free (current_filename );
101104 string_list_clear (list , 1 );
102105 strbuf_release (& buf );
103106 strbuf_release (& contents );
104- finish_command (& cp );
105107 return -1 ;
106108 }
107109 util -> matching = -1 ;
@@ -113,10 +115,10 @@ static int read_patches(const char *range, struct string_list *list,
113115 error (_ ("could not parse first line of `log` output: "
114116 "did not start with 'commit ': '%s'" ),
115117 line );
118+ free (current_filename );
116119 string_list_clear (list , 1 );
117120 strbuf_release (& buf );
118121 strbuf_release (& contents );
119- finish_command (& cp );
120122 return -1 ;
121123 }
122124
@@ -134,9 +136,16 @@ static int read_patches(const char *range, struct string_list *list,
134136 orig_len = len ;
135137 len = parse_git_diff_header (& root , & linenr , 0 , line ,
136138 len , size , & patch );
137- if (len < 0 )
138- die (_ ("could not parse git header '%.*s'" ),
139- orig_len , line );
139+ if (len < 0 ) {
140+ error (_ ("could not parse git header '%.*s'" ),
141+ orig_len , line );
142+ free (util );
143+ free (current_filename );
144+ string_list_clear (list , 1 );
145+ strbuf_release (& buf );
146+ strbuf_release (& contents );
147+ return -1 ;
148+ }
140149 strbuf_addstr (& buf , " ## " );
141150 if (patch .is_new > 0 )
142151 strbuf_addf (& buf , "%s (new)" , patch .new_name );
@@ -219,9 +228,6 @@ static int read_patches(const char *range, struct string_list *list,
219228 strbuf_release (& buf );
220229 free (current_filename );
221230
222- if (finish_command (& cp ))
223- return -1 ;
224-
225231 return 0 ;
226232}
227233
@@ -459,12 +465,35 @@ static void patch_diff(const char *a, const char *b,
459465 diff_flush (diffopt );
460466}
461467
468+ static struct strbuf * output_prefix_cb (struct diff_options * opt , void * data )
469+ {
470+ return data ;
471+ }
472+
462473static void output (struct string_list * a , struct string_list * b ,
463- struct diff_options * diffopt )
474+ struct range_diff_options * range_diff_opts )
464475{
465476 struct strbuf buf = STRBUF_INIT , dashes = STRBUF_INIT ;
466477 int patch_no_width = decimal_width (1 + (a -> nr > b -> nr ? a -> nr : b -> nr ));
467478 int i = 0 , j = 0 ;
479+ struct diff_options opts ;
480+ struct strbuf indent = STRBUF_INIT ;
481+
482+ if (range_diff_opts -> diffopt )
483+ memcpy (& opts , range_diff_opts -> diffopt , sizeof (opts ));
484+ else
485+ diff_setup (& opts );
486+
487+ if (!opts .output_format )
488+ opts .output_format = DIFF_FORMAT_PATCH ;
489+ opts .flags .suppress_diff_headers = 1 ;
490+ opts .flags .dual_color_diffed_diffs =
491+ range_diff_opts -> dual_color ;
492+ opts .flags .suppress_hunk_header_line_count = 1 ;
493+ opts .output_prefix = output_prefix_cb ;
494+ strbuf_addstr (& indent , " " );
495+ opts .output_prefix_data = & indent ;
496+ diff_setup_done (& opts );
468497
469498 /*
470499 * We assume the user is really more interested in the second argument
@@ -485,79 +514,59 @@ static void output(struct string_list *a, struct string_list *b,
485514
486515 /* Show unmatched LHS commit whose predecessors were shown. */
487516 if (i < a -> nr && a_util -> matching < 0 ) {
488- output_pair_header (diffopt , patch_no_width ,
517+ if (!range_diff_opts -> right_only )
518+ output_pair_header (& opts , patch_no_width ,
489519 & buf , & dashes , a_util , NULL );
490520 i ++ ;
491521 continue ;
492522 }
493523
494524 /* Show unmatched RHS commits. */
495525 while (j < b -> nr && b_util -> matching < 0 ) {
496- output_pair_header (diffopt , patch_no_width ,
526+ if (!range_diff_opts -> left_only )
527+ output_pair_header (& opts , patch_no_width ,
497528 & buf , & dashes , NULL , b_util );
498529 b_util = ++ j < b -> nr ? b -> items [j ].util : NULL ;
499530 }
500531
501532 /* Show matching LHS/RHS pair. */
502533 if (j < b -> nr ) {
503534 a_util = a -> items [b_util -> matching ].util ;
504- output_pair_header (diffopt , patch_no_width ,
535+ output_pair_header (& opts , patch_no_width ,
505536 & buf , & dashes , a_util , b_util );
506- if (!(diffopt -> output_format & DIFF_FORMAT_NO_OUTPUT ))
537+ if (!(opts . output_format & DIFF_FORMAT_NO_OUTPUT ))
507538 patch_diff (a -> items [b_util -> matching ].string ,
508- b -> items [j ].string , diffopt );
539+ b -> items [j ].string , & opts );
509540 a_util -> shown = 1 ;
510541 j ++ ;
511542 }
512543 }
513544 strbuf_release (& buf );
514545 strbuf_release (& dashes );
515- }
516-
517- static struct strbuf * output_prefix_cb (struct diff_options * opt , void * data )
518- {
519- return data ;
546+ strbuf_release (& indent );
520547}
521548
522549int show_range_diff (const char * range1 , const char * range2 ,
523- int creation_factor , int dual_color ,
524- const struct diff_options * diffopt ,
525- const struct strvec * other_arg )
550+ struct range_diff_options * range_diff_opts )
526551{
527552 int res = 0 ;
528553
529554 struct string_list branch1 = STRING_LIST_INIT_DUP ;
530555 struct string_list branch2 = STRING_LIST_INIT_DUP ;
531556
532- if (read_patches (range1 , & branch1 , other_arg ))
557+ if (range_diff_opts -> left_only && range_diff_opts -> right_only )
558+ res = error (_ ("--left-only and --right-only are mutually exclusive" ));
559+
560+ if (!res && read_patches (range1 , & branch1 , range_diff_opts -> other_arg ))
533561 res = error (_ ("could not parse log for '%s'" ), range1 );
534- if (!res && read_patches (range2 , & branch2 , other_arg ))
562+ if (!res && read_patches (range2 , & branch2 , range_diff_opts -> other_arg ))
535563 res = error (_ ("could not parse log for '%s'" ), range2 );
536564
537565 if (!res ) {
538- struct diff_options opts ;
539- struct strbuf indent = STRBUF_INIT ;
540-
541- if (diffopt )
542- memcpy (& opts , diffopt , sizeof (opts ));
543- else
544- diff_setup (& opts );
545-
546- if (!opts .output_format )
547- opts .output_format = DIFF_FORMAT_PATCH ;
548- opts .flags .suppress_diff_headers = 1 ;
549- opts .flags .dual_color_diffed_diffs = dual_color ;
550- opts .flags .suppress_hunk_header_line_count = 1 ;
551- opts .output_prefix = output_prefix_cb ;
552- strbuf_addstr (& indent , " " );
553- opts .output_prefix_data = & indent ;
554- diff_setup_done (& opts );
555-
556566 find_exact_matches (& branch1 , & branch2 );
557- get_correspondences (& branch1 , & branch2 , creation_factor );
558- output (& branch1 , & branch2 , & opts );
559-
560- strbuf_release (& indent );
567+ get_correspondences (& branch1 , & branch2 ,
568+ range_diff_opts -> creation_factor );
569+ output (& branch1 , & branch2 , range_diff_opts );
561570 }
562571
563572 string_list_clear (& branch1 , 1 );
0 commit comments