@@ -81,6 +81,8 @@ static int read_patches(const char *range, struct string_list *list,
81
81
finish_command (& cp );
82
82
return -1 ;
83
83
}
84
+ if (finish_command (& cp ))
85
+ return -1 ;
84
86
85
87
line = contents .buf ;
86
88
size = contents .len ;
@@ -98,10 +100,10 @@ static int read_patches(const char *range, struct string_list *list,
98
100
if (get_oid (p , & util -> oid )) {
99
101
error (_ ("could not parse commit '%s'" ), p );
100
102
free (util );
103
+ free (current_filename );
101
104
string_list_clear (list , 1 );
102
105
strbuf_release (& buf );
103
106
strbuf_release (& contents );
104
- finish_command (& cp );
105
107
return -1 ;
106
108
}
107
109
util -> matching = -1 ;
@@ -113,10 +115,10 @@ static int read_patches(const char *range, struct string_list *list,
113
115
error (_ ("could not parse first line of `log` output: "
114
116
"did not start with 'commit ': '%s'" ),
115
117
line );
118
+ free (current_filename );
116
119
string_list_clear (list , 1 );
117
120
strbuf_release (& buf );
118
121
strbuf_release (& contents );
119
- finish_command (& cp );
120
122
return -1 ;
121
123
}
122
124
@@ -134,9 +136,16 @@ static int read_patches(const char *range, struct string_list *list,
134
136
orig_len = len ;
135
137
len = parse_git_diff_header (& root , & linenr , 0 , line ,
136
138
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
+ }
140
149
strbuf_addstr (& buf , " ## " );
141
150
if (patch .is_new > 0 )
142
151
strbuf_addf (& buf , "%s (new)" , patch .new_name );
@@ -219,9 +228,6 @@ static int read_patches(const char *range, struct string_list *list,
219
228
strbuf_release (& buf );
220
229
free (current_filename );
221
230
222
- if (finish_command (& cp ))
223
- return -1 ;
224
-
225
231
return 0 ;
226
232
}
227
233
@@ -459,12 +465,35 @@ static void patch_diff(const char *a, const char *b,
459
465
diff_flush (diffopt );
460
466
}
461
467
468
+ static struct strbuf * output_prefix_cb (struct diff_options * opt , void * data )
469
+ {
470
+ return data ;
471
+ }
472
+
462
473
static void output (struct string_list * a , struct string_list * b ,
463
- struct diff_options * diffopt )
474
+ struct range_diff_options * range_diff_opts )
464
475
{
465
476
struct strbuf buf = STRBUF_INIT , dashes = STRBUF_INIT ;
466
477
int patch_no_width = decimal_width (1 + (a -> nr > b -> nr ? a -> nr : b -> nr ));
467
478
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 );
468
497
469
498
/*
470
499
* 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,
485
514
486
515
/* Show unmatched LHS commit whose predecessors were shown. */
487
516
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 ,
489
519
& buf , & dashes , a_util , NULL );
490
520
i ++ ;
491
521
continue ;
492
522
}
493
523
494
524
/* Show unmatched RHS commits. */
495
525
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 ,
497
528
& buf , & dashes , NULL , b_util );
498
529
b_util = ++ j < b -> nr ? b -> items [j ].util : NULL ;
499
530
}
500
531
501
532
/* Show matching LHS/RHS pair. */
502
533
if (j < b -> nr ) {
503
534
a_util = a -> items [b_util -> matching ].util ;
504
- output_pair_header (diffopt , patch_no_width ,
535
+ output_pair_header (& opts , patch_no_width ,
505
536
& buf , & dashes , a_util , b_util );
506
- if (!(diffopt -> output_format & DIFF_FORMAT_NO_OUTPUT ))
537
+ if (!(opts . output_format & DIFF_FORMAT_NO_OUTPUT ))
507
538
patch_diff (a -> items [b_util -> matching ].string ,
508
- b -> items [j ].string , diffopt );
539
+ b -> items [j ].string , & opts );
509
540
a_util -> shown = 1 ;
510
541
j ++ ;
511
542
}
512
543
}
513
544
strbuf_release (& buf );
514
545
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 );
520
547
}
521
548
522
549
int 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 )
526
551
{
527
552
int res = 0 ;
528
553
529
554
struct string_list branch1 = STRING_LIST_INIT_DUP ;
530
555
struct string_list branch2 = STRING_LIST_INIT_DUP ;
531
556
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 ))
533
561
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 ))
535
563
res = error (_ ("could not parse log for '%s'" ), range2 );
536
564
537
565
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
-
556
566
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 );
561
570
}
562
571
563
572
string_list_clear (& branch1 , 1 );
0 commit comments