#include "diffcore.h"
#include "tree.h"
-static void show_path(struct strbuf *base, struct diff_options *opt,
- struct tree_desc *t1, struct tree_desc *t2);
-
/*
* Compare two tree entries, taking into account only path/S_ISDIR(mode),
* but not their sha1's.
*
* 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,
+ * so that they sort *after* valid tree entries.
+ *
+ * Due to this convention, if trees are scanned in sorted order, all
+ * non-empty descriptors will be processed first.
*/
static int tree_entry_pathcmp(struct tree_desc *t1, struct tree_desc *t2)
{
- unsigned mode1, mode2;
- const char *path1, *path2;
- const unsigned char *sha1, *sha2;
- int cmp, pathlen1, pathlen2;
-
- sha1 = tree_entry_extract(t1, &path1, &mode1);
- sha2 = tree_entry_extract(t2, &path2, &mode2);
-
- pathlen1 = tree_entry_len(&t1->entry);
- pathlen2 = tree_entry_len(&t2->entry);
-
- cmp = base_name_compare(path1, pathlen1, mode1, path2, pathlen2, mode2);
+ struct name_entry *e1, *e2;
+ int cmp;
+
+ /* empty descriptors sort after valid tree entries */
+ if (!t1->size)
+ return t2->size ? 1 : 0;
+ else if (!t2->size)
+ return -1;
+
+ e1 = &t1->entry;
+ e2 = &t2->entry;
+ cmp = base_name_compare(e1->path, tree_entry_len(e1), e1->mode,
+ e2->path, tree_entry_len(e2), e2->mode);
return cmp;
}
}
}
-int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
- const char *base_str, struct diff_options *opt)
+static int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
+ const char *base_str, struct diff_options *opt)
{
struct strbuf base;
int baselen = strlen(base_str);
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);