Skip to content

Commit ad1c435

Browse files
Carson HowardCarson Howard
authored andcommitted
submodule: check index for prefix before adding submodule
submodule: check path and prefix before adding submodule submodule: fix test errors
1 parent 217add9 commit ad1c435

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/submodule.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,10 @@ int git_submodule_add_setup(
660660
int use_gitlink)
661661
{
662662
int error = 0;
663+
size_t path_len;
664+
const char *dir;
663665
git_config_backend *mods = NULL;
666+
git_index *index;
664667
git_submodule *sm = NULL;
665668
git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
666669
git_repository *subrepo = NULL;
@@ -688,6 +691,34 @@ int git_submodule_add_setup(
688691
goto cleanup;
689692
}
690693

694+
/* get the index for the repo */
695+
696+
if ((error = git_repository_index__weakptr(&index, repo)) < 0)
697+
goto cleanup;
698+
699+
/* see if the submodule name exists as a file on the index */
700+
701+
if ((error = git_index_find(NULL, index, path)) == 0) {
702+
giterr_set(GITERR_SUBMODULE,
703+
"'%s' already exists in the index", path);
704+
return GIT_EEXISTS;
705+
}
706+
707+
/* We need the path to end with '/' so we can check it as a directory prefix */
708+
709+
path_len = strlen(path);
710+
dir = git__malloc(path_len + 1);
711+
strcpy(dir, path);
712+
git_path_string_to_dir(dir, path_len + 1);
713+
714+
/* see if the submodule name exists as a directory on the index */
715+
716+
if ((error = git_index_find_prefix(NULL, index, dir)) == 0) {
717+
giterr_set(GITERR_SUBMODULE,
718+
"'%s' already exists in the index", path);
719+
return GIT_EEXISTS;
720+
}
721+
691722
/* update .gitmodules */
692723

693724
if (!(mods = open_gitmodules(repo, GITMODULES_CREATE))) {

tests/submodule/add.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,69 @@ void test_submodule_add__url_relative_to_workdir(void)
128128

129129
assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo));
130130
}
131+
132+
void test_submodule_add__path_exists_in_index(void)
133+
{
134+
git_index *index;
135+
git_submodule *sm;
136+
git_buf dirname = GIT_BUF_INIT;
137+
git_buf filename = GIT_BUF_INIT;
138+
FILE *fd;
139+
140+
/* In this repo, HEAD (master) has no remote tracking branc h*/
141+
g_repo = cl_git_sandbox_init("testrepo");
142+
143+
git_buf_joinpath(&dirname, git_repository_workdir(g_repo), "/TestGitRepository");
144+
git_buf_joinpath(&filename, dirname.ptr, "/test.txt");
145+
146+
mkdir(dirname.ptr, 0700);
147+
fd = fopen(filename.ptr, "w");
148+
fclose(fd);
149+
150+
cl_git_pass(
151+
git_repository_index__weakptr(&index, g_repo)
152+
);
153+
154+
cl_git_pass(
155+
git_index_add_bypath(index, "TestGitRepository/test.txt")
156+
);
157+
158+
cl_git_fail_with(
159+
git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1),
160+
GIT_EEXISTS
161+
);
162+
163+
git_buf_free(&dirname);
164+
git_buf_free(&filename);
165+
}
166+
167+
void test_submodule_add__file_exists_in_index(void)
168+
{
169+
git_index *index;
170+
git_submodule *sm;
171+
git_buf name = GIT_BUF_INIT;
172+
FILE *fd;
173+
174+
/* In this repo, HEAD (master) has no remote tracking branc h*/
175+
g_repo = cl_git_sandbox_init("testrepo");
176+
177+
git_buf_joinpath(&name, git_repository_workdir(g_repo), "/TestGitRepository");
178+
179+
fd = fopen(name.ptr, "w");
180+
fclose(fd);
181+
182+
cl_git_pass(
183+
git_repository_index__weakptr(&index, g_repo)
184+
);
185+
186+
cl_git_pass(
187+
git_index_add_bypath(index, "TestGitRepository")
188+
);
189+
190+
cl_git_fail_with(
191+
git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1),
192+
GIT_EEXISTS
193+
);
194+
195+
git_buf_free(&name);
196+
}

0 commit comments

Comments
 (0)