Skip to content

Commit bfa8312

Browse files
committed
Merge branch 'kj/renamed-submodule' into jch
The case where a new submodule takes a path where used to be a completely different subproject is now dealt a bit better than before. Comments? * kj/renamed-submodule: submodule: skip redundant active entries when pattern covers path submodule: prevent overwriting .gitmodules entry on path reuse
2 parents 7b6ee0a + 015518d commit bfa8312

File tree

3 files changed

+87
-11
lines changed

3 files changed

+87
-11
lines changed

builtin/submodule--helper.c

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "advice.h"
3333
#include "branch.h"
3434
#include "list-objects-filter-options.h"
35+
#include "wildmatch.h"
36+
#include "strbuf.h"
3537

3638
#define OPT_QUIET (1 << 0)
3739
#define OPT_CACHED (1 << 1)
@@ -3329,6 +3331,9 @@ static void configure_added_submodule(struct add_data *add_data)
33293331
char *key;
33303332
struct child_process add_submod = CHILD_PROCESS_INIT;
33313333
struct child_process add_gitmodules = CHILD_PROCESS_INIT;
3334+
const struct string_list *values;
3335+
size_t i;
3336+
int matched = 0;
33323337

33333338
key = xstrfmt("submodule.%s.url", add_data->sm_name);
33343339
git_config_set_gently(key, add_data->realrepo);
@@ -3371,20 +3376,25 @@ static void configure_added_submodule(struct add_data *add_data)
33713376
* is_submodule_active(), since that function needs to find
33723377
* out the value of "submodule.active" again anyway.
33733378
*/
3374-
if (!git_config_get("submodule.active")) {
3375-
/*
3376-
* If the submodule being added isn't already covered by the
3377-
* current configured pathspec, set the submodule's active flag
3378-
*/
3379-
if (!is_submodule_active(the_repository, add_data->sm_path)) {
3380-
key = xstrfmt("submodule.%s.active", add_data->sm_name);
3381-
git_config_set_gently(key, "true");
3382-
free(key);
3383-
}
3384-
} else {
3379+
if (git_config_get("submodule.active") || /* key absent */
3380+
git_config_get_string_multi("submodule.active", &values)) {
3381+
/* submodule.active is missing -> force-enable */
33853382
key = xstrfmt("submodule.%s.active", add_data->sm_name);
33863383
git_config_set_gently(key, "true");
33873384
free(key);
3385+
} else {
3386+
for (i = 0; i < values->nr; i++) {
3387+
const char *pat = values->items[i].string;
3388+
if (!wildmatch(pat, add_data->sm_path, 0)) { /* match found */
3389+
matched = 1;
3390+
break;
3391+
}
3392+
}
3393+
if (!matched) { /* no pattern matched -> force-enable */
3394+
key = xstrfmt("submodule.%s.active", add_data->sm_name);
3395+
git_config_set_gently(key, "true");
3396+
free(key);
3397+
}
33883398
}
33893399
}
33903400

@@ -3445,6 +3455,10 @@ static int module_add(int argc, const char **argv, const char *prefix,
34453455
struct add_data add_data = ADD_DATA_INIT;
34463456
const char *ref_storage_format = NULL;
34473457
char *to_free = NULL;
3458+
const struct submodule *existing;
3459+
struct strbuf buf = STRBUF_INIT;
3460+
int i;
3461+
char *sm_name_to_free = NULL;
34483462
struct option options[] = {
34493463
OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
34503464
N_("branch of repository to add as submodule")),
@@ -3547,6 +3561,29 @@ static int module_add(int argc, const char **argv, const char *prefix,
35473561
if(!add_data.sm_name)
35483562
add_data.sm_name = add_data.sm_path;
35493563

3564+
existing = submodule_from_name(the_repository,
3565+
null_oid(the_hash_algo),
3566+
add_data.sm_name);
3567+
3568+
if (existing && strcmp(existing->path, add_data.sm_path)) {
3569+
if (!force) {
3570+
die(_("submodule name '%s' already used for path '%s'"),
3571+
add_data.sm_name, existing->path);
3572+
}
3573+
3574+
/* --force: build <name><n> until unique */
3575+
for (i = 1; ; i++) {
3576+
strbuf_reset(&buf);
3577+
strbuf_addf(&buf, "%s%d", add_data.sm_name, i);
3578+
if (!submodule_from_name(the_repository,
3579+
null_oid(the_hash_algo),
3580+
buf.buf)) {
3581+
break;
3582+
}
3583+
}
3584+
3585+
add_data.sm_name = sm_name_to_free = strbuf_detach(&buf, NULL);
3586+
}
35503587
if (check_submodule_name(add_data.sm_name))
35513588
die(_("'%s' is not a valid submodule name"), add_data.sm_name);
35523589

@@ -3562,6 +3599,7 @@ static int module_add(int argc, const char **argv, const char *prefix,
35623599

35633600
ret = 0;
35643601
cleanup:
3602+
free(sm_name_to_free);
35653603
free(add_data.sm_path);
35663604
free(to_free);
35673605
strbuf_release(&sb);

t/t7400-submodule-basic.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,4 +1482,27 @@ test_expect_success '`submodule init` and `init.templateDir`' '
14821482
)
14831483
'
14841484

1485+
test_expect_success 'submodule add fails when name is reused' '
1486+
git init test-submodule &&
1487+
(
1488+
cd test-submodule &&
1489+
git commit --allow-empty -m init &&
1490+
1491+
git init ../child-origin &&
1492+
git -C ../child-origin commit --allow-empty -m init &&
1493+
1494+
git submodule add ../child-origin child &&
1495+
git commit -m "Add submodule child" &&
1496+
1497+
git mv child child_old &&
1498+
git commit -m "Move child to child_old" &&
1499+
1500+
# Now adding a *new* repo at the old name must fail
1501+
git init ../child2-origin &&
1502+
git -C ../child2-origin commit --allow-empty -m init &&
1503+
test_must_fail git submodule add ../child2-origin child
1504+
)
1505+
'
1506+
1507+
14851508
test_done

t/t7413-submodule-is-active.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,19 @@ test_expect_success 'is-active, submodule.active and submodule add' '
124124
git -C super2 config --get submodule.mod.active
125125
'
126126

127+
test_expect_success 'submodule add skips redundant active entry' '
128+
git init repo &&
129+
(
130+
cd repo &&
131+
git config submodule.active "lib/*" &&
132+
git commit --allow-empty -m init &&
133+
134+
git init ../lib-origin &&
135+
git -C ../lib-origin commit --allow-empty -m init &&
136+
137+
git submodule add ../lib-origin lib/foo &&
138+
! git config --get submodule.lib/foo.active
139+
)
140+
'
141+
127142
test_done

0 commit comments

Comments
 (0)