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_status__ignore_untracked(void) { unsigned int status; git_submodule *sm; git_buf path = GIT_BUF_INIT; git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_UNTRACKED; cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "sm_unchanged")); cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_submodule_foreach(g_repo, set_sm_ignore, &ign)); cl_git_fail(git_submodule_lookup(&sm, g_repo, "not-submodule")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_index")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED) != 0); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_file")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED) != 0); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_untracked_file")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status)); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_missing_commits")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0); /* removed sm_unchanged for deleted workdir */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0); /* now mkdir sm_unchanged to test uninitialized */ cl_git_pass(git_futils_mkdir(git_buf_cstr(&path), NULL, 0755, 0)); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_git_pass(git_submodule_reload(sm)); cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0); /* update sm_changed_head in index */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head")); cl_git_pass(git_submodule_add_to_index(sm, true)); /* reload is not needed because add_to_index updates the submodule data */ cl_git_pass(git_submodule_status(&status, sm)); cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0); git_buf_free(&path); }
void test_submodule_nosubs__bad_gitmodules(void) { git_repository *repo = cl_git_sandbox_init("status"); cl_git_mkfile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=flooble\n\n"); cl_git_rewritefile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=rebase\n\n"); cl_git_pass(git_submodule_lookup(NULL, repo, "foobar")); cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(NULL, repo, "subdir")); }
void test_submodule_lookup__accessors(void) { git_submodule *sm; const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0"; cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_assert(git_submodule_owner(sm) == g_repo); cl_assert_equal_s("sm_unchanged", git_submodule_name(sm)); cl_assert(git__suffixcmp(git_submodule_path(sm), "sm_unchanged") == 0); cl_assert(git__suffixcmp(git_submodule_url(sm), "/submod2_target") == 0); cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0); cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE); cl_assert(git_submodule_update(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head")); cl_assert_equal_s("sm_changed_head", git_submodule_name(sm)); cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_wd_id(sm), "3d9386c507f6b093471a3e324085657a3c2b4247") == 0); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited")); cl_assert_equal_s("sm_added_and_uncommited", git_submodule_name(sm)); cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0); cl_assert(git_submodule_head_id(sm) == NULL); cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0); git_submodule_free(sm); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_missing_commits")); cl_assert_equal_s("sm_missing_commits", git_submodule_name(sm)); cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0); cl_assert(git_oid_streq(git_submodule_wd_id(sm), "5e4963595a9774b90524d35a807169049de8ccad") == 0); git_submodule_free(sm); }
void test_submodule_update__update_and_init_submodule(void) { git_submodule *sm; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; unsigned int submodule_status = 0; g_repo = setup_fixture_submodule_simple(); /* get the submodule */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); cl_git_pass(git_submodule_status(&submodule_status, sm)); cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_WD_UNINITIALIZED); /* update (with option to initialize sub repo) */ cl_git_pass(git_submodule_update(sm, 1, &update_options)); /* verify expected state */ cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); git_submodule_free(sm); }
void test_submodule_status__untracked_dirs_containing_ignored_files(void) { git_buf path = GIT_BUF_INIT; unsigned int status, expected; git_submodule *sm; cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "modules/sm_unchanged/info/exclude")); cl_git_append2file(git_buf_cstr(&path), "\n*.ignored\n"); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "sm_unchanged/directory")); cl_git_pass(git_futils_mkdir(git_buf_cstr(&path), NULL, 0755, 0)); cl_git_pass(git_buf_joinpath(&path, git_buf_cstr(&path), "i_am.ignored")); cl_git_mkfile(git_buf_cstr(&path), "ignored this file, please\n"); cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status)); expected = GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD; cl_assert(status == expected); git_buf_free(&path); }
void test_rebase_submodule__init_untracked(void) { git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; git_buf untracked_path = GIT_BUF_INIT; FILE *fp; git_submodule *submodule; cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/asparagus")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master")); cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); cl_git_pass(git_submodule_lookup(&submodule, repo, "my-submodule")); cl_git_pass(git_submodule_update(submodule, 1, NULL)); git_buf_printf(&untracked_path, "%s/my-submodule/untracked", git_repository_workdir(repo)); fp = fopen(git_buf_cstr(&untracked_path), "w"); fprintf(fp, "An untracked file in a submodule should not block a rebase\n"); fclose(fp); git_buf_free(&untracked_path); cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL)); git_submodule_free(submodule); git_annotated_commit_free(branch_head); git_annotated_commit_free(upstream_head); git_reference_free(branch_ref); git_reference_free(upstream_ref); git_rebase_free(rebase); }
/* When looking at the short name for a submodule, we need to prevent * people from overwriting the `.git` file in the submodule working * directory itself. We don't want to look at the actual repository * path, since it will be in the super's repository above us, and * typically named with the name of our subrepository. Consequently, * preventing access to the short name of the actual repository path * would prevent us from creating files with the same name as the * subrepo. (Eg, a submodule named "libgit2" could not contain a file * named "libgit2", which would be unfortunate.) */ void test_repo_reservedname__submodule_pointer(void) { #ifdef GIT_WIN32 git_repository *super_repo, *sub_repo; git_submodule *sub; git_buf *sub_reserved; size_t sub_reserved_len; if (!cl_sandbox_supports_8dot3()) clar__skip(); super_repo = setup_fixture_submod2(); assert_submodule_exists(super_repo, "sm_unchanged"); cl_git_pass(git_submodule_lookup(&sub, super_repo, "sm_unchanged")); cl_git_pass(git_submodule_open(&sub_repo, sub)); cl_assert(git_repository__reserved_names(&sub_reserved, &sub_reserved_len, sub_repo, true)); cl_assert_equal_i(2, sub_reserved_len); cl_assert_equal_s(".git", sub_reserved[0].ptr); cl_assert_equal_s("GIT~1", sub_reserved[1].ptr); git_submodule_free(sub); git_repository_free(sub_repo); #endif }
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_snapshot(&cfg, g_repo)); cl_git_pass(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); git_submodule_free(sm); }
void test_submodule_modify__save_last(void) { git_submodule *sm; cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only")); cl_git_pass(git_submodule_save(sm)); }
void test_submodule_repository_init__basic(void) { git_submodule *sm; git_repository *repo; git_buf dot_git_content = GIT_BUF_INIT; 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 */ assert_config_entry_value(repo, "core.worktree", "../../../sm_gitmodules_only/"); /* Verify gitlink */ cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_gitmodules_only" "/.git")); cl_assert_equal_s("gitdir: ../.git/modules/sm_gitmodules_only/", dot_git_content.ptr); cl_assert(git_path_isfile("submod2/" "sm_gitmodules_only" "/.git")); cl_assert(git_path_isdir("submod2/.git/modules")); cl_assert(git_path_isdir("submod2/.git/modules/" "sm_gitmodules_only")); cl_assert(git_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD")); git_submodule_free(sm); git_repository_free(repo); git_buf_free(&dot_git_content); }
void test_submodule_nosubs__lookup(void) { git_repository *repo = cl_git_sandbox_init("status"); git_submodule *sm = NULL; p_mkdir("status/subrepo", 0777); cl_git_mkfile("status/subrepo/.git", "gitdir: ../.git"); cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir")); cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo")); cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir")); cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo")); }
static int cb_submodule__each(git_submodule *submodule, const char *name, void *data) { struct rugged_cb_payload *payload = data; git_repository *repo; git_submodule *dummy_sm; VALUE rb_repo; rb_repo = payload->rb_data; Data_Get_Struct(rb_repo, git_repository, repo); /* The submodule passed here has it's refcount decreased just after * the foreach finishes. The only way to increase that refcount is * to lookup the submodule. * * This should not return an error as the submodule name here is valid * and exists, as it was just passed to this callback. */ git_submodule_lookup(&dummy_sm, repo, git_submodule_name(submodule)); rb_protect( rb_yield, rugged_submodule_new(rb_repo, dummy_sm), &payload->exception ); return (payload->exception) ? GIT_ERROR : GIT_OK; }
void test_submodule_modify__sync(void) { git_submodule *sm1, *sm2, *sm3; git_config *cfg; const char *str; #define SM1 "sm_unchanged" #define SM2 "sm_changed_head" #define SM3 "sm_added_and_uncommited" /* look up some submodules */ cl_git_pass(git_submodule_lookup(&sm1, g_repo, SM1)); cl_git_pass(git_submodule_lookup(&sm2, g_repo, SM2)); cl_git_pass(git_submodule_lookup(&sm3, g_repo, SM3)); /* At this point, the .git/config URLs for the submodules have * not be rewritten with the absolute paths (although the * .gitmodules have. Let's confirm that they DO NOT match * yet, then we can do a sync to make them match... */ /* check submodule info does not match before sync */ cl_git_pass(git_repository_config_snapshot(&cfg, g_repo)); cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM1".url")); cl_assert(strcmp(git_submodule_url(sm1), str) != 0); cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM2".url")); cl_assert(strcmp(git_submodule_url(sm2), str) != 0); cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM3".url")); cl_assert(strcmp(git_submodule_url(sm3), str) != 0); git_config_free(cfg); /* sync all the submodules */ cl_git_pass(git_submodule_foreach(g_repo, sync_one_submodule, NULL)); /* check that submodule config is updated */ assert_submodule_url_is_synced( sm1, "submodule."SM1".url", "branch.origin.remote"); assert_submodule_url_is_synced( sm2, "submodule."SM2".url", "branch.origin.remote"); assert_submodule_url_is_synced( sm3, "submodule."SM3".url", "branch.origin.remote"); git_submodule_free(sm1); git_submodule_free(sm2); git_submodule_free(sm3); }
void refute__submodule_exists( git_repository *repo, const char *name, int expected_error, const char *msg, const char *file, int line) { clar__assert_equal( file, line, msg, 1, "%i", expected_error, (int)(git_submodule_lookup(NULL, repo, name))); }
void test_submodule_lookup__simple_lookup(void) { git_submodule *sm; /* lookup existing */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_assert(sm); /* lookup pending change in .gitmodules that is not in HEAD */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited")); cl_assert(sm); /* lookup pending change in .gitmodules that is neither in HEAD nor index */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only")); cl_assert(sm); /* lookup git repo subdir that is not added as submodule */ cl_assert(git_submodule_lookup(&sm, g_repo, "not_submodule") == GIT_EEXISTS); /* lookup existing directory that is not a submodule */ cl_assert(git_submodule_lookup(&sm, g_repo, "just_a_dir") == GIT_ENOTFOUND); /* lookup existing file that is not a submodule */ cl_assert(git_submodule_lookup(&sm, g_repo, "just_a_file") == GIT_ENOTFOUND); /* lookup non-existent item */ cl_assert(git_submodule_lookup(&sm, g_repo, "no_such_file") == GIT_ENOTFOUND); }
void assert__submodule_exists( git_repository *repo, const char *name, const char *msg, const char *file, int line) { git_submodule *sm; int error = git_submodule_lookup(&sm, repo, name); if (error) cl_git_report_failure(error, file, line, msg); cl_assert_at_line(sm != NULL, file, line); git_submodule_free(sm); }
unsigned int get_submodule_status(git_repository *repo, const char *name) { git_submodule *sm = NULL; unsigned int status = 0; cl_git_pass(git_submodule_lookup(&sm, repo, name)); cl_assert(sm); cl_git_pass(git_submodule_status(&status, sm)); git_submodule_free(sm); return status; }
static bool checkout_is_workdir_modified( checkout_data *data, const git_diff_file *baseitem, const git_index_entry *wditem) { git_oid oid; const git_index_entry *ie; /* handle "modified" submodule */ if (wditem->mode == GIT_FILEMODE_COMMIT) { git_submodule *sm; unsigned int sm_status = 0; const git_oid *sm_oid = NULL; if (git_submodule_lookup(&sm, data->repo, wditem->path) < 0 || git_submodule_status(&sm_status, sm) < 0) return true; if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status)) return true; sm_oid = git_submodule_wd_id(sm); if (!sm_oid) return false; return (git_oid__cmp(&baseitem->oid, sm_oid) != 0); } /* Look at the cache to decide if the workdir is modified. If not, * we can simply compare the oid in the cache to the baseitem instead * of hashing the file. */ if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) { if (wditem->mtime.seconds == ie->mtime.seconds && wditem->mtime.nanoseconds == ie->mtime.nanoseconds && wditem->file_size == ie->file_size) return (git_oid__cmp(&baseitem->oid, &ie->oid) != 0); } /* depending on where base is coming from, we may or may not know * the actual size of the data, so we can't rely on this shortcut. */ if (baseitem->size && wditem->file_size != baseitem->size) return true; if (git_diff__oid_for_file( data->repo, wditem->path, wditem->mode, wditem->file_size, &oid) < 0) return false; return (git_oid__cmp(&baseitem->oid, &oid) != 0); }
static int diff_file_content_commit_to_str( git_diff_file_content *fc, bool check_status) { char oid[GIT_OID_HEXSZ+1]; git_buf content = GIT_BUF_INIT; const char *status = ""; if (check_status) { int error = 0; git_submodule *sm = NULL; unsigned int sm_status = 0; const git_oid *sm_head; if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) { /* GIT_EEXISTS means a "submodule" that has not been git added */ if (error == GIT_EEXISTS) { giterr_clear(); error = 0; } return error; } if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) { git_submodule_free(sm); return error; } /* update OID if we didn't have it previously */ if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 && ((sm_head = git_submodule_wd_id(sm)) != NULL || (sm_head = git_submodule_head_id(sm)) != NULL)) { git_oid_cpy(&fc->file->id, sm_head); fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status)) status = "-dirty"; git_submodule_free(sm); } git_oid_tostr(oid, sizeof(oid), &fc->file->id); if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) return -1; fc->map.len = git_buf_len(&content); fc->map.data = git_buf_detach(&content); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; return 0; }
static bool submodule_is_config_only( checkout_data *data, const char *path) { git_submodule *sm = NULL; unsigned int sm_loc = 0; if (git_submodule_lookup(&sm, data->repo, path) < 0 || git_submodule_location(&sm_loc, sm) < 0 || sm_loc == GIT_SUBMODULE_STATUS_IN_CONFIG) return true; return false; }
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_status__unchanged(void) { unsigned int status, expected; git_submodule *sm; cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_git_pass(git_submodule_status(&status, sm)); cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status)); expected = GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD; cl_assert(status == expected); }
void test_submodule_update__unitialized_submodule_no_init(void) { git_submodule *sm; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; g_repo = setup_fixture_submodule_simple(); /* get the submodule */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); /* updating an unitialized repository throws */ cl_git_fail_with( GIT_ERROR, git_submodule_update(sm, 0, &update_options)); git_submodule_free(sm); }
void test_submodule_update__update_submodule(void) { git_submodule *sm; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; unsigned int submodule_status = 0; struct update_submodule_cb_payload update_payload = { 0 }; g_repo = setup_fixture_submodule_simple(); update_options.checkout_opts.progress_cb = checkout_progress_cb; update_options.checkout_opts.progress_payload = &update_payload; update_options.remote_callbacks.update_tips = update_tips; update_options.remote_callbacks.payload = &update_payload; /* get the submodule */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); /* verify the initial state of the submodule */ cl_git_pass(git_submodule_status(&submodule_status, sm)); cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_WD_UNINITIALIZED); /* initialize and update the submodule */ cl_git_pass(git_submodule_init(sm, 0)); cl_git_pass(git_submodule_update(sm, 0, &update_options)); /* verify state */ cl_git_pass(git_submodule_status(&submodule_status, sm)); cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD); cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0); /* verify that the expected callbacks have been called. */ cl_assert_equal_i(1, update_payload.checkout_progress_called); cl_assert_equal_i(1, update_payload.update_tips_called); git_submodule_free(sm); }
static int checksum_tree_callback (const char *root, const git_tree_entry *entry, void *data) { int iter_r = 1; int tmp_r; struct TreeWalkData *twdata = data; git_otype otype = git_tree_entry_type (entry); switch (otype) { case GIT_OBJ_TREE: case GIT_OBJ_BLOB: if (!checksum_object_id (twdata, git_tree_entry_id (entry), twdata->error)) { twdata->caught_error = TRUE; return -1; } break; case GIT_OBJ_COMMIT: { git_submodule *submod = NULL; tmp_r = git_submodule_lookup (&submod, twdata->repo, git_tree_entry_name (entry)); if (!handle_libgit_ret (tmp_r, twdata->error)) goto out; tmp_r = checksum_submodule (twdata, submod); if (tmp_r != 0) goto out; git_submodule_free (submod); } break; default: g_assert_not_reached (); } iter_r = 0; out: if (iter_r > 0) twdata->caught_error = TRUE; return iter_r; }
void test_submodule_init__relative_url_detached_head(void) { git_submodule *sm; git_config *cfg; git_buf absolute_url = GIT_BUF_INIT; const char *config_url; git_reference *head_ref = NULL; git_object *head_commit = NULL; g_repo = setup_fixture_submodule_simple(); /* Put the parent repository into a detached head state. */ cl_git_pass(git_repository_head(&head_ref, g_repo)); cl_git_pass(git_reference_peel(&head_commit, head_ref, GIT_OBJ_COMMIT)); cl_git_pass(git_repository_set_head_detached(g_repo, git_commit_id((git_commit *)head_commit))); 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_snapshot(&cfg, g_repo)); cl_git_pass(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); git_object_free(head_commit); git_reference_free(head_ref); git_submodule_free(sm); }
/* * call-seq: * submodules[name] -> submodule or nil * * Lookup +submodule+ by +name+ or +path+ (they are usually the same) in * +repository+. * * Returns +nil+ if submodule does not exist. * * Raises <tt>Rugged::SubmoduleError</tt> if submodule exists only in working * directory (i.e. there is a subdirectory that is a valid self-contained git * repository) and is not mentioned in the +HEAD+, the index and the config. */ static VALUE rb_git_submodule_collection_aref(VALUE self, VALUE rb_name) { git_repository *repo; git_submodule *submodule; int error; VALUE rb_repo = rugged_owner(self); Data_Get_Struct(rb_repo, git_repository, repo); Check_Type(rb_name, T_STRING); error = git_submodule_lookup( &submodule, repo, StringValueCStr(rb_name) ); if (error == GIT_ENOTFOUND) return Qnil; rugged_exception_check(error); return rugged_submodule_new(rb_repo, submodule); }
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_modify__edit_and_save(void) { git_submodule *sm1, *sm2; char *old_url; git_submodule_ignore_t old_ignore; git_submodule_update_t old_update; git_repository *r2; int old_fetchrecurse; cl_git_pass(git_submodule_lookup(&sm1, g_repo, "sm_changed_head")); old_url = git__strdup(git_submodule_url(sm1)); /* modify properties of submodule */ cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL)); old_ignore = git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED); old_update = git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE); old_fetchrecurse = git_submodule_set_fetch_recurse_submodules(sm1, 1); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* revert without saving (and confirm setters return old value) */ cl_git_pass(git_submodule_set_url(sm1, old_url)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_DEFAULT)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_DEFAULT)); cl_assert_equal_i( 1, git_submodule_set_fetch_recurse_submodules(sm1, old_fetchrecurse)); /* check that revert was successful */ cl_assert_equal_s(old_url, git_submodule_url(sm1)); cl_assert_equal_i((int)old_ignore, (int)git_submodule_ignore(sm1)); cl_assert_equal_i((int)old_update, (int)git_submodule_update(sm1)); cl_assert_equal_i( old_fetchrecurse, git_submodule_fetch_recurse_submodules(sm1)); /* modify properties of submodule (again) */ cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL)); git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED); git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE); git_submodule_set_fetch_recurse_submodules(sm1, 1); /* call save */ cl_git_pass(git_submodule_save(sm1)); /* attempt to "revert" values */ git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_DEFAULT); git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_DEFAULT); /* but ignore and update should NOT revert because the DEFAULT * should now be the newly saved value... */ cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* call reload and check that the new values are loaded */ cl_git_pass(git_submodule_reload(sm1)); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm1)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm1)); /* open a second copy of the repo and compare submodule */ cl_git_pass(git_repository_open(&r2, "submod2")); cl_git_pass(git_submodule_lookup(&sm2, r2, "sm_changed_head")); cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm2)); cl_assert_equal_i( (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm2)); cl_assert_equal_i( (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update(sm2)); cl_assert_equal_i(1, git_submodule_fetch_recurse_submodules(sm2)); git_repository_free(r2); git__free(old_url); }