summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2018-07-18 21:04:13 +0200
committerPatrick Steinhardt <ps@pks.im>2018-10-26 14:58:50 +0200
commitc37c6ed84f6133b1fd5d42b3899c7bb4ff880d85 (patch)
tree34d3e026424eb28d127c158440aab91d0b64b9a3
parenta051bce70c44c4ec395a4d9b75fddff6deb105ae (diff)
downloadlibgit2-c37c6ed84f6133b1fd5d42b3899c7bb4ff880d85.tar.gz
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. (cherry picked from commit 2dff7e282da77f6b791e843ec267d9ddecabc187)
-rw-r--r--src/tree.c14
-rw-r--r--tests/object/tree/update.c15
-rw-r--r--tests/resources/testrepo2/.gitted/objects/39/6c7f1adb7925f51ba13a75f48252f44c5a14a2bin0 -> 71 bytes
3 files changed, 23 insertions, 6 deletions
diff --git a/src/tree.c b/src/tree.c
index 12622975a..f52ab0fe6 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -490,15 +490,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);
@@ -596,12 +597,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;
}
@@ -699,7 +700,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;
}
}
diff --git a/tests/object/tree/update.c b/tests/object/tree/update.c
index b76e8612a..167faecbb 100644
--- a/tests/object/tree/update.c
+++ b/tests/object/tree/update.c
@@ -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);
+}
diff --git a/tests/resources/testrepo2/.gitted/objects/39/6c7f1adb7925f51ba13a75f48252f44c5a14a2 b/tests/resources/testrepo2/.gitted/objects/39/6c7f1adb7925f51ba13a75f48252f44c5a14a2
new file mode 100644
index 000000000..667704b32
--- /dev/null
+++ b/tests/resources/testrepo2/.gitted/objects/39/6c7f1adb7925f51ba13a75f48252f44c5a14a2
Binary files differ