Commit b2ab887e by Jameson Miller

submodule init should resolve relative url paths

Submodule init should handle relative paths in .gitmodules files
and resolve these urls when updating the git config file.
parent 0bb237ed
......@@ -381,10 +381,6 @@ int git_submodule_add_setup(
return GIT_EEXISTS;
}
/* resolve parameters */
if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0)
goto cleanup;
/* validate and normalize path */
if (git__prefixcmp(path, git_repository_workdir(repo)) == 0)
......@@ -409,7 +405,7 @@ int git_submodule_add_setup(
goto cleanup;
if ((error = submodule_config_key_trunc_puts(&name, "url")) < 0 ||
(error = git_config_file_set_string(mods, name.ptr, real_url.ptr)) < 0)
(error = git_config_file_set_string(mods, name.ptr, url)) < 0)
goto cleanup;
git_buf_clear(&name);
......@@ -425,7 +421,12 @@ int git_submodule_add_setup(
*/
if (!(git_path_exists(name.ptr) &&
git_path_contains(&name, DOT_GIT))) {
if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
/* resolve the actual URL to use */
if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0)
goto cleanup;
if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
goto cleanup;
}
......@@ -466,13 +467,24 @@ int git_submodule_repo_init(
{
int error;
git_repository *sub_repo = NULL;
const char *configured_url;
git_config *cfg = NULL;
git_buf buf = GIT_BUF_INIT;
assert(out && sm);
error = submodule_repo_init(&sub_repo, sm->repo, sm->path, sm->url, use_gitlink);
/* get the configured remote url of the submodule */
if ((error = git_buf_printf(&buf, "submodule.%s.url", sm->name)) < 0 ||
(error = git_repository_config(&cfg, sm->repo)) < 0 ||
(error = git_config_get_string(&configured_url, cfg, buf.ptr)) < 0 ||
(error = submodule_repo_init(&sub_repo, sm->repo, sm->path, configured_url, use_gitlink)) < 0)
goto done;
*out = sub_repo;
done:
git_config_free(cfg);
git_buf_free(&buf);
return error;
}
......@@ -827,7 +839,7 @@ int git_submodule_init(git_submodule *sm, int overwrite)
{
int error;
const char *val;
git_buf key = GIT_BUF_INIT;
git_buf key = GIT_BUF_INIT, effective_submodule_url = GIT_BUF_INIT;
git_config *cfg = NULL;
if (!sm->url) {
......@@ -841,9 +853,10 @@ int git_submodule_init(git_submodule *sm, int overwrite)
/* write "submodule.NAME.url" */
if ((error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 ||
if ((git_submodule_resolve_url(&effective_submodule_url, sm->repo, sm->url)) < 0 ||
(error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 ||
(error = git_config__update_entry(
cfg, key.ptr, sm->url, overwrite != 0, false)) < 0)
cfg, key.ptr, effective_submodule_url.ptr, overwrite != 0, false)) < 0)
goto cleanup;
/* write "submodule.NAME.update" if not default */
......@@ -861,6 +874,7 @@ int git_submodule_init(git_submodule *sm, int overwrite)
cleanup:
git_config_free(cfg);
git_buf_free(&key);
git_buf_free(&effective_submodule_url);
return error;
}
......
[submodule "testrepo"]
path = testrepo
url = ../testrepo.git
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
Unnamed repository; edit this file 'description' to name the repository.
# pack-refs with: peeled fully-peeled
229cea838964f435d4fc2c11561ddb7447003609 refs/remotes/origin/alternate_1
a8575e6aaececba78823993e4f11abbc6172aabd refs/remotes/origin/master
a8575e6aaececba78823993e4f11abbc6172aabd
#include "clar_libgit2.h"
#include "posix.h"
#include "path.h"
#include "submodule_helpers.h"
#include "fileops.h"
static git_repository *g_repo = NULL;
void test_submodule_init__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_submodule_init__absolute_url(void)
{
git_submodule *sm;
git_config *cfg;
git_buf absolute_url = GIT_BUF_INIT;
const char *config_url;
g_repo = setup_fixture_submodule_simple();
cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
/* write the absolute url to the .gitmodules file*/
cl_git_pass(git_submodule_set_url(sm, absolute_url.ptr));
/* verify that the .gitmodules is set with an absolute path*/
cl_assert_equal_s(absolute_url.ptr, git_submodule_url(sm));
/* init and verify that absolute path is written to .git/config */
cl_git_pass(git_submodule_init(sm, false));
cl_git_pass(git_repository_config(&cfg, g_repo));
git_config_get_string(&config_url, cfg, "submodule.testrepo.url");
cl_assert_equal_s(absolute_url.ptr, config_url);
git_buf_free(&absolute_url);
git_config_free(cfg);
}
void test_submodule_init__relative_url(void)
{
git_submodule *sm;
git_config *cfg;
git_buf absolute_url = GIT_BUF_INIT;
const char *config_url;
g_repo = setup_fixture_submodule_simple();
cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
/* verify that the .gitmodules is set with an absolute path*/
cl_assert_equal_s("../testrepo.git", git_submodule_url(sm));
/* init and verify that absolute path is written to .git/config */
cl_git_pass(git_submodule_init(sm, false));
cl_git_pass(git_repository_config(&cfg, g_repo));
git_config_get_string(&config_url, cfg, "submodule.testrepo.url");
cl_assert_equal_s(absolute_url.ptr, config_url);
git_buf_free(&absolute_url);
git_config_free(cfg);
}
......@@ -17,6 +17,7 @@ void test_submodule_repository_init__basic(void)
g_repo = setup_fixture_submod2();
cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only"));
cl_git_pass(git_submodule_init(sm, 0));
cl_git_pass(git_submodule_repo_init(&repo, sm, 1));
/* Verify worktree */
......
......@@ -126,6 +126,20 @@ git_repository *setup_fixture_submod2(void)
return repo;
}
git_repository *setup_fixture_submodule_simple(void)
{
git_repository *repo = cl_git_sandbox_init("submodule_simple");
cl_fixture_sandbox("testrepo.git");
p_mkdir("submodule_simple/testrepo", 0777);
cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");
cl_git_pass(git_repository_reinit_filesystem(repo, 1));
return repo;
}
void assert__submodule_exists(
git_repository *repo, const char *name,
const char *msg, const char *file, int line)
......
......@@ -3,6 +3,7 @@ extern void rewrite_gitmodules(const char *workdir);
/* these will automatically set a cleanup callback */
extern git_repository *setup_fixture_submodules(void);
extern git_repository *setup_fixture_submod2(void);
extern git_repository *setup_fixture_submodule_simple(void);
extern unsigned int get_submodule_status(git_repository *, const char *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment