via teaching tree_entry_pathcmp() how to compare empty tree descriptors:

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 */

Right now we never go to when compared tree descriptors are infinity, as
this condition is checked in the loop beginning as finishing criteria,
but will do 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 <k...@mns.spb.ru>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
---

( re-posting without change )

 tree-diff.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/tree-diff.c b/tree-diff.c
index cf96ad7..2fd6d0e 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -12,12 +12,19 @@
  *
  * NOTE files and directories *always* compare differently, even when having
  *      the same name - thanks to base_name_compare().
+ *
+ * NOTE empty (=invalid) descriptor(s) take part in comparison as +infty.
  */
 static int tree_entry_pathcmp(struct tree_desc *t1, struct tree_desc *t2)
 {
        struct name_entry *e1, *e2;
        int cmp;
 
+       if (!t1->size)
+               return t2->size ? +1 /* +∞ > c */  : 0 /* +∞ = +∞ */;
+       else if (!t2->size)
+               return -1;      /* c < +∞ */
+
        e1 = &t1->entry;
        e2 = &t2->entry;
        cmp = base_name_compare(e1->path, tree_entry_len(e1), e1->mode,
@@ -151,18 +158,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
                        skip_uninteresting(t1, &base, opt);
                        skip_uninteresting(t2, &base, opt);
                }
-               if (!t1->size) {
-                       if (!t2->size)
-                               break;
-                       show_path(&base, opt, /*t1=*/NULL, t2);
-                       update_tree_entry(t2);
-                       continue;
-               }
-               if (!t2->size) {
-                       show_path(&base, opt, t1, /*t2=*/NULL);
-                       update_tree_entry(t1);
-                       continue;
-               }
+               if (!t1->size && !t2->size)
+                       break;
 
                cmp = tree_entry_pathcmp(t1, t2);
 
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to