void test_submodule_nosubs__reload_add_reload(void) { git_repository *repo = cl_git_sandbox_init("status"); git_submodule *sm; cl_git_pass(git_submodule_reload_all(repo, 0)); /* try one add with a reload (to make sure no errors happen) */ cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1)); cl_git_pass(git_submodule_reload_all(repo, 0)); cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm)); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2")); cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm)); git_submodule_free(sm); /* try one add without a reload (to make sure cache inval works, too) */ cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "libgit2-again", 1)); cl_assert_equal_s("libgit2-again", git_submodule_name(sm)); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, repo, "libgit2-again")); cl_assert_equal_s("libgit2-again", git_submodule_name(sm)); git_submodule_free(sm); }
void test_submodule_add__url_absolute(void) { git_submodule *sm; git_config *cfg; git_repository *repo; const char *worktree_path; git_buf dot_git_content = GIT_BUF_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_path_isfile("submod2/" "sm_libgit2" "/.git")); cl_assert(git_path_isdir("submod2/.git/modules")); cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2")); cl_assert(git_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 */ cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_get_string(&worktree_path, cfg, "core.worktree")); cl_assert_equal_s("../../../sm_libgit2/", worktree_path); /* 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_config_free(cfg); git_repository_free(repo); git_buf_free(&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_path_isdir("submod2/" "sm_libgit2b" "/.git")); cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); cl_assert(!git_path_exists("submod2/.git/modules/" "sm_libgit2b")); assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git"); }
static void add_submodule_with_commit(const char *name) { git_submodule *sm; git_repository *smrepo; git_index *idx; git_buf p = GIT_BUF_INIT; cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", name, 1)); assert_submodule_exists(g_repo, name); cl_git_pass(git_submodule_open(&smrepo, sm)); cl_git_pass(git_repository_index(&idx, smrepo)); cl_git_pass(git_buf_joinpath(&p, git_repository_workdir(smrepo), "file")); cl_git_mkfile(p.ptr, "new file"); git_buf_free(&p); cl_git_pass(git_index_add_bypath(idx, "file")); cl_git_pass(git_index_write(idx)); git_index_free(idx); cl_repo_commit_from_index(NULL, smrepo, NULL, 0, "initial commit"); git_repository_free(smrepo); cl_git_pass(git_submodule_add_finalize(sm)); git_submodule_free(sm); }
/* * call-seq: * submodules.setup_add(url, path[, options]) -> submodule * * Setup a new +submodule+ for checkout in +repository+. * * This does <tt>"git submodule add"</tt> up to the fetch and checkout of the * submodule contents. It prepares a new submodule, creates an entry in * +.gitmodules+ and creates an empty initialized repository either at the * given +path+ in the working directory or in +.git/modules+ with a gitlink * from the working directory to the new repository. * * To fully emulate <tt>"git submodule add"</tt> call this function, then open * the submodule repository and perform the clone step as needed. * Lastly, call Submodule#finalize_add to wrap up adding the new submodule and * +.gitmodules+ to the index to be ready to commit. * * - +url+: URL for the submodule's remote * - +path+: path at which the submodule should be created * * The following options can be passed in the +options+ Hash: * :gitlink :: * (defaults to +true+) should workdir contain a * gitlink to the repository in +.git/modules+ vs. repository * directly in workdir. * * Returns the newly created +submodule+ */ static VALUE rb_git_submodule_setup_add(int argc, VALUE *argv, VALUE self) { git_submodule *submodule; git_repository *repo; int error; int use_gitlink = 1; VALUE rb_repo, rb_url, rb_path, rb_options; rb_scan_args(argc, argv, "20:", &rb_url, &rb_path, &rb_options); Check_Type(rb_url, T_STRING); Check_Type(rb_path, T_STRING); rb_repo = rugged_owner(self); Data_Get_Struct(rb_repo, git_repository, repo); if (!NIL_P(rb_options)) { VALUE rb_val; rb_val = rb_hash_aref(rb_options, CSTR2SYM("gitlink")); use_gitlink = (rb_val != Qfalse); } error = git_submodule_add_setup( &submodule, repo, StringValueCStr(rb_url), StringValueCStr(rb_path), use_gitlink ); rugged_exception_check(error); return rugged_submodule_new(rb_repo, submodule); }
void test_submodule_modify__add(void) { git_submodule *sm; git_config *cfg; const char *s; /* re-add existing submodule */ cl_assert( git_submodule_add_setup(NULL, g_repo, "whatever", "sm_unchanged", 1) == GIT_EEXISTS ); /* add a submodule using a gitlink */ cl_git_pass( git_submodule_add_setup(&sm, g_repo, SM_LIBGIT2_URL, SM_LIBGIT2, 1) ); cl_assert(git_path_isfile("submod2/" SM_LIBGIT2 "/.git")); cl_assert(git_path_isdir("submod2/.git/modules")); cl_assert(git_path_isdir("submod2/.git/modules/" SM_LIBGIT2)); cl_assert(git_path_isfile("submod2/.git/modules/" SM_LIBGIT2 "/HEAD")); cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass( git_config_get_string(&s, cfg, "submodule." SM_LIBGIT2 ".url")); cl_assert_equal_s(s, SM_LIBGIT2_URL); git_config_free(cfg); /* add a submodule not using a gitlink */ cl_git_pass( git_submodule_add_setup(&sm, g_repo, SM_LIBGIT2_URL, SM_LIBGIT2B, 0) ); cl_assert(git_path_isdir("submod2/" SM_LIBGIT2B "/.git")); cl_assert(git_path_isfile("submod2/" SM_LIBGIT2B "/.git/HEAD")); cl_assert(!git_path_exists("submod2/.git/modules/" SM_LIBGIT2B)); cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass( git_config_get_string(&s, cfg, "submodule." SM_LIBGIT2B ".url")); cl_assert_equal_s(s, SM_LIBGIT2_URL); git_config_free(cfg); }
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)); }
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_nosubs__add(void) { git_repository *repo = cl_git_sandbox_init("status"); git_submodule *sm, *sm2; cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1)); cl_git_pass(git_submodule_lookup(&sm2, repo, "submodules/libgit2")); git_submodule_free(sm2); cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL)); git_submodule_free(sm); }
void test_submodule_add__url_absolute(void) { git_submodule *sm; 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_path_isfile("submod2/" "sm_libgit2" "/.git")); cl_assert(git_path_isdir("submod2/.git/modules")); cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2")); cl_assert(git_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git"); /* 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_path_isdir("submod2/" "sm_libgit2b" "/.git")); cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); cl_assert(!git_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; /* 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_load(&remote, g_repo, "origin")); cl_git_pass(git_remote_rename(remote, "test_remote", NULL, NULL)); cl_git_fail(git_remote_load(&remote, g_repo, "origin")); git_remote_free(remote); 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(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_free(&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_clone_nonetwork__clone_submodule(void) { git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT; git_index *index; git_oid tree_id, commit_id; git_submodule *sm; git_signature *sig; git_repository *sm_repo; cl_git_pass(git_repository_init(&g_repo, "willaddsubmodule", false)); /* Create the submodule structure, clone into it and finalize */ cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "testrepo", true)); clone_opts.repository_cb = just_return_repo; clone_opts.repository_cb_payload = sm; clone_opts.remote_cb = just_return_origin; clone_opts.remote_cb_payload = sm; cl_git_pass(git_clone(&sm_repo, cl_fixture("testrepo.git"), "testrepo", &clone_opts)); cl_git_pass(git_submodule_add_finalize(sm)); git_repository_free(sm_repo); git_submodule_free(sm); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_write_tree(&tree_id, index)); git_index_free(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)); git_signature_free(sig); assert_submodule_exists(g_repo, "testrepo"); }
void test_submodule_nosubs__add_and_delete(void) { git_repository *repo = cl_git_sandbox_init("status"); git_submodule *sm; git_buf buf = GIT_BUF_INIT; /* note lack of calls to git_submodule_reload_all - this *should* work */ cl_git_fail(git_submodule_lookup(NULL, repo, "libgit2")); cl_git_fail(git_submodule_lookup(NULL, repo, "submodules/libgit2")); /* create */ cl_git_pass(git_submodule_add_setup( &sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1)); cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm)); cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm)); git_submodule_free(sm); cl_git_pass(git_futils_readbuffer(&buf, "status/.gitmodules")); cl_assert(strstr(buf.ptr, "[submodule \"submodules/libgit2\"]") != NULL); cl_assert(strstr(buf.ptr, "path = submodules/libgit2") != NULL); git_buf_free(&buf); /* lookup */ cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2")); cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2")); cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm)); cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm)); git_submodule_free(sm); /* update name */ cl_git_rewritefile( "status/.gitmodules", "[submodule \"libgit2\"]\n" " path = submodules/libgit2\n" " url = https://github.com/libgit2/libgit2.git\n"); cl_git_pass(git_submodule_lookup(&sm, repo, "libgit2")); cl_assert_equal_s("libgit2", git_submodule_name(sm)); cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm)); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2")); git_submodule_free(sm); /* revert name update */ cl_git_rewritefile( "status/.gitmodules", "[submodule \"submodules/libgit2\"]\n" " path = submodules/libgit2\n" " url = https://github.com/libgit2/libgit2.git\n"); cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2")); cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2")); git_submodule_free(sm); /* remove completely */ cl_must_pass(p_unlink("status/.gitmodules")); cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2")); cl_git_fail(git_submodule_lookup(&sm, repo, "submodules/libgit2")); }
void test_submodule_lookup__just_added(void) { git_submodule *sm; git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT; git_reference *original_head = NULL; refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); baseline_tests(); cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules")); cl_git_pass(git_repository_head(&original_head, g_repo)); cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_just_added", 1)); git_submodule_free(sm); assert_submodule_exists(g_repo, "sm_just_added"); cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1)); assert_submodule_exists(g_repo, "sm_just_added_2"); cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */ git_submodule_free(sm); add_submodule_with_commit("sm_just_added_head"); cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head"); assert_submodule_exists(g_repo, "sm_just_added_head"); add_submodule_with_commit("sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_idx"); cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules")); cl_git_append2file( "submod2/.gitmodules", "\n[submodule \"mismatch_name\"]\n" "\tpath = mismatch_path\n" "\turl = https://example.com/example.git\n\n"); assert_submodule_exists(g_repo, "mismatch_name"); assert_submodule_exists(g_repo, "mismatch_path"); assert_submodule_exists(g_repo, "sm_just_added"); assert_submodule_exists(g_repo, "sm_just_added_2"); assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap2.ptr); git_buf_free(&snap2); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); assert_submodule_exists(g_repo, "sm_just_added"); assert_submodule_exists(g_repo, "sm_just_added_2"); assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap1.ptr); git_buf_free(&snap1); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); /* note error code change, because add_setup made a repo in the workdir */ refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS); refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS); /* these still exist in index and head respectively */ assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); { git_index *idx; cl_git_pass(git_repository_index(&idx, g_repo)); cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx")); cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head")); cl_git_pass(git_index_write(idx)); git_index_free(idx); } refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS); assert_submodule_exists(g_repo, "sm_just_added_head"); { git_signature *sig; cl_git_pass(git_signature_now(&sig, "resetter", "*****@*****.**")); cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, sig, "move head back")); git_signature_free(sig); git_reference_free(original_head); } refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS); }