Ejemplo n.º 1
0
void test_index_bypath__add_submodule(void)
{
	unsigned int status;
	const char *sm_name = "sm_changed_head";

	cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
	cl_assert_equal_i(GIT_SUBMODULE_STATUS_WD_MODIFIED, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
	cl_git_pass(git_index_add_bypath(g_idx, sm_name));
	cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
	cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
}
Ejemplo n.º 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);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
 Submodule::status Submodule::get_status() const
 {
     unsigned int res;
     if (auto err = git_submodule_status(&res, repo_, git_submodule_name(sm_.get()), git_submodule_ignore(sm_.get())))
         throw error_t("git_submodule_status failed with error code " + std::to_string(err));
     else
         return static_cast<status>(res);
 }
Ejemplo n.º 7
0
unsigned int get_submodule_status(git_repository *repo, const char *name)
{
	unsigned int status = 0;

	assert(repo && name);

	cl_git_pass(git_submodule_status(&status, repo, name, GIT_SUBMODULE_IGNORE_UNSPECIFIED));

	return status;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
void test_submodule_status__ignore_none(void)
{
	unsigned int status;
	git_submodule *sm;
	git_buf path = GIT_BUF_INIT;

	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_assert_equal_i(GIT_ENOTFOUND,
		git_submodule_lookup(&sm, g_repo, "just_a_dir"));
	cl_assert_equal_i(GIT_EEXISTS,
		git_submodule_lookup(&sm, g_repo, "not-submodule"));
	cl_assert_equal_i(GIT_EEXISTS,
		git_submodule_lookup(&sm, g_repo, "not"));

	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((status & GIT_SUBMODULE_STATUS_WD_UNTRACKED) != 0);

	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);

	/* remove sm_changed_head from index */
	{
		git_index *index;
		size_t pos;

		cl_git_pass(git_repository_index(&index, g_repo));
		cl_assert(!git_index_find(&pos, index, "sm_changed_head"));
		cl_git_pass(git_index_remove(index, "sm_changed_head", 0));
		cl_git_pass(git_index_write(index));

		git_index_free(index);
	}

	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
	cl_git_pass(git_submodule_reload(sm));
	cl_git_pass(git_submodule_status(&status, sm));
	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_DELETED) != 0);

	git_buf_free(&path);
}
Ejemplo n.º 13
0
/**
 * This version of the output prefixes each path with two status
 * columns and shows submodule status information.
 */
static void print_short(git_repository *repo, git_status_list *status)
{
	size_t i, maxi = git_status_list_entrycount(status);
	const git_status_entry *s;
	char istatus, wstatus;
	const char *extra, *a, *b, *c;

	for (i = 0; i < maxi; ++i) {
		s = git_status_byindex(status, i);

		if (s->status == GIT_STATUS_CURRENT)
			continue;

		a = b = c = NULL;
		istatus = wstatus = ' ';
		extra = "";

		if (s->status & GIT_STATUS_INDEX_NEW)
			istatus = 'A';
		if (s->status & GIT_STATUS_INDEX_MODIFIED)
			istatus = 'M';
		if (s->status & GIT_STATUS_INDEX_DELETED)
			istatus = 'D';
		if (s->status & GIT_STATUS_INDEX_RENAMED)
			istatus = 'R';
		if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
			istatus = 'T';

		if (s->status & GIT_STATUS_WT_NEW) {
			if (istatus == ' ')
				istatus = '?';
			wstatus = '?';
		}
		if (s->status & GIT_STATUS_WT_MODIFIED)
			wstatus = 'M';
		if (s->status & GIT_STATUS_WT_DELETED)
			wstatus = 'D';
		if (s->status & GIT_STATUS_WT_RENAMED)
			wstatus = 'R';
		if (s->status & GIT_STATUS_WT_TYPECHANGE)
			wstatus = 'T';

		if (s->status & GIT_STATUS_IGNORED) {
			istatus = '!';
			wstatus = '!';
		}

		if (istatus == '?' && wstatus == '?')
			continue;

		/**
		 * A commit in a tree is how submodules are stored, so
		 * let's go take a look at its status.
		 */
		if (s->index_to_workdir &&
			s->index_to_workdir->new_file.mode == GIT_FILEMODE_COMMIT)
		{
			unsigned int smstatus = 0;

			if (!git_submodule_status(&smstatus, repo, s->index_to_workdir->new_file.path,
						  GIT_SUBMODULE_IGNORE_UNSPECIFIED)) {
				if (smstatus & GIT_SUBMODULE_STATUS_WD_MODIFIED)
					extra = " (new commits)";
				else if (smstatus & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
					extra = " (modified content)";
				else if (smstatus & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
					extra = " (modified content)";
				else if (smstatus & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
					extra = " (untracked content)";
			}
		}

		/**
		 * Now that we have all the information, format the output.
		 */

		if (s->head_to_index) {
			a = s->head_to_index->old_file.path;
			b = s->head_to_index->new_file.path;
		}
		if (s->index_to_workdir) {
			if (!a)
				a = s->index_to_workdir->old_file.path;
			if (!b)
				b = s->index_to_workdir->old_file.path;
			c = s->index_to_workdir->new_file.path;
		}

		if (istatus == 'R') {
			if (wstatus == 'R')
				printf("%c%c %s %s %s%s\n", istatus, wstatus, a, b, c, extra);
			else
				printf("%c%c %s %s%s\n", istatus, wstatus, a, b, extra);
		} else {
			if (wstatus == 'R')
				printf("%c%c %s %s%s\n", istatus, wstatus, a, c, extra);
			else
				printf("%c%c %s%s\n", istatus, wstatus, a, extra);
		}
	}

	for (i = 0; i < maxi; ++i) {
		s = git_status_byindex(status, i);

		if (s->status == GIT_STATUS_WT_NEW)
			printf("?? %s\n", s->index_to_workdir->old_file.path);
	}
}
Ejemplo n.º 14
0
void test_submodule_update__can_force_update(void)
{
	git_submodule *sm = NULL;
	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
	unsigned int submodule_status = 0;
	git_reference *branch_reference = NULL;
	git_object *branch_commit = NULL;

	g_repo = setup_fixture_submodule_simple();

	/* Initialize and update the sub repository */
	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);

	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);

	/* checkout the alternate_1 branch */
	checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;

	cl_git_pass(git_reference_lookup(&branch_reference, g_repo, "refs/heads/alternate_1"));
	cl_git_pass(git_reference_peel(&branch_commit, branch_reference, GIT_OBJ_COMMIT));
	cl_git_pass(git_checkout_tree(g_repo, branch_commit, &checkout_options));
	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(branch_reference)));

	/*
	 * Verify state after checkout of parent repository. The submodule ID in the
	 * HEAD commit and index should be updated, but not the workdir.
	 */
	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 |
		GIT_SUBMODULE_STATUS_WD_MODIFIED);

	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);

	/*
	 * Create a conflicting edit in the subrepository to verify that
	 * the submodule update action is blocked.
	 */
	cl_git_write2file("submodule_simple/testrepo/branch_file.txt", "a conflicting edit", 0,
		O_WRONLY | O_CREAT | O_TRUNC, 0777);

	/* forcefully checkout and verify the submodule state was updated. */
	update_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
	cl_git_pass(git_submodule_update(sm, 0, &update_options));
	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);

	git_submodule_free(sm);
	git_object_free(branch_commit);
	git_reference_free(branch_reference);
}
Ejemplo n.º 15
0
void test_submodule_update__update_already_checked_out_submodule(void)
{
	git_submodule *sm = NULL;
	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
	unsigned int submodule_status = 0;
	git_reference *branch_reference = NULL;
	git_object *branch_commit = NULL;
	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;

	/* Initialize and update the sub repository */
	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);

	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);

	/* checkout the alternate_1 branch */
	checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;

	cl_git_pass(git_reference_lookup(&branch_reference, g_repo, "refs/heads/alternate_1"));
	cl_git_pass(git_reference_peel(&branch_commit, branch_reference, GIT_OBJ_COMMIT));
	cl_git_pass(git_checkout_tree(g_repo, branch_commit, &checkout_options));
	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(branch_reference)));

	/*
	 * Verify state after checkout of parent repository. The submodule ID in the
	 * HEAD commit and index should be updated, but not the workdir.
	 */

	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 |
		GIT_SUBMODULE_STATUS_WD_MODIFIED);

	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);

	/*
	 * Update the submodule and verify the state.
	 * Now, the HEAD, index, and Workdir commits should all be updated to
	 * the new commit.
	 */
	cl_git_pass(git_submodule_update(sm, 0, &update_options));
	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);

	/* verify that the expected callbacks have been called. */
	cl_assert_equal_i(1, update_payload.checkout_progress_called);
	
	git_submodule_free(sm);
	git_object_free(branch_commit);
	git_reference_free(branch_reference);
}