summaryrefslogtreecommitdiff
path: root/src/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree.c')
-rw-r--r--src/tree.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/tree.c b/src/tree.c
index 605af8b39..ab3bec8cd 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -40,12 +40,33 @@ int entry_search_cmp(const void *key, const void *array_member)
return strcmp(filename, entry->filename);
}
+static int cache_name_compare(const char *name1, int len1, int isdir1,
+ const char *name2, int len2, int isdir2)
+{
+ int len = len1 < len2 ? len1 : len2;
+ int cmp;
+
+ cmp = memcmp(name1, name2, len);
+ if (cmp)
+ return cmp;
+ if (len1 < len2)
+ return ((isdir1 == isdir2) ? -1 :
+ (isdir1 ? '/' - name2[len1] : name2[len1] - '/'));
+ if (len1 > len2)
+ return ((isdir1 == isdir2) ? 1 :
+ (isdir2 ? name1[len2] - '/' : '/' - name1[len2]));
+ return 0;
+}
+
int entry_sort_cmp(const void *a, const void *b)
{
const git_tree_entry *entry_a = *(const git_tree_entry **)(a);
const git_tree_entry *entry_b = *(const git_tree_entry **)(b);
- return strcmp(entry_a->filename, entry_b->filename);
+ return cache_name_compare(entry_a->filename, strlen(entry_a->filename),
+ entry_a->attr & 040000,
+ entry_b->filename, strlen(entry_b->filename),
+ entry_b->attr & 040000);
}
void git_tree_clear_entries(git_tree *tree)