Skip to content

Commit 2dff7e2

Browse files
committed
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.
1 parent 99bb98c commit 2dff7e2

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

src/tree.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,15 +447,16 @@ static int append_entry(
447447
git_treebuilder *bld,
448448
const char *filename,
449449
const git_oid *id,
450-
git_filemode_t filemode)
450+
git_filemode_t filemode,
451+
bool from_tree)
451452
{
452453
git_tree_entry *entry;
453454
int error = 0;
454455

455-
if (!valid_entry_name(bld->repo, filename))
456+
if (!from_tree && !valid_entry_name(bld->repo, filename))
456457
return tree_error("failed to insert entry: invalid name for a tree entry", filename);
457458

458-
if (git_oid_iszero(id))
459+
if (!from_tree && git_oid_iszero(id))
459460
return tree_error("failed to insert entry: invalid null OID for a tree entry", filename);
460461

461462
entry = alloc_entry(filename, strlen(filename), id);
@@ -553,12 +554,12 @@ static int write_tree(
553554
last_comp = subdir;
554555
}
555556

556-
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
557+
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR, false);
557558
git__free(subdir);
558559
if (error < 0)
559560
goto on_error;
560561
} else {
561-
error = append_entry(bld, filename, &entry->id, entry->mode);
562+
error = append_entry(bld, filename, &entry->id, entry->mode, false);
562563
if (error < 0)
563564
goto on_error;
564565
}
@@ -656,7 +657,8 @@ int git_treebuilder_new(
656657
if (append_entry(
657658
bld, entry_src->filename,
658659
entry_src->oid,
659-
entry_src->attr) < 0)
660+
entry_src->attr,
661+
true) < 0)
660662
goto on_error;
661663
}
662664
}

tests/object/tree/update.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,18 @@ void test_object_tree_update__add_conflict2(void)
284284

285285
cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates));
286286
}
287+
288+
void test_object_tree_update__remove_invalid_submodule(void)
289+
{
290+
git_tree *baseline;
291+
git_oid updated_tree_id, baseline_id;
292+
git_tree_update updates[] = {
293+
{GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB, "submodule"},
294+
};
295+
296+
cl_git_pass(git_oid_fromstr(&baseline_id, "396c7f1adb7925f51ba13a75f48252f44c5a14a2"));
297+
cl_git_pass(git_tree_lookup(&baseline, g_repo, &baseline_id));
298+
cl_git_pass(git_tree_create_updated(&updated_tree_id, g_repo, baseline, 1, updates));
299+
300+
git_tree_free(baseline);
301+
}
Binary file not shown.

0 commit comments

Comments
 (0)