Skip to content

Commit ba64f50

Browse files
authored
Merge pull request libgit2#5322 from kdj0c/fix_sub_sync
Fix git_submodule_sync with relative url
2 parents 33f93bf + 11e8ee1 commit ba64f50

File tree

2 files changed

+70
-56
lines changed

2 files changed

+70
-56
lines changed

src/submodule.c

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,50 +1420,46 @@ int git_submodule_init(git_submodule *sm, int overwrite)
14201420

14211421
int git_submodule_sync(git_submodule *sm)
14221422
{
1423-
int error = 0;
1424-
git_config *cfg = NULL;
1425-
git_buf key = GIT_BUF_INIT;
1423+
git_buf key = GIT_BUF_INIT, url = GIT_BUF_INIT, remote_name = GIT_BUF_INIT;
14261424
git_repository *smrepo = NULL;
1425+
git_config *cfg = NULL;
1426+
int error = 0;
14271427

14281428
if (!sm->url) {
1429-
git_error_set(GIT_ERROR_SUBMODULE,
1430-
"no URL configured for submodule '%s'", sm->name);
1429+
git_error_set(GIT_ERROR_SUBMODULE, "no URL configured for submodule '%s'", sm->name);
14311430
return -1;
14321431
}
14331432

14341433
/* copy URL over to config only if it already exists */
1434+
if ((error = git_repository_config__weakptr(&cfg, sm->repo)) < 0 ||
1435+
(error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 ||
1436+
(error = git_submodule_resolve_url(&url, sm->repo, sm->url)) < 0 ||
1437+
(error = git_config__update_entry(cfg, key.ptr, url.ptr, true, true)) < 0)
1438+
goto out;
14351439

1436-
if (!(error = git_repository_config__weakptr(&cfg, sm->repo)) &&
1437-
!(error = git_buf_printf(&key, "submodule.%s.url", sm->name)))
1438-
error = git_config__update_entry(cfg, key.ptr, sm->url, true, true);
1440+
if (!(sm->flags & GIT_SUBMODULE_STATUS_IN_WD))
1441+
goto out;
14391442

14401443
/* if submodule exists in the working directory, update remote url */
1444+
if ((error = git_submodule_open(&smrepo, sm)) < 0 ||
1445+
(error = git_repository_config__weakptr(&cfg, smrepo)) < 0)
1446+
goto out;
14411447

1442-
if (!error &&
1443-
(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0 &&
1444-
!(error = git_submodule_open(&smrepo, sm)))
1445-
{
1446-
git_buf remote_name = GIT_BUF_INIT;
1447-
1448-
if ((error = git_repository_config__weakptr(&cfg, smrepo)) < 0)
1449-
/* return error from reading submodule config */;
1450-
else if ((error = lookup_head_remote_key(&remote_name, smrepo)) < 0) {
1451-
git_error_clear();
1452-
error = git_buf_sets(&key, "remote.origin.url");
1453-
} else {
1454-
error = git_buf_join3(
1455-
&key, '.', "remote", remote_name.ptr, "url");
1456-
git_buf_dispose(&remote_name);
1457-
}
1458-
1459-
if (!error)
1460-
error = git_config__update_entry(cfg, key.ptr, sm->url, true, false);
1461-
1462-
git_repository_free(smrepo);
1448+
if (lookup_head_remote_key(&remote_name, smrepo) == 0) {
1449+
if ((error = git_buf_join3(&key, '.', "remote", remote_name.ptr, "url")) < 0)
1450+
goto out;
1451+
} else if ((error = git_buf_sets(&key, "remote.origin.url")) < 0) {
1452+
goto out;
14631453
}
14641454

1465-
git_buf_dispose(&key);
1455+
if ((error = git_config__update_entry(cfg, key.ptr, url.ptr, true, false)) < 0)
1456+
goto out;
14661457

1458+
out:
1459+
git_repository_free(smrepo);
1460+
git_buf_dispose(&remote_name);
1461+
git_buf_dispose(&key);
1462+
git_buf_dispose(&url);
14671463
return error;
14681464
}
14691465

@@ -1606,43 +1602,40 @@ static int submodule_update_head(git_submodule *submodule)
16061602

16071603
int git_submodule_reload(git_submodule *sm, int force)
16081604
{
1609-
int error = 0, isvalid;
1610-
git_config *mods;
1605+
git_config *mods = NULL;
1606+
int error;
16111607

16121608
GIT_UNUSED(force);
16131609

16141610
assert(sm);
16151611

1616-
isvalid = git_submodule_name_is_valid(sm->repo, sm->name, 0);
1617-
if (isvalid <= 0) {
1612+
if ((error = git_submodule_name_is_valid(sm->repo, sm->name, 0)) <= 0)
16181613
/* This should come with a warning, but we've no API for that */
1619-
return isvalid;
1620-
}
1614+
goto out;
16211615

1622-
if (!git_repository_is_bare(sm->repo)) {
1623-
/* refresh config data */
1624-
if ((error = gitmodules_snapshot(&mods, sm->repo)) < 0 && error != GIT_ENOTFOUND)
1625-
return error;
1626-
if (mods != NULL) {
1627-
error = submodule_read_config(sm, mods);
1628-
git_config_free(mods);
1616+
if (git_repository_is_bare(sm->repo))
1617+
goto out;
16291618

1630-
if (error < 0)
1631-
return error;
1632-
}
1619+
/* refresh config data */
1620+
if ((error = gitmodules_snapshot(&mods, sm->repo)) < 0 && error != GIT_ENOTFOUND)
1621+
goto out;
16331622

1634-
/* refresh wd data */
1635-
sm->flags &=
1636-
~(GIT_SUBMODULE_STATUS_IN_WD |
1637-
GIT_SUBMODULE_STATUS__WD_OID_VALID |
1638-
GIT_SUBMODULE_STATUS__WD_FLAGS);
1623+
if (mods != NULL && (error = submodule_read_config(sm, mods)) < 0)
1624+
goto out;
16391625

1640-
error = submodule_load_from_wd_lite(sm);
1641-
}
1626+
/* refresh wd data */
1627+
sm->flags &=
1628+
~(GIT_SUBMODULE_STATUS_IN_WD |
1629+
GIT_SUBMODULE_STATUS__WD_OID_VALID |
1630+
GIT_SUBMODULE_STATUS__WD_FLAGS);
16421631

1643-
if (error == 0 && (error = submodule_update_index(sm)) == 0)
1644-
error = submodule_update_head(sm);
1632+
if ((error = submodule_load_from_wd_lite(sm)) < 0 ||
1633+
(error = submodule_update_index(sm)) < 0 ||
1634+
(error = submodule_update_head(sm)) < 0)
1635+
goto out;
16451636

1637+
out:
1638+
git_config_free(mods);
16461639
return error;
16471640
}
16481641

@@ -2168,7 +2161,7 @@ static int lookup_default_remote(git_remote **remote, git_repository *repo)
21682161
int error = lookup_head_remote(remote, repo);
21692162

21702163
/* if that failed, use 'origin' instead */
2171-
if (error == GIT_ENOTFOUND)
2164+
if (error == GIT_ENOTFOUND || error == GIT_EUNBORNBRANCH)
21722165
error = git_remote_lookup(remote, repo, "origin");
21732166

21742167
if (error == GIT_ENOTFOUND)

tests/submodule/modify.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,24 @@ void test_submodule_modify__set_url(void)
210210
cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm));
211211
git_submodule_free(sm);
212212
}
213+
214+
void test_submodule_modify__set_relative_url(void)
215+
{
216+
git_buf path = GIT_BUF_INIT;
217+
git_repository *repo;
218+
git_submodule *sm;
219+
220+
cl_git_pass(git_submodule_set_url(g_repo, SM1, "../relative-url"));
221+
cl_git_pass(git_submodule_lookup(&sm, g_repo, SM1));
222+
cl_git_pass(git_submodule_sync(sm));
223+
cl_git_pass(git_submodule_open(&repo, sm));
224+
225+
cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "relative-url"));
226+
227+
assert_config_entry_value(g_repo, "submodule."SM1".url", path.ptr);
228+
assert_config_entry_value(repo, "remote.origin.url", path.ptr);
229+
230+
git_repository_free(repo);
231+
git_submodule_free(sm);
232+
git_buf_dispose(&path);
233+
}

0 commit comments

Comments
 (0)