submodule: check index for prefix before adding submodule submodule: check path and prefix before adding submodule submodule: fix test errors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/src/submodule.c b/src/submodule.c
index 3ec0307..147d3ae 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -660,7 +660,10 @@ int git_submodule_add_setup(
int use_gitlink)
{
int error = 0;
+ size_t path_len;
+ const char *dir;
git_config_backend *mods = NULL;
+ git_index *index;
git_submodule *sm = NULL;
git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
git_repository *subrepo = NULL;
@@ -688,6 +691,34 @@ int git_submodule_add_setup(
goto cleanup;
}
+ /* get the index for the repo */
+
+ if ((error = git_repository_index__weakptr(&index, repo)) < 0)
+ goto cleanup;
+
+ /* see if the submodule name exists as a file on the index */
+
+ if ((error = git_index_find(NULL, index, path)) == 0) {
+ giterr_set(GITERR_SUBMODULE,
+ "'%s' already exists in the index", path);
+ return GIT_EEXISTS;
+ }
+
+ /* We need the path to end with '/' so we can check it as a directory prefix */
+
+ path_len = strlen(path);
+ dir = git__malloc(path_len + 1);
+ strcpy(dir, path);
+ git_path_string_to_dir(dir, path_len + 1);
+
+ /* see if the submodule name exists as a directory on the index */
+
+ if ((error = git_index_find_prefix(NULL, index, dir)) == 0) {
+ giterr_set(GITERR_SUBMODULE,
+ "'%s' already exists in the index", path);
+ return GIT_EEXISTS;
+ }
+
/* update .gitmodules */
if (!(mods = open_gitmodules(repo, GITMODULES_CREATE))) {
diff --git a/tests/submodule/add.c b/tests/submodule/add.c
index c3b3e63..ca6500d 100644
--- a/tests/submodule/add.c
+++ b/tests/submodule/add.c
@@ -128,3 +128,69 @@ void test_submodule_add__url_relative_to_workdir(void)
assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo));
}
+
+void test_submodule_add__path_exists_in_index(void)
+{
+ git_index *index;
+ git_submodule *sm;
+ git_buf dirname = GIT_BUF_INIT;
+ git_buf filename = GIT_BUF_INIT;
+ FILE *fd;
+
+ /* In this repo, HEAD (master) has no remote tracking branc h*/
+ g_repo = cl_git_sandbox_init("testrepo");
+
+ git_buf_joinpath(&dirname, git_repository_workdir(g_repo), "/TestGitRepository");
+ git_buf_joinpath(&filename, dirname.ptr, "/test.txt");
+
+ mkdir(dirname.ptr, 0700);
+ fd = fopen(filename.ptr, "w");
+ fclose(fd);
+
+ cl_git_pass(
+ git_repository_index__weakptr(&index, g_repo)
+ );
+
+ cl_git_pass(
+ git_index_add_bypath(index, "TestGitRepository/test.txt")
+ );
+
+ cl_git_fail_with(
+ git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1),
+ GIT_EEXISTS
+ );
+
+ git_buf_free(&dirname);
+ 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;
+ FILE *fd;
+
+ /* In this repo, HEAD (master) has no remote tracking branc h*/
+ g_repo = cl_git_sandbox_init("testrepo");
+
+ git_buf_joinpath(&name, git_repository_workdir(g_repo), "/TestGitRepository");
+
+ fd = fopen(name.ptr, "w");
+ fclose(fd);
+
+ cl_git_pass(
+ git_repository_index__weakptr(&index, g_repo)
+ );
+
+ cl_git_pass(
+ git_index_add_bypath(index, "TestGitRepository")
+ );
+
+ cl_git_fail_with(
+ git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1),
+ GIT_EEXISTS
+ );
+
+ git_buf_free(&name);
+}