Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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"));
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
/* 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
}
Пример #9
0
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);
}
Пример #10
0
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));
}
Пример #11
0
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);
}
Пример #12
0
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;
}
Пример #14
0
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);
}
Пример #15
0
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)));
}
Пример #16
0
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);
}
Пример #17
0
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);
}
Пример #18
0
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;
}
Пример #19
0
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);
}
Пример #20
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;
}
Пример #21
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;
}
Пример #22
0
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);
}
Пример #23
0
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);
}
Пример #24
0
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);
}
Пример #25
0
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);
}
Пример #26
0
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;
}
Пример #27
0
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);
}
Пример #29
0
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"));
}
Пример #30
0
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);
}