1 |
diff --git a/diff.h b/diff.h |
2 |
index e9ccb38..fe5c287 100644 |
3 |
--- a/diff.h |
4 |
+++ b/diff.h |
5 |
@@ -180,6 +180,7 @@ struct diff_options { |
6 |
pathchange_fn_t pathchange; |
7 |
change_fn_t change; |
8 |
add_remove_fn_t add_remove; |
9 |
+ void *change_fn_data; |
10 |
diff_format_fn_t format_callback; |
11 |
void *format_callback_data; |
12 |
diff_prefix_fn_t output_prefix; |
13 |
diff --git a/revision.c b/revision.c |
14 |
index 771d079..7c23ab7 100644 |
15 |
--- a/revision.c |
16 |
+++ b/revision.c |
17 |
@@ -394,8 +394,16 @@ static struct commit *one_relevant_parent(const struct rev_info *revs, |
18 |
* if the whole diff is removal of old data, and otherwise |
19 |
* REV_TREE_DIFFERENT (of course if the trees are the same we |
20 |
* want REV_TREE_SAME). |
21 |
- * That means that once we get to REV_TREE_DIFFERENT, we do not |
22 |
- * have to look any further. |
23 |
+ * |
24 |
+ * The only time we care about the distinction is when |
25 |
+ * remove_empty_trees is in effect, in which case we care only about |
26 |
+ * whether the whole change is REV_TREE_NEW, or if there's another type |
27 |
+ * of change. Which means we can stop the diff early in either of these |
28 |
+ * cases: |
29 |
+ * |
30 |
+ * 1. We're not using remove_empty_trees at all. |
31 |
+ * |
32 |
+ * 2. We saw anything except REV_TREE_NEW. |
33 |
*/ |
34 |
static int tree_difference = REV_TREE_SAME; |
35 |
|
36 |
@@ -406,9 +414,10 @@ static void file_add_remove(struct diff_options *options, |
37 |
const char *fullpath, unsigned dirty_submodule) |
38 |
{ |
39 |
int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD; |
40 |
+ struct rev_info *revs = options->change_fn_data; |
41 |
|
42 |
tree_difference |= diff; |
43 |
- if (tree_difference == REV_TREE_DIFFERENT) |
44 |
+ if (!revs->remove_empty_trees || tree_difference != REV_TREE_NEW) |
45 |
DIFF_OPT_SET(options, HAS_CHANGES); |
46 |
} |
47 |
|
48 |
@@ -1346,6 +1355,7 @@ void init_revisions(struct rev_info *revs, const char *prefix) |
49 |
DIFF_OPT_SET(&revs->pruning, QUICK); |
50 |
revs->pruning.add_remove = file_add_remove; |
51 |
revs->pruning.change = file_change; |
52 |
+ revs->pruning.change_fn_data = revs; |
53 |
revs->sort_order = REV_SORT_IN_GRAPH_ORDER; |
54 |
revs->dense = 1; |
55 |
revs->prefix = prefix; |