diff options
-rw-r--r-- | src/tree.c | 9 | ||||
-rw-r--r-- | tests/object/tree/write.c | 61 |
2 files changed, 67 insertions, 3 deletions
diff --git a/src/tree.c b/src/tree.c index b64efe460..4ddb26b2d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -667,10 +667,16 @@ int git_treebuilder_insert( entry->removed = 0; bld->entrycount++; } + + entry->attr = filemode; + git_oid_cpy(&entry->oid, id); } else { entry = alloc_entry(filename); GITERR_CHECK_ALLOC(entry); + entry->attr = filemode; + git_oid_cpy(&entry->oid, id); + if (git_vector_insert_sorted(&bld->entries, entry, NULL) < 0) { git__free(entry); return -1; @@ -679,9 +685,6 @@ int git_treebuilder_insert( bld->entrycount++; } - git_oid_cpy(&entry->oid, id); - entry->attr = filemode; - if (entry_out) *entry_out = entry; diff --git a/tests/object/tree/write.c b/tests/object/tree/write.c index 45356e807..ef7adaf20 100644 --- a/tests/object/tree/write.c +++ b/tests/object/tree/write.c @@ -396,3 +396,64 @@ void test_object_tree_write__cruel_paths(void) git_tree_free(tree); } + +void test_object_tree_write__from_tree_git_sorting(void) +{ + git_index *index; + git_odb *db; + git_treebuilder *bld; + git_oid first_tree = {{0}}, second_tree = {{0}}, subtree_id = {{0}}, second_tree_bld = {{0}}; + git_tree *tree; + git_index_entry entry = {{0}}; + const char *foo = "foo\n"; + const char *bar = "bar\n"; + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_index_clear(index)); + cl_git_pass(git_repository_odb(&db, g_repo)); + + cl_git_pass(git_odb_write(&entry.id, db, foo, strlen(foo), GIT_OBJ_BLOB)); + entry.mode = GIT_FILEMODE_BLOB; + entry.path = "foo.txt"; + + cl_git_pass(git_index_add(index, &entry)); + cl_git_pass(git_index_write_tree(&first_tree, index)); + + /* Clear the index and re-add so we don't use any tree caches */ + cl_git_pass(git_index_clear(index)); + cl_git_pass(git_index_add(index, &entry)); + + cl_git_pass(git_odb_write(&entry.id, db, bar, strlen(bar), GIT_OBJ_BLOB)); + entry.mode = GIT_FILEMODE_BLOB; + entry.path = "foo/bar"; + + cl_git_pass(git_index_add(index, &entry)); + cl_git_pass(git_index_write_tree(&second_tree, index)); + + /* + * The index has now written the tree from scratch. We will + * create a builder taking the first tree as a starting point + * and create the second tree. + */ + + cl_git_pass(git_treebuilder_create(&bld, NULL)); + + cl_git_pass(git_treebuilder_insert(NULL, bld, "bar", &entry.id, entry.mode)); + cl_git_pass(git_treebuilder_write(&subtree_id, g_repo, bld)); + git_treebuilder_free(bld); + + /* assert subtree_id is the same as the one from the index */ + + cl_git_pass(git_tree_lookup(&tree, g_repo, &first_tree)); + cl_git_pass(git_treebuilder_create(&bld, tree)); + + cl_git_pass(git_treebuilder_insert(NULL, bld, "foo", &subtree_id, GIT_FILEMODE_TREE)); + cl_git_pass(git_treebuilder_write(&second_tree_bld, g_repo, bld)); + git_treebuilder_free(bld); + + cl_assert(!git_oid_cmp(&second_tree, &second_tree_bld)); + + git_tree_free(tree); + git_odb_free(db); + git_index_free(index); +} |