1515static struct combine_diff_path * intersect_paths (struct combine_diff_path * curr , int n , int num_parent )
1616{
1717 struct diff_queue_struct * q = & diff_queued_diff ;
18- struct combine_diff_path * p ;
19- int i ;
18+ struct combine_diff_path * p , * * tail = & curr ;
19+ int i , cmp ;
2020
2121 if (!n ) {
22- struct combine_diff_path * list = NULL , * * tail = & list ;
2322 for (i = 0 ; i < q -> nr ; i ++ ) {
2423 int len ;
2524 const char * path ;
@@ -31,7 +30,6 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
3130 p -> path = (char * ) & (p -> parent [num_parent ]);
3231 memcpy (p -> path , path , len );
3332 p -> path [len ] = 0 ;
34- p -> len = len ;
3533 p -> next = NULL ;
3634 memset (p -> parent , 0 ,
3735 sizeof (p -> parent [0 ]) * num_parent );
@@ -44,31 +42,37 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
4442 * tail = p ;
4543 tail = & p -> next ;
4644 }
47- return list ;
45+ return curr ;
4846 }
4947
50- for (p = curr ; p ; p = p -> next ) {
51- int found = 0 ;
52- if (!p -> len )
48+ /*
49+ * paths in curr (linked list) and q->queue[] (array) are
50+ * both sorted in the tree order.
51+ */
52+ i = 0 ;
53+ while ((p = * tail ) != NULL ) {
54+ cmp = ((i >= q -> nr )
55+ ? -1 : strcmp (p -> path , q -> queue [i ]-> two -> path ));
56+
57+ if (cmp < 0 ) {
58+ /* p->path not in q->queue[]; drop it */
59+ * tail = p -> next ;
60+ free (p );
5361 continue ;
54- for (i = 0 ; i < q -> nr ; i ++ ) {
55- const char * path ;
56- int len ;
62+ }
5763
58- if (diff_unmodified_pair (q -> queue [i ]))
59- continue ;
60- path = q -> queue [i ]-> two -> path ;
61- len = strlen (path );
62- if (len == p -> len && !memcmp (path , p -> path , len )) {
63- found = 1 ;
64- hashcpy (p -> parent [n ].sha1 , q -> queue [i ]-> one -> sha1 );
65- p -> parent [n ].mode = q -> queue [i ]-> one -> mode ;
66- p -> parent [n ].status = q -> queue [i ]-> status ;
67- break ;
68- }
64+ if (cmp > 0 ) {
65+ /* q->queue[i] not in p->path; skip it */
66+ i ++ ;
67+ continue ;
6968 }
70- if (!found )
71- p -> len = 0 ;
69+
70+ hashcpy (p -> parent [n ].sha1 , q -> queue [i ]-> one -> sha1 );
71+ p -> parent [n ].mode = q -> queue [i ]-> one -> mode ;
72+ p -> parent [n ].status = q -> queue [i ]-> status ;
73+
74+ tail = & p -> next ;
75+ i ++ ;
7276 }
7377 return curr ;
7478}
@@ -1219,8 +1223,6 @@ void show_combined_diff(struct combine_diff_path *p,
12191223{
12201224 struct diff_options * opt = & rev -> diffopt ;
12211225
1222- if (!p -> len )
1223- return ;
12241226 if (opt -> output_format & (DIFF_FORMAT_RAW |
12251227 DIFF_FORMAT_NAME |
12261228 DIFF_FORMAT_NAME_STATUS ))
@@ -1284,17 +1286,21 @@ static void handle_combined_callback(struct diff_options *opt,
12841286 q .queue = xcalloc (num_paths , sizeof (struct diff_filepair * ));
12851287 q .alloc = num_paths ;
12861288 q .nr = num_paths ;
1287- for (i = 0 , p = paths ; p ; p = p -> next ) {
1288- if (!p -> len )
1289- continue ;
1289+ for (i = 0 , p = paths ; p ; p = p -> next )
12901290 q .queue [i ++ ] = combined_pair (p , num_parent );
1291- }
12921291 opt -> format_callback (& q , opt , opt -> format_callback_data );
12931292 for (i = 0 ; i < num_paths ; i ++ )
12941293 free_combined_pair (q .queue [i ]);
12951294 free (q .queue );
12961295}
12971296
1297+ static const char * path_path (void * obj )
1298+ {
1299+ struct combine_diff_path * path = (struct combine_diff_path * )obj ;
1300+
1301+ return path -> path ;
1302+ }
1303+
12981304void diff_tree_combined (const unsigned char * sha1 ,
12991305 const struct sha1_array * parents ,
13001306 int dense ,
@@ -1310,6 +1316,8 @@ void diff_tree_combined(const unsigned char *sha1,
13101316 diffopts .output_format = DIFF_FORMAT_NO_OUTPUT ;
13111317 DIFF_OPT_SET (& diffopts , RECURSIVE );
13121318 DIFF_OPT_CLR (& diffopts , ALLOW_EXTERNAL );
1319+ /* tell diff_tree to emit paths in sorted (=tree) order */
1320+ diffopts .orderfile = NULL ;
13131321
13141322 show_log_first = !!rev -> loginfo && !rev -> no_commit_id ;
13151323 needsep = 0 ;
@@ -1335,22 +1343,46 @@ void diff_tree_combined(const unsigned char *sha1,
13351343 printf ("%s%c" , diff_line_prefix (opt ),
13361344 opt -> line_termination );
13371345 }
1346+
1347+ /* if showing diff, show it in requested order */
1348+ if (diffopts .output_format != DIFF_FORMAT_NO_OUTPUT &&
1349+ opt -> orderfile ) {
1350+ diffcore_order (opt -> orderfile );
1351+ }
1352+
13381353 diff_flush (& diffopts );
13391354 }
13401355
1341- /* find out surviving paths */
1342- for (num_paths = 0 , p = paths ; p ; p = p -> next ) {
1343- if (p -> len )
1344- num_paths ++ ;
1356+ /* find out number of surviving paths */
1357+ for (num_paths = 0 , p = paths ; p ; p = p -> next )
1358+ num_paths ++ ;
1359+
1360+ /* order paths according to diffcore_order */
1361+ if (opt -> orderfile && num_paths ) {
1362+ struct obj_order * o ;
1363+
1364+ o = xmalloc (sizeof (* o ) * num_paths );
1365+ for (i = 0 , p = paths ; p ; p = p -> next , i ++ )
1366+ o [i ].obj = p ;
1367+ order_objects (opt -> orderfile , path_path , o , num_paths );
1368+ for (i = 0 ; i < num_paths - 1 ; i ++ ) {
1369+ p = o [i ].obj ;
1370+ p -> next = o [i + 1 ].obj ;
1371+ }
1372+
1373+ p = o [num_paths - 1 ].obj ;
1374+ p -> next = NULL ;
1375+ paths = o [0 ].obj ;
1376+ free (o );
13451377 }
1378+
1379+
13461380 if (num_paths ) {
13471381 if (opt -> output_format & (DIFF_FORMAT_RAW |
13481382 DIFF_FORMAT_NAME |
13491383 DIFF_FORMAT_NAME_STATUS )) {
1350- for (p = paths ; p ; p = p -> next ) {
1351- if (p -> len )
1352- show_raw_diff (p , num_parent , rev );
1353- }
1384+ for (p = paths ; p ; p = p -> next )
1385+ show_raw_diff (p , num_parent , rev );
13541386 needsep = 1 ;
13551387 }
13561388 else if (opt -> output_format &
@@ -1363,11 +1395,9 @@ void diff_tree_combined(const unsigned char *sha1,
13631395 if (needsep )
13641396 printf ("%s%c" , diff_line_prefix (opt ),
13651397 opt -> line_termination );
1366- for (p = paths ; p ; p = p -> next ) {
1367- if (p -> len )
1368- show_patch_diff (p , num_parent , dense ,
1369- 0 , rev );
1370- }
1398+ for (p = paths ; p ; p = p -> next )
1399+ show_patch_diff (p , num_parent , dense ,
1400+ 0 , rev );
13711401 }
13721402 }
13731403
0 commit comments