struct add_data add_data = ADD_DATA_INIT;
const char *ref_storage_format = NULL;
char *to_free = NULL;
+ const struct submodule *existing;
+ struct strbuf buf = STRBUF_INIT;
+ int i;
+ char *sm_name_to_free = NULL;
struct option options[] = {
OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
N_("branch of repository to add as submodule")),
if(!add_data.sm_name)
add_data.sm_name = add_data.sm_path;
+ existing = submodule_from_name(the_repository,
+ null_oid(the_hash_algo),
+ add_data.sm_name);
+
+ if (existing && strcmp(existing->path, add_data.sm_path)) {
+ if (!force) {
+ die(_("submodule name '%s' already used for path '%s'"),
+ add_data.sm_name, existing->path);
+ }
+
+ /* --force: build <name><n> until unique */
+ for (i = 1; ; i++) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "%s%d", add_data.sm_name, i);
+ if (!submodule_from_name(the_repository,
+ null_oid(the_hash_algo),
+ buf.buf)) {
+ break;
+ }
+ }
+
+ add_data.sm_name = sm_name_to_free = strbuf_detach(&buf, NULL);
+ }
if (check_submodule_name(add_data.sm_name))
die(_("'%s' is not a valid submodule name"), add_data.sm_name);
ret = 0;
cleanup:
+ free(sm_name_to_free);
free(add_data.sm_path);
free(to_free);
strbuf_release(&sb);
)
'
+test_expect_success 'submodule add fails when name is reused' '
+ git init test-submodule &&
+ (
+ cd test-submodule &&
+ git commit --allow-empty -m init &&
+
+ git init ../child-origin &&
+ git -C ../child-origin commit --allow-empty -m init &&
+
+ git submodule add ../child-origin child &&
+ git commit -m "Add submodule child" &&
+
+ git mv child child_old &&
+ git commit -m "Move child to child_old" &&
+
+ # Now adding a *new* repo at the old name must fail
+ git init ../child2-origin &&
+ git -C ../child2-origin commit --allow-empty -m init &&
+ test_must_fail git submodule add ../child2-origin child
+ )
+'
+
+
test_done