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( ...@@ -381,10 +381,6 @@ int git_submodule_add_setup(
return GIT_EEXISTS; return GIT_EEXISTS;
} }
/* resolve parameters */
if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0)
goto cleanup;
/* validate and normalize path */ /* validate and normalize path */
if (git__prefixcmp(path, git_repository_workdir(repo)) == 0) if (git__prefixcmp(path, git_repository_workdir(repo)) == 0)
...@@ -409,7 +405,7 @@ int git_submodule_add_setup( ...@@ -409,7 +405,7 @@ int git_submodule_add_setup(
goto cleanup; goto cleanup;
if ((error = submodule_config_key_trunc_puts(&name, "url")) < 0 || 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; goto cleanup;
git_buf_clear(&name); git_buf_clear(&name);
...@@ -425,6 +421,11 @@ int git_submodule_add_setup( ...@@ -425,6 +421,11 @@ int git_submodule_add_setup(
*/ */
if (!(git_path_exists(name.ptr) && if (!(git_path_exists(name.ptr) &&
git_path_contains(&name, DOT_GIT))) { git_path_contains(&name, DOT_GIT))) {
/* 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) if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
goto cleanup; goto cleanup;
} }
...@@ -466,13 +467,24 @@ int git_submodule_repo_init( ...@@ -466,13 +467,24 @@ int git_submodule_repo_init(
{ {
int error; int error;
git_repository *sub_repo = NULL; git_repository *sub_repo = NULL;
const char *configured_url;
git_config *cfg = NULL;
git_buf buf = GIT_BUF_INIT;
assert(out && sm); 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; *out = sub_repo;
done:
git_config_free(cfg);
git_buf_free(&buf);
return error; return error;
} }
...@@ -827,7 +839,7 @@ int git_submodule_init(git_submodule *sm, int overwrite) ...@@ -827,7 +839,7 @@ int git_submodule_init(git_submodule *sm, int overwrite)
{ {
int error; int error;
const char *val; 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; git_config *cfg = NULL;
if (!sm->url) { if (!sm->url) {
...@@ -841,9 +853,10 @@ int git_submodule_init(git_submodule *sm, int overwrite) ...@@ -841,9 +853,10 @@ int git_submodule_init(git_submodule *sm, int overwrite)
/* write "submodule.NAME.url" */ /* 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( (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; goto cleanup;
/* write "submodule.NAME.update" if not default */ /* write "submodule.NAME.update" if not default */
...@@ -861,6 +874,7 @@ int git_submodule_init(git_submodule *sm, int overwrite) ...@@ -861,6 +874,7 @@ int git_submodule_init(git_submodule *sm, int overwrite)
cleanup: cleanup:
git_config_free(cfg); git_config_free(cfg);
git_buf_free(&key); git_buf_free(&key);
git_buf_free(&effective_submodule_url);
return error; 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) ...@@ -17,6 +17,7 @@ void test_submodule_repository_init__basic(void)
g_repo = setup_fixture_submod2(); g_repo = setup_fixture_submod2();
cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only")); 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)); cl_git_pass(git_submodule_repo_init(&repo, sm, 1));
/* Verify worktree */ /* Verify worktree */
......
...@@ -126,6 +126,20 @@ git_repository *setup_fixture_submod2(void) ...@@ -126,6 +126,20 @@ git_repository *setup_fixture_submod2(void)
return repo; 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( void assert__submodule_exists(
git_repository *repo, const char *name, git_repository *repo, const char *name,
const char *msg, const char *file, int line) const char *msg, const char *file, int line)
......
...@@ -3,6 +3,7 @@ extern void rewrite_gitmodules(const char *workdir); ...@@ -3,6 +3,7 @@ extern void rewrite_gitmodules(const char *workdir);
/* these will automatically set a cleanup callback */ /* these will automatically set a cleanup callback */
extern git_repository *setup_fixture_submodules(void); extern git_repository *setup_fixture_submodules(void);
extern git_repository *setup_fixture_submod2(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 *); 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