diff options
author | Jameson Miller <jamill@microsoft.com> | 2014-10-20 18:07:32 -0400 |
---|---|---|
committer | Jameson Miller <jamill@microsoft.com> | 2014-12-22 16:35:45 -0500 |
commit | b2ab887e1137207edb286812a3237b351ab39506 (patch) | |
tree | 38f060dd5fbe37fc6f1f7f0a34b3cc331b806930 | |
parent | 0bb237ed89a6700a1b6b884444ff044fd1467535 (diff) | |
download | libgit2-b2ab887e1137207edb286812a3237b351ab39506.tar.gz |
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.
18 files changed, 131 insertions, 10 deletions
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 Binary files differnew file mode 100644 index 000000000..6e22d7ffb --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/index diff --git a/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 b/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 Binary files differnew file mode 100644 index 000000000..9f0800d29 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 diff --git a/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 b/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 Binary files differnew file mode 100644 index 000000000..d0681ac40 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 diff --git a/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd b/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd Binary files differnew file mode 100644 index 000000000..b8961b0be --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd diff --git a/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a b/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a Binary files differnew file mode 100644 index 000000000..653238cd8 --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a diff --git a/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 b/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 Binary files differnew file mode 100644 index 000000000..dabf65b7e --- /dev/null +++ b/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 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 *); |