Unverified Commit dc27772c by Patrick Steinhardt Committed by GitHub

Merge pull request #4378 from cjhoward92/fix/submodule-add-check-index

submodule: check index for path and prefix before adding submodule
parents b3c3415d 69a282da
......@@ -149,6 +149,51 @@ static int find_by_path(const git_config_entry *entry, void *payload)
return 0;
}
/*
* Checks to see if the submodule shares its name with a file or directory that
* already exists on the index. If so, the submodule cannot be added.
*/
static int is_path_occupied(bool *occupied, git_repository *repo, const char *path)
{
int error = 0;
git_index *index;
git_buf dir = GIT_BUF_INIT;
*occupied = false;
if ((error = git_repository_index__weakptr(&index, repo)) < 0)
goto out;
if ((error = git_index_find(NULL, index, path)) != GIT_ENOTFOUND) {
if (!error) {
giterr_set(GITERR_SUBMODULE,
"File '%s' already exists in the index", path);
*occupied = true;
}
goto out;
}
if ((error = git_buf_sets(&dir, path)) < 0)
goto out;
if ((error = git_path_to_dir(&dir)) < 0)
goto out;
if ((error = git_index_find_prefix(NULL, index, dir.ptr)) != GIT_ENOTFOUND) {
if (!error) {
giterr_set(GITERR_SUBMODULE,
"Directory '%s' already exists in the index", path);
*occupied = true;
}
goto out;
}
error = 0;
out:
git_buf_free(&dir);
return error;
}
/**
* Release the name map returned by 'load_submodule_names'.
*/
......@@ -664,6 +709,7 @@ int git_submodule_add_setup(
git_submodule *sm = NULL;
git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
git_repository *subrepo = NULL;
bool path_occupied;
assert(repo && url && path);
......@@ -688,6 +734,14 @@ int git_submodule_add_setup(
goto cleanup;
}
if ((error = is_path_occupied(&path_occupied, repo, path)) < 0)
goto cleanup;
if (path_occupied) {
error = GIT_EEXISTS;
goto cleanup;
}
/* update .gitmodules */
if (!(mods = open_gitmodules(repo, GITMODULES_CREATE))) {
......
......@@ -7,6 +7,7 @@
#include "repository.h"
static git_repository *g_repo = NULL;
static const char *valid_blob_id = "fa49b077972391ad58037050f2a75f74e3671e92";
void test_submodule_add__cleanup(void)
{
......@@ -128,3 +129,57 @@ void test_submodule_add__url_relative_to_workdir(void)
assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo));
}
static void test_add_entry(
git_index *index,
const char *idstr,
const char *path,
git_filemode_t mode)
{
git_index_entry entry = {{0}};
cl_git_pass(git_oid_fromstr(&entry.id, idstr));
entry.path = path;
entry.mode = mode;
cl_git_pass(git_index_add(index, &entry));
}
void test_submodule_add__path_exists_in_index(void)
{
git_index *index;
git_submodule *sm;
git_buf filename = GIT_BUF_INIT;
g_repo = cl_git_sandbox_init("testrepo");
cl_git_pass(git_buf_joinpath(&filename, "subdirectory", "test.txt"));
cl_git_pass(git_repository_index__weakptr(&index, g_repo));
test_add_entry(index, valid_blob_id, filename.ptr, GIT_FILEMODE_BLOB);
cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS);
git_submodule_free(sm);
git_buf_free(&filename);
}
void test_submodule_add__file_exists_in_index(void)
{
git_index *index;
git_submodule *sm;
git_buf name = GIT_BUF_INIT;
g_repo = cl_git_sandbox_init("testrepo");
cl_git_pass(git_repository_index__weakptr(&index, g_repo));
test_add_entry(index, valid_blob_id, "subdirectory", GIT_FILEMODE_BLOB);
cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS);
git_submodule_free(sm);
git_buf_free(&name);
}
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