From 515a4c7c0634018097d3cd85f6a819dabe4cfd32 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 19 Jun 2012 00:59:04 +0200 Subject: [PATCH] tree: Proper path comparison logic --- src/path.c | 19 ++++++---- tests-clar/object/tree/write.c | 63 ++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/path.c b/src/path.c index 1d85559a9..a6574b3de 100644 --- a/src/path.c +++ b/src/path.c @@ -468,19 +468,24 @@ int git_path_cmp( const char *name1, size_t len1, int isdir1, const char *name2, size_t len2, int isdir2) { + unsigned char c1, c2; size_t 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; + + c1 = name1[len]; + c2 = name2[len]; + + if (c1 == '\0' && isdir1) + c1 = '/'; + + if (c2 == '\0' && isdir2) + c2 = '/'; + + return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; } /* Taken from git.git */ diff --git a/tests-clar/object/tree/write.c b/tests-clar/object/tree/write.c index e6dc549a5..a7831203c 100644 --- a/tests-clar/object/tree/write.c +++ b/tests-clar/object/tree/write.c @@ -82,3 +82,66 @@ void test_object_tree_write__subtree(void) cl_assert(2 == git_tree_entrycount(tree)); git_tree_free(tree); } + +/* + * And the Lord said: Is this tree properly sorted? + */ +void test_object_tree_write__sorted_subtrees(void) +{ + git_treebuilder *builder; + unsigned int i, position_c, position_cake, position_config; + + struct { + unsigned int attr; + const char *filename; + } entries[] = { + { 0100644, ".gitattributes" }, + { 0100644, ".gitignore" }, + { 0100644, ".htaccess" }, + { 0100644, "Capfile" }, + { 0100644, "Makefile"}, + { 0100644, "README"}, + { 0040000, "app"}, + { 0040000, "cake"}, + { 0040000, "config"}, + { 0100644, "c"}, + { 0100644, "git_test.txt"}, + { 0100644, "htaccess.htaccess"}, + { 0100644, "index.php"}, + { 0040000, "plugins"}, + { 0040000, "schemas"}, + { 0040000, "ssl-certs"}, + { 0040000, "vendors"} + }; + + git_oid blank_oid, tree_oid; + + memset(&blank_oid, 0x0, sizeof(blank_oid)); + + cl_git_pass(git_treebuilder_create(&builder, NULL)); + + for (i = 0; i < ARRAY_SIZE(entries); ++i) { + cl_git_pass(git_treebuilder_insert(NULL, + builder, entries[i].filename, &blank_oid, entries[i].attr)); + } + + cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); + + for (i = 0; i < builder->entries.length; ++i) { + git_tree_entry *entry = git_vector_get(&builder->entries, i); + + if (strcmp(entry->filename, "c") == 0) + position_c = i; + + if (strcmp(entry->filename, "cake") == 0) + position_cake = i; + + if (strcmp(entry->filename, "config") == 0) + position_config = i; + } + + cl_assert(position_c < position_cake); + cl_assert(position_cake < position_config); + + git_treebuilder_free(builder); +}