diff options
Diffstat (limited to 'tests/libgit2/submodule/add.c')
-rw-r--r-- | tests/libgit2/submodule/add.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/tests/libgit2/submodule/add.c b/tests/libgit2/submodule/add.c new file mode 100644 index 000000000..ae5507d7f --- /dev/null +++ b/tests/libgit2/submodule/add.c @@ -0,0 +1,251 @@ +#include "clar_libgit2.h" +#include "posix.h" +#include "path.h" +#include "submodule_helpers.h" +#include "config/config_helpers.h" +#include "futils.h" +#include "repository.h" +#include "git2/sys/commit.h" + +static git_repository *g_repo = NULL; +static const char *valid_blob_id = "fa49b077972391ad58037050f2a75f74e3671e92"; + +void test_submodule_add__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static void assert_submodule_url(const char* name, const char *url) +{ + git_str key = GIT_STR_INIT; + + + cl_git_pass(git_str_printf(&key, "submodule.%s.url", name)); + assert_config_entry_value(g_repo, git_str_cstr(&key), url); + + git_str_dispose(&key); +} + +void test_submodule_add__url_absolute(void) +{ + git_submodule *sm; + git_repository *repo; + git_str dot_git_content = GIT_STR_INIT; + + g_repo = setup_fixture_submod2(); + + /* re-add existing submodule */ + cl_git_fail_with( + GIT_EEXISTS, + git_submodule_add_setup(NULL, g_repo, "whatever", "sm_unchanged", 1)); + + /* add a submodule using a gitlink */ + + cl_git_pass( + git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2", 1) + ); + git_submodule_free(sm); + + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2" "/.git")); + + cl_assert(git_fs_path_isdir("submod2/.git/modules")); + cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_libgit2")); + cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); + assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git"); + + cl_git_pass(git_repository_open(&repo, "submod2/" "sm_libgit2")); + + /* Verify worktree path is relative */ + assert_config_entry_value(repo, "core.worktree", "../../../sm_libgit2/"); + + /* Verify gitdir path is relative */ + cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_libgit2" "/.git")); + cl_assert_equal_s("gitdir: ../.git/modules/sm_libgit2/", dot_git_content.ptr); + + git_repository_free(repo); + git_str_dispose(&dot_git_content); + + /* add a submodule not using a gitlink */ + + cl_git_pass( + git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2b", 0) + ); + git_submodule_free(sm); + + cl_assert(git_fs_path_isdir("submod2/" "sm_libgit2b" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); + cl_assert(!git_fs_path_exists("submod2/.git/modules/" "sm_libgit2b")); + assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git"); +} + +void test_submodule_add__url_relative(void) +{ + git_submodule *sm; + git_remote *remote; + git_strarray problems = {0}; + + /* default remote url is https://github.com/libgit2/false.git */ + g_repo = cl_git_sandbox_init("testrepo2"); + + /* make sure we don't default to origin - rename origin -> test_remote */ + cl_git_pass(git_remote_rename(&problems, g_repo, "origin", "test_remote")); + cl_assert_equal_i(0, problems.count); + git_strarray_dispose(&problems); + cl_git_fail(git_remote_lookup(&remote, g_repo, "origin")); + + cl_git_pass( + git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1) + ); + git_submodule_free(sm); + + assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository"); +} + +void test_submodule_add__url_relative_to_origin(void) +{ + git_submodule *sm; + + /* default remote url is https://github.com/libgit2/false.git */ + g_repo = cl_git_sandbox_init("testrepo2"); + + cl_git_pass( + git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1) + ); + git_submodule_free(sm); + + assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository"); +} + +void test_submodule_add__url_relative_to_workdir(void) +{ + git_submodule *sm; + + /* In this repo, HEAD (master) has no remote tracking branc h*/ + g_repo = cl_git_sandbox_init("testrepo"); + + cl_git_pass( + git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1) + ); + git_submodule_free(sm); + + assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo)); +} + +static void test_add_entry( + git_index *index, + const char *idstr, + const char *path, + git_filemode_t mode) +{ + git_index_entry entry = {{0}}; + + cl_git_pass(git_oid_fromstr(&entry.id, idstr)); + + entry.path = path; + entry.mode = mode; + + cl_git_pass(git_index_add(index, &entry)); +} + +void test_submodule_add__path_exists_in_index(void) +{ + git_index *index; + git_submodule *sm; + git_str filename = GIT_STR_INIT; + + g_repo = cl_git_sandbox_init("testrepo"); + + cl_git_pass(git_str_joinpath(&filename, "subdirectory", "test.txt")); + + cl_git_pass(git_repository_index__weakptr(&index, g_repo)); + + test_add_entry(index, valid_blob_id, filename.ptr, GIT_FILEMODE_BLOB); + + cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS); + + git_submodule_free(sm); + git_str_dispose(&filename); +} + +void test_submodule_add__file_exists_in_index(void) +{ + git_index *index; + git_submodule *sm; + git_str name = GIT_STR_INIT; + + g_repo = cl_git_sandbox_init("testrepo"); + + cl_git_pass(git_repository_index__weakptr(&index, g_repo)); + + test_add_entry(index, valid_blob_id, "subdirectory", GIT_FILEMODE_BLOB); + + cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS); + + git_submodule_free(sm); + git_str_dispose(&name); +} + +void test_submodule_add__submodule_clone(void) +{ + git_oid tree_id, commit_id; + git_signature *sig; + git_submodule *sm; + git_index *index; + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + /* Create the submodule structure, clone into it and finalize */ + cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "testrepo-add", true)); + cl_git_pass(git_submodule_clone(NULL, sm, NULL)); + cl_git_pass(git_submodule_add_finalize(sm)); + + /* Create the submodule commit */ + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_index_write_tree(&tree_id, index)); + cl_git_pass(git_signature_now(&sig, "Submoduler", "submoduler@local")); + cl_git_pass(git_commit_create_from_ids(&commit_id, g_repo, "HEAD", sig, sig, NULL, "A submodule\n", + &tree_id, 0, NULL)); + + assert_submodule_exists(g_repo, "testrepo-add"); + + git_signature_free(sig); + git_submodule_free(sm); + git_index_free(index); +} + +void test_submodule_add__submodule_clone_into_nonempty_dir_succeeds(void) +{ + git_submodule *sm; + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + cl_git_pass(p_mkdir("empty_standard_repo/sm", 0777)); + cl_git_mkfile("empty_standard_repo/sm/foobar", ""); + + /* Create the submodule structure, clone into it and finalize */ + cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "sm", true)); + cl_git_pass(git_submodule_clone(NULL, sm, NULL)); + cl_git_pass(git_submodule_add_finalize(sm)); + + cl_assert(git_fs_path_exists("empty_standard_repo/sm/foobar")); + + assert_submodule_exists(g_repo, "sm"); + + git_submodule_free(sm); +} + +void test_submodule_add__submodule_clone_twice_fails(void) +{ + git_submodule *sm; + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + /* Create the submodule structure, clone into it and finalize */ + cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "sm", true)); + cl_git_pass(git_submodule_clone(NULL, sm, NULL)); + cl_git_pass(git_submodule_add_finalize(sm)); + + cl_git_fail(git_submodule_clone(NULL, sm, NULL)); + + git_submodule_free(sm); +} |