Skip to content

Commit f4c214b

Browse files
committed
Merge branch 'jk/revision-pruning-optim'
Pathspec-limited revision traversal was taught not to keep finding unneeded differences once it knows two trees are different inside given pathspec. * jk/revision-pruning-optim: revision: quit pruning diff more quickly when possible
2 parents cb52b49 + a937b37 commit f4c214b

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

diff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ struct diff_options {
180180
pathchange_fn_t pathchange;
181181
change_fn_t change;
182182
add_remove_fn_t add_remove;
183+
void *change_fn_data;
183184
diff_format_fn_t format_callback;
184185
void *format_callback_data;
185186
diff_prefix_fn_t output_prefix;

revision.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,16 @@ static struct commit *one_relevant_parent(const struct rev_info *revs,
395395
* if the whole diff is removal of old data, and otherwise
396396
* REV_TREE_DIFFERENT (of course if the trees are the same we
397397
* want REV_TREE_SAME).
398-
* That means that once we get to REV_TREE_DIFFERENT, we do not
399-
* have to look any further.
398+
*
399+
* The only time we care about the distinction is when
400+
* remove_empty_trees is in effect, in which case we care only about
401+
* whether the whole change is REV_TREE_NEW, or if there's another type
402+
* of change. Which means we can stop the diff early in either of these
403+
* cases:
404+
*
405+
* 1. We're not using remove_empty_trees at all.
406+
*
407+
* 2. We saw anything except REV_TREE_NEW.
400408
*/
401409
static int tree_difference = REV_TREE_SAME;
402410

@@ -407,9 +415,10 @@ static void file_add_remove(struct diff_options *options,
407415
const char *fullpath, unsigned dirty_submodule)
408416
{
409417
int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD;
418+
struct rev_info *revs = options->change_fn_data;
410419

411420
tree_difference |= diff;
412-
if (tree_difference == REV_TREE_DIFFERENT)
421+
if (!revs->remove_empty_trees || tree_difference != REV_TREE_NEW)
413422
DIFF_OPT_SET(options, HAS_CHANGES);
414423
}
415424

@@ -1407,6 +1416,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
14071416
DIFF_OPT_SET(&revs->pruning, QUICK);
14081417
revs->pruning.add_remove = file_add_remove;
14091418
revs->pruning.change = file_change;
1419+
revs->pruning.change_fn_data = revs;
14101420
revs->sort_order = REV_SORT_IN_GRAPH_ORDER;
14111421
revs->dense = 1;
14121422
revs->prefix = prefix;

0 commit comments

Comments
 (0)