mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-12 00:03:03 +00:00
tree: Proper path comparison logic
This commit is contained in:
parent
ac8eac2f66
commit
515a4c7c06
19
src/path.c
19
src/path.c
@ -468,19 +468,24 @@ int git_path_cmp(
|
|||||||
const char *name1, size_t len1, int isdir1,
|
const char *name1, size_t len1, int isdir1,
|
||||||
const char *name2, size_t len2, int isdir2)
|
const char *name2, size_t len2, int isdir2)
|
||||||
{
|
{
|
||||||
|
unsigned char c1, c2;
|
||||||
size_t len = len1 < len2 ? len1 : len2;
|
size_t len = len1 < len2 ? len1 : len2;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
cmp = memcmp(name1, name2, len);
|
cmp = memcmp(name1, name2, len);
|
||||||
if (cmp)
|
if (cmp)
|
||||||
return cmp;
|
return cmp;
|
||||||
if (len1 < len2)
|
|
||||||
return (!isdir1 && !isdir2) ? -1 :
|
c1 = name1[len];
|
||||||
(isdir1 ? '/' - name2[len1] : name2[len1] - '/');
|
c2 = name2[len];
|
||||||
if (len1 > len2)
|
|
||||||
return (!isdir1 && !isdir2) ? 1 :
|
if (c1 == '\0' && isdir1)
|
||||||
(isdir2 ? name1[len2] - '/' : '/' - name1[len2]);
|
c1 = '/';
|
||||||
return 0;
|
|
||||||
|
if (c2 == '\0' && isdir2)
|
||||||
|
c2 = '/';
|
||||||
|
|
||||||
|
return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Taken from git.git */
|
/* Taken from git.git */
|
||||||
|
@ -82,3 +82,66 @@ void test_object_tree_write__subtree(void)
|
|||||||
cl_assert(2 == git_tree_entrycount(tree));
|
cl_assert(2 == git_tree_entrycount(tree));
|
||||||
git_tree_free(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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user