Skip to content

Commit 6ca844e

Browse files
Kirill Smelkovgitster
authored andcommitted
tree-diff: remove special-case diff-emitting code for empty-tree cases
While walking trees, we iterate their entries from lowest to highest in sort order, so empty tree means all entries were already went over. If we artificially assign +infinity value to such tree "entry", it will go after all usual entries, and through the usual driver loop we will be taking the same actions, which were hand-coded for special cases, i.e. t1 empty, t2 non-empty pathcmp(+∞, t2) -> +1 show_path(/*t1=*/NULL, t2); /* = t1 > t2 case in main loop */ t1 non-empty, t2-empty pathcmp(t1, +∞) -> -1 show_path(t1, /*t2=*/NULL); /* = t1 < t2 case in main loop */ In other words when we have t1 and t2, we return a sign that tells the caller to indicate the "earlier" one to be emitted, and by returning the sign that causes the non-empty side to be emitted, we will automatically cause the entries from the remaining side to be emitted, without attempting to touch the empty side at all. We can teach tree_entry_pathcmp() to pretend that an empty tree has an element that sorts after anything else to achieve this. Right now we never go to when compared tree descriptors are both infinity, as this condition is checked in the loop beginning as finishing criteria, but will do so in the future, when there will be several parents iterated simultaneously, and some pair of them would run to the end. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 1a27a15 commit 6ca844e

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

tree-diff.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@
1212
*
1313
* NOTE files and directories *always* compare differently, even when having
1414
* the same name - thanks to base_name_compare().
15+
*
16+
* NOTE empty (=invalid) descriptor(s) take part in comparison as +infty,
17+
* so that they sort *after* valid tree entries.
18+
*
19+
* Due to this convention, if trees are scanned in sorted order, all
20+
* non-empty descriptors will be processed first.
1521
*/
1622
static int tree_entry_pathcmp(struct tree_desc *t1, struct tree_desc *t2)
1723
{
1824
struct name_entry *e1, *e2;
1925
int cmp;
2026

27+
/* empty descriptors sort after valid tree entries */
28+
if (!t1->size)
29+
return t2->size ? 1 : 0;
30+
else if (!t2->size)
31+
return -1;
32+
2133
e1 = &t1->entry;
2234
e2 = &t2->entry;
2335
cmp = base_name_compare(e1->path, tree_entry_len(e1), e1->mode,
@@ -150,18 +162,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
150162
skip_uninteresting(t1, &base, opt);
151163
skip_uninteresting(t2, &base, opt);
152164
}
153-
if (!t1->size) {
154-
if (!t2->size)
155-
break;
156-
show_path(&base, opt, /*t1=*/NULL, t2);
157-
update_tree_entry(t2);
158-
continue;
159-
}
160-
if (!t2->size) {
161-
show_path(&base, opt, t1, /*t2=*/NULL);
162-
update_tree_entry(t1);
163-
continue;
164-
}
165+
if (!t1->size && !t2->size)
166+
break;
165167

166168
cmp = tree_entry_pathcmp(t1, t2);
167169

0 commit comments

Comments
 (0)