Commit 2dff7e28 by Carlos Martín Nieto

tree: accept null ids in existing trees when updating

When we add entries to a treebuilder we validate them. But we validate even
those that we're adding because they exist in the base tree. This disables
using the normal mechanisms on these trees, even to fix them.

Keep track of whether the entry we're appending comes from an existing tree and
bypass the name and id validation if it's from existing data.
parent 99bb98c0
......@@ -447,15 +447,16 @@ static int append_entry(
git_treebuilder *bld,
const char *filename,
const git_oid *id,
git_filemode_t filemode)
git_filemode_t filemode,
bool from_tree)
{
git_tree_entry *entry;
int error = 0;
if (!valid_entry_name(bld->repo, filename))
if (!from_tree && !valid_entry_name(bld->repo, filename))
return tree_error("failed to insert entry: invalid name for a tree entry", filename);
if (git_oid_iszero(id))
if (!from_tree && git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID for a tree entry", filename);
entry = alloc_entry(filename, strlen(filename), id);
......@@ -553,12 +554,12 @@ static int write_tree(
last_comp = subdir;
}
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR, false);
git__free(subdir);
if (error < 0)
goto on_error;
} else {
error = append_entry(bld, filename, &entry->id, entry->mode);
error = append_entry(bld, filename, &entry->id, entry->mode, false);
if (error < 0)
goto on_error;
}
......@@ -656,7 +657,8 @@ int git_treebuilder_new(
if (append_entry(
bld, entry_src->filename,
entry_src->oid,
entry_src->attr) < 0)
entry_src->attr,
true) < 0)
goto on_error;
}
}
......
......@@ -284,3 +284,18 @@ void test_object_tree_update__add_conflict2(void)
cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates));
}
void test_object_tree_update__remove_invalid_submodule(void)
{
git_tree *baseline;
git_oid updated_tree_id, baseline_id;
git_tree_update updates[] = {
{GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB, "submodule"},
};
cl_git_pass(git_oid_fromstr(&baseline_id, "396c7f1adb7925f51ba13a75f48252f44c5a14a2"));
cl_git_pass(git_tree_lookup(&baseline, g_repo, &baseline_id));
cl_git_pass(git_tree_create_updated(&updated_tree_id, g_repo, baseline, 1, updates));
git_tree_free(baseline);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment