Skip to content

Commit 3fc8522

Browse files
committed
Merge branch 'sb/submodule-url-to-absolute'
Some codepaths failed to form a proper URL when .gitmodules record the URL to a submodule repository as relative to the repository of superproject, which has been corrected. * sb/submodule-url-to-absolute: submodule helper: convert relative URL to absolute URL if needed
2 parents ea100b6 + e0a862f commit 3fc8522

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

builtin/submodule--helper.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,26 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
584584
return 0;
585585
}
586586

587+
static char *compute_submodule_clone_url(const char *rel_url)
588+
{
589+
char *remoteurl, *relurl;
590+
char *remote = get_default_remote();
591+
struct strbuf remotesb = STRBUF_INIT;
592+
593+
strbuf_addf(&remotesb, "remote.%s.url", remote);
594+
if (git_config_get_string(remotesb.buf, &remoteurl)) {
595+
warning(_("could not look up configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
596+
remoteurl = xgetcwd();
597+
}
598+
relurl = relative_url(remoteurl, rel_url, NULL);
599+
600+
free(remote);
601+
free(remoteurl);
602+
strbuf_release(&remotesb);
603+
604+
return relurl;
605+
}
606+
587607
struct init_cb {
588608
const char *prefix;
589609
unsigned int flags;
@@ -634,21 +654,9 @@ static void init_submodule(const char *path, const char *prefix,
634654
/* Possibly a url relative to parent */
635655
if (starts_with_dot_dot_slash(url) ||
636656
starts_with_dot_slash(url)) {
637-
char *remoteurl, *relurl;
638-
char *remote = get_default_remote();
639-
struct strbuf remotesb = STRBUF_INIT;
640-
strbuf_addf(&remotesb, "remote.%s.url", remote);
641-
free(remote);
642-
643-
if (git_config_get_string(remotesb.buf, &remoteurl)) {
644-
warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
645-
remoteurl = xgetcwd();
646-
}
647-
relurl = relative_url(remoteurl, url, NULL);
648-
strbuf_release(&remotesb);
649-
free(remoteurl);
650-
free(url);
651-
url = relurl;
657+
char *oldurl = url;
658+
url = compute_submodule_clone_url(oldurl);
659+
free(oldurl);
652660
}
653661

654662
if (git_config_set_gently(sb.buf, url))
@@ -1582,6 +1590,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
15821590
struct strbuf sb = STRBUF_INIT;
15831591
const char *displaypath = NULL;
15841592
int needs_cloning = 0;
1593+
int need_free_url = 0;
15851594

15861595
if (ce_stage(ce)) {
15871596
if (suc->recursive_prefix)
@@ -1630,8 +1639,14 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
16301639

16311640
strbuf_reset(&sb);
16321641
strbuf_addf(&sb, "submodule.%s.url", sub->name);
1633-
if (repo_config_get_string_const(the_repository, sb.buf, &url))
1634-
url = sub->url;
1642+
if (repo_config_get_string_const(the_repository, sb.buf, &url)) {
1643+
if (starts_with_dot_slash(sub->url) ||
1644+
starts_with_dot_dot_slash(sub->url)) {
1645+
url = compute_submodule_clone_url(sub->url);
1646+
need_free_url = 1;
1647+
} else
1648+
url = sub->url;
1649+
}
16351650

16361651
strbuf_reset(&sb);
16371652
strbuf_addf(&sb, "%s/.git", ce->name);
@@ -1677,6 +1692,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
16771692
cleanup:
16781693
strbuf_reset(&displaypath_sb);
16791694
strbuf_reset(&sb);
1695+
if (need_free_url)
1696+
free((void*)url);
16801697

16811698
return needs_cloning;
16821699
}

t/t7400-submodule-basic.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,30 @@ test_expect_success 'submodule update and setting submodule.<name>.active' '
12241224
test_cmp expect actual
12251225
'
12261226

1227+
test_expect_success 'clone active submodule without submodule url set' '
1228+
test_when_finished "rm -rf test/test" &&
1229+
mkdir test &&
1230+
# another dir breaks accidental relative paths still being correct
1231+
git clone file://"$pwd"/multisuper test/test &&
1232+
(
1233+
cd test/test &&
1234+
git config submodule.active "." &&
1235+
1236+
# do not pass --init flag, as the submodule is already active:
1237+
git submodule update &&
1238+
git submodule status >actual_raw &&
1239+
1240+
cut -c 1,43- actual_raw >actual &&
1241+
cat >expect <<-\EOF &&
1242+
sub0 (test2)
1243+
sub1 (test2)
1244+
sub2 (test2)
1245+
sub3 (test2)
1246+
EOF
1247+
test_cmp expect actual
1248+
)
1249+
'
1250+
12271251
test_expect_success 'clone --recurse-submodules with a pathspec works' '
12281252
test_when_finished "rm -rf multisuper_clone" &&
12291253
cat >expected <<-\EOF &&

0 commit comments

Comments
 (0)