combine-diff: move changed-paths scanning logic into its own function

Move code for finding paths for which diff(commit,parent_i) is not-empty for all parents to separate function - at present we have generic (and slow) code for this job, which translates 1 n-parent problem to n 1-parent problems and then intersect results, and will be adding another limited, but faster, paths scanning implementation in the next patch. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kirill Smelkov committed Feb 3, 2014 at 16:47 UTC eeb3f32868862609b475122f3e0c2ef7c0dd3e79
1 file changed +53 -27
combine-diff.c
+53 -27
@@ -1301,6 +1301,51 @@ static const char *path_path(void *obj)
1301 return path->path;
1302 }
1303
1304 +
1305 +/* find set of paths that every parent touches */
1306 +static struct combine_diff_path *find_paths(const unsigned char *sha1,
1307 + const struct sha1_array *parents, struct diff_options *opt)
1308 +{
1309 + struct combine_diff_path *paths = NULL;
1310 + int i, num_parent = parents->nr;
1311 +
1312 + int output_format = opt->output_format;
1313 + const char *orderfile = opt->orderfile;
1314 +
1315 + opt->output_format = DIFF_FORMAT_NO_OUTPUT;
1316 + /* tell diff_tree to emit paths in sorted (=tree) order */
1317 + opt->orderfile = NULL;
1318 +
1319 + for (i = 0; i < num_parent; i++) {
1320 + /*
1321 + * show stat against the first parent even when doing
1322 + * combined diff.
1323 + */
1324 + int stat_opt = (output_format &
1325 + (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
1326 + if (i == 0 && stat_opt)
1327 + opt->output_format = stat_opt;
1328 + else
1329 + opt->output_format = DIFF_FORMAT_NO_OUTPUT;
1330 + diff_tree_sha1(parents->sha1[i], sha1, "", opt);
1331 + diffcore_std(opt);
1332 + paths = intersect_paths(paths, i, num_parent);
1333 +
1334 + /* if showing diff, show it in requested order */
1335 + if (opt->output_format != DIFF_FORMAT_NO_OUTPUT &&
1336 + orderfile) {
1337 + diffcore_order(orderfile);
1338 + }
1339 +
1340 + diff_flush(opt);
1341 + }
1342 +
1343 + opt->output_format = output_format;
1344 + opt->orderfile = orderfile;
1345 + return paths;
1346 +}
1347 +
1348 +
1349 void diff_tree_combined(const unsigned char *sha1,
1350 const struct sha1_array *parents,
1351 int dense,
@@ -1308,7 +1353,7 @@ void diff_tree_combined(const unsigned char *sha1,
1353 {
1354 struct diff_options *opt = &rev->diffopt;
1355 struct diff_options diffopts;
1311 - struct combine_diff_path *p, *paths = NULL;
1356 + struct combine_diff_path *p, *paths;
1357 int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
1358
1359 /* nothing to do, if no parents */
@@ -1327,35 +1372,16 @@ void diff_tree_combined(const unsigned char *sha1,
1372
1373 diffopts = *opt;
1374 copy_pathspec(&diffopts.pathspec, &opt->pathspec);
1330 - diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
1375 DIFF_OPT_SET(&diffopts, RECURSIVE);
1376 DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
1333 - /* tell diff_tree to emit paths in sorted (=tree) order */
1334 - diffopts.orderfile = NULL;
1377
1336 - /* find set of paths that everybody touches */
1337 - for (i = 0; i < num_parent; i++) {
1338 - /* show stat against the first parent even
1339 - * when doing combined diff.
1340 - */
1341 - int stat_opt = (opt->output_format &
1342 - (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
1343 - if (i == 0 && stat_opt)
1344 - diffopts.output_format = stat_opt;
1345 - else
1346 - diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
1347 - diff_tree_sha1(parents->sha1[i], sha1, "", &diffopts);
1348 - diffcore_std(&diffopts);
1349 - paths = intersect_paths(paths, i, num_parent);
1350 -
1351 - /* if showing diff, show it in requested order */
1352 - if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT &&
1353 - opt->orderfile) {
1354 - diffcore_order(opt->orderfile);
1355 - }
1356 -
1357 - diff_flush(&diffopts);
1358 - }
1378 + /* find set of paths that everybody touches
1379 + *
1380 + * NOTE find_paths() also handles --stat, as it computes
1381 + * diff(sha1,parent_i) for all i to do the job, specifically
1382 + * for parent0.
1383 + */
1384 + paths = find_paths(sha1, parents, &diffopts);
1385
1386 /* find out number of surviving paths */
1387 for (num_paths = 0, p = paths; p; p = p->next)