From b2ab887e1137207edb286812a3237b351ab39506 Mon Sep 17 00:00:00 2001 From: Jameson Miller Date: Mon, 20 Oct 2014 18:07:32 -0400 Subject: 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. --- src/submodule.c | 34 +++++++--- tests/resources/submodule_simple/.gitmodules | 3 + tests/resources/submodule_simple/.gitted/HEAD | 1 + tests/resources/submodule_simple/.gitted/config | 8 +++ .../resources/submodule_simple/.gitted/description | 1 + tests/resources/submodule_simple/.gitted/index | Bin 0 -> 184 bytes .../22/9cea838964f435d4fc2c11561ddb7447003609 | Bin 0 -> 134 bytes .../5b/19f7523fbf55c96153ff5a94875583f1115a36 | Bin 0 -> 91 bytes .../a8/575e6aaececba78823993e4f11abbc6172aabd | Bin 0 -> 174 bytes .../b4/f28943fad380f4ee3a9c6b95259b28204cc25a | Bin 0 -> 65 bytes .../d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 | Bin 0 -> 92 bytes .../resources/submodule_simple/.gitted/packed-refs | 3 + .../.gitted/refs/heads/alternate_1 | 1 + .../submodule_simple/.gitted/refs/heads/master | 1 + tests/submodule/init.c | 73 +++++++++++++++++++++ tests/submodule/repository_init.c | 1 + tests/submodule/submodule_helpers.c | 14 ++++ tests/submodule/submodule_helpers.h | 1 + 18 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 tests/resources/submodule_simple/.gitmodules create mode 100644 tests/resources/submodule_simple/.gitted/HEAD create mode 100644 tests/resources/submodule_simple/.gitted/config create mode 100644 tests/resources/submodule_simple/.gitted/description create mode 100644 tests/resources/submodule_simple/.gitted/index create mode 100644 tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 create mode 100644 tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 create mode 100644 tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd create mode 100644 tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a create mode 100644 tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 create mode 100644 tests/resources/submodule_simple/.gitted/packed-refs create mode 100644 tests/resources/submodule_simple/.gitted/refs/heads/alternate_1 create mode 100644 tests/resources/submodule_simple/.gitted/refs/heads/master create mode 100644 tests/submodule/init.c diff --git a/src/submodule.c b/src/submodule.c index 8dca0ae73..d2af1440a 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -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; } diff --git a/tests/resources/submodule_simple/.gitmodules b/tests/resources/submodule_simple/.gitmodules new file mode 100644 index 000000000..03150b4a7 --- /dev/null +++ b/tests/resources/submodule_simple/.gitmodules @@ -0,0 +1,3 @@ +[submodule "testrepo"] + path = testrepo + url = ../testrepo.git diff --git a/tests/resources/submodule_simple/.gitted/HEAD b/tests/resources/submodule_simple/.gitted/HEAD new file mode 100644 index 000000000..cb089cd89 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/resources/submodule_simple/.gitted/config b/tests/resources/submodule_simple/.gitted/config new file mode 100644 index 000000000..78387c50b --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/config @@ -0,0 +1,8 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = false + logallrefupdates = true + symlinks = false + ignorecase = true + hideDotFiles = dotGitOnly diff --git a/tests/resources/submodule_simple/.gitted/description b/tests/resources/submodule_simple/.gitted/description new file mode 100644 index 000000000..498b267a8 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests/resources/submodule_simple/.gitted/index b/tests/resources/submodule_simple/.gitted/index new file mode 100644 index 000000000..6e22d7ffb Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/index differ diff --git a/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 b/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 new file mode 100644 index 000000000..9f0800d29 Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 differ diff --git a/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 b/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 new file mode 100644 index 000000000..d0681ac40 Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 differ diff --git a/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd b/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd new file mode 100644 index 000000000..b8961b0be Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd differ diff --git a/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a b/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a new file mode 100644 index 000000000..653238cd8 Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a differ diff --git a/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 b/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 new file mode 100644 index 000000000..dabf65b7e Binary files /dev/null and b/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 differ diff --git a/tests/resources/submodule_simple/.gitted/packed-refs b/tests/resources/submodule_simple/.gitted/packed-refs new file mode 100644 index 000000000..040012653 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/packed-refs @@ -0,0 +1,3 @@ +# pack-refs with: peeled fully-peeled +229cea838964f435d4fc2c11561ddb7447003609 refs/remotes/origin/alternate_1 +a8575e6aaececba78823993e4f11abbc6172aabd refs/remotes/origin/master diff --git a/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1 b/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1 new file mode 100644 index 000000000..6f5196665 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1 @@ -0,0 +1 @@ +229cea838964f435d4fc2c11561ddb7447003609 diff --git a/tests/resources/submodule_simple/.gitted/refs/heads/master b/tests/resources/submodule_simple/.gitted/refs/heads/master new file mode 100644 index 000000000..f01cfb23f --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/refs/heads/master @@ -0,0 +1 @@ +a8575e6aaececba78823993e4f11abbc6172aabd diff --git a/tests/submodule/init.c b/tests/submodule/init.c new file mode 100644 index 000000000..c03bf4610 --- /dev/null +++ b/tests/submodule/init.c @@ -0,0 +1,73 @@ +#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); +} diff --git a/tests/submodule/repository_init.c b/tests/submodule/repository_init.c index e9733a658..bf1968d66 100644 --- a/tests/submodule/repository_init.c +++ b/tests/submodule/repository_init.c @@ -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 */ diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c index c6d04b40a..19bb04f75 100644 --- a/tests/submodule/submodule_helpers.c +++ b/tests/submodule/submodule_helpers.c @@ -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) diff --git a/tests/submodule/submodule_helpers.h b/tests/submodule/submodule_helpers.h index 4b2620bfa..1493f245f 100644 --- a/tests/submodule/submodule_helpers.h +++ b/tests/submodule/submodule_helpers.h @@ -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 *); -- cgit v1.2.1