Example #1
0
void test_repo_init__extended_with_template_and_shared_mode(void)
{
	git_buf expected = GIT_BUF_INIT;
	git_buf actual = GIT_BUF_INIT;
	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	int filemode = true;
	const char *repo_path = NULL;

	cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl");
	template_sandbox("template");

	opts.flags = GIT_REPOSITORY_INIT_MKPATH |
		GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
	opts.template_path = "template";
	opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;

	cl_git_pass(git_repository_init_ext(&_repo, "init_shared_from_tpl", &opts));

	cl_assert(!git_repository_is_bare(_repo));
	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/"));

	filemode = cl_repo_get_bool(_repo, "core.filemode");

	cl_git_pass(git_futils_readbuffer(
		&expected, "template/description"));
	cl_git_pass(git_futils_readbuffer(
		&actual, "init_shared_from_tpl/.git/description"));

	cl_assert_equal_s(expected.ptr, actual.ptr);

	git_buf_free(&expected);
	git_buf_free(&actual);

	repo_path = git_repository_path(_repo);
	assert_mode_seems_okay(repo_path, "hooks",
		GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
	assert_mode_seems_okay(repo_path, "info",
		GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
	assert_mode_seems_okay(repo_path, "description",
		GIT_FILEMODE_BLOB, false, filemode);

	/* for a non-symlinked hook, it should have shared permissions now */
	assert_hooks_match(
		"template", git_repository_path(_repo),
		"hooks/update.sample", filemode);

	/* for a symlinked hook, the permissions still should match the
	 * source link, not the GIT_REPOSITORY_INIT_SHARED_GROUP value
	 */
	assert_hooks_match(
		"template", git_repository_path(_repo),
		"hooks/link.sample", filemode);

	cl_fixture_cleanup("template");
}
Example #2
0
void test_reset_hard__resetting_reverts_modified_files(void)
{
	git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
	int i;
	static const char *files[4] = {
		"current_file",
		"modified_file",
		"staged_new_file",
		"staged_changes_modified_file" };
	static const char *before[4] = {
		"current_file\n",
		"modified_file\nmodified_file\n",
		"staged_new_file\n",
		"staged_changes_modified_file\nstaged_changes_modified_file\nstaged_changes_modified_file\n"
	};
	static const char *after[4] = {
		"current_file\n",
		"modified_file\n",
		/* wrong value because reset is still slightly incorrect */
		"staged_new_file\n",
		/* right value: NULL, */
		"staged_changes_modified_file\n"
	};
	const char *wd = git_repository_workdir(repo);

	cl_assert(wd);

	for (i = 0; i < 4; ++i) {
		cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
		cl_git_pass(git_futils_readbuffer(&content, path.ptr));
		cl_assert_equal_s(before[i], content.ptr);
	}

	retrieve_target_from_oid(
		&target, repo, "26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f");

	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD));

	for (i = 0; i < 4; ++i) {
		cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
		if (after[i]) {
			cl_git_pass(git_futils_readbuffer(&content, path.ptr));
			cl_assert(strequal_ignore_eol(after[i], content.ptr));
		} else {
			cl_assert(!git_path_exists(path.ptr));
		}
	}

	git_buf_free(&content);
	git_buf_free(&path);
}
Example #3
0
void test_reset_hard__resetting_reverts_modified_files(void)
{
    git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
    int i;
    static const char *files[4] = {
        "current_file",
        "modified_file",
        "staged_new_file",
        "staged_changes_modified_file"
    };
    static const char *before[4] = {
        "current_file\n",
        "modified_file\nmodified_file\n",
        "staged_new_file\n",
        "staged_changes_modified_file\nstaged_changes_modified_file\nstaged_changes_modified_file\n"
    };
    static const char *after[4] = {
        "current_file\n",
        "modified_file\n",
        NULL,
        "staged_changes_modified_file\n"
    };
    const char *wd = git_repository_workdir(repo);

    cl_assert(wd);

    for (i = 0; i < 4; ++i) {
        cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
        cl_git_pass(git_futils_readbuffer(&content, path.ptr));
        cl_assert_equal_s(before[i], content.ptr);
    }

    cl_git_pass(git_revparse_single(&target, repo, "26a125e"));

    cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));

    for (i = 0; i < 4; ++i) {
        cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
        if (after[i]) {
            cl_git_pass(git_futils_readbuffer(&content, path.ptr));
            cl_assert(strequal_ignore_eol(after[i], content.ptr));
        } else {
            cl_assert(!git_path_exists(path.ptr));
        }
    }

    git_buf_free(&content);
    git_buf_free(&path);
}
Example #4
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;
	git_strarray array, *active_refs = NULL;

	cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
	fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;

	if(fetchspec != NULL) {
		array.count = 1;
		array.strings = (char **) &fetchspec;
		active_refs = &array;
	}

	cl_git_pass(git_remote_fetch(remote, active_refs, &fetch_opts, NULL));
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_dispose(&fetchhead_buf);

	cl_assert(equals);
}
Example #5
0
static int read_loose(git_rawobj *out, git_buf *loc)
{
	int error;
	git_buf obj = GIT_BUF_INIT;

	assert(out && loc);

	if (git_buf_oom(loc))
		return -1;

	out->data = NULL;
	out->len = 0;
	out->type = GIT_OBJ_BAD;

	if ((error = git_futils_readbuffer(&obj, loc->ptr)) < 0)
		goto done;

	if (!is_zlib_compressed_data((unsigned char *)obj.ptr, obj.size))
		error = read_loose_packlike(out, &obj);
	else
		error = read_loose_standard(out, &obj);

done:
	git_buf_dispose(&obj);
	return error;
}
Example #6
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;
	git_strarray array, *active_refs = NULL;

	cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);

	if(fetchspec != NULL) {
		array.count = 1;
		array.strings = (char **) &fetchspec;
		active_refs = &array;
	}

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote, active_refs));
	cl_git_pass(git_remote_update_tips(remote, NULL));
	git_remote_disconnect(remote);
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_free(&fetchhead_buf);

	cl_assert(equals);
}
Example #7
0
/*
 * Read the contents of `file_path` and set `path_out` to the repo dir that
 * it points to.  Before calling, set `path_out` to the base directory that
 * should be used if the contents of `file_path` are a relative path.
 */
static int read_gitfile(git_buf *path_out, const char *file_path)
{
	int     error = 0;
	git_buf file = GIT_BUF_INIT;
	size_t  prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);

	assert(path_out && file_path);

	if (git_futils_readbuffer(&file, file_path) < 0)
		return -1;

	git_buf_rtrim(&file);
	/* apparently on Windows, some people use backslashes in paths */
	git_path_mkposix(file.ptr);

	if (git_buf_len(&file) <= prefix_len ||
		memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
	{
		giterr_set(GITERR_REPOSITORY,
			"The `.git` file at '%s' is malformed", file_path);
		error = -1;
	}
	else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
		const char *gitlink = git_buf_cstr(&file) + prefix_len;
		while (*gitlink && git__isspace(*gitlink)) gitlink++;

		error = git_path_prettify_dir(
			path_out, gitlink, git_buf_cstr(path_out));
	}

	git_buf_free(&file);
	return error;
}
Example #8
0
void test_checkout_index__conflicts_honor_coreautocrlf(void)
{
#ifdef GIT_WIN32
	git_index *index;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_buf conflicting_buf = GIT_BUF_INIT;

	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	cl_git_pass(git_repository_index(&index, g_repo));

	add_conflict(index, "conflicting.txt");
	cl_git_pass(git_index_write(index));

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

	cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
	cl_assert(strcmp(conflicting_buf.ptr,
		"<<<<<<< ours\r\n"
		"this file is changed in master and branch\r\n"
		"=======\r\n"
		"this file is changed in branch and master\r\n"
		">>>>>>> theirs\r\n") == 0);
	git_buf_free(&conflicting_buf);

	git_index_free(index);
#endif
}
Example #9
0
/*
 * Read the contents of `file_path` and set `path_out` to the repo dir that
 * it points to.  Before calling, set `path_out` to the base directory that
 * should be used if the contents of `file_path` are a relative path.
 */
static int read_gitfile(git_buf *path_out, const char *file_path)
{
	int     error = 0;
	git_buf file = GIT_BUF_INIT;
	size_t  prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);

	assert(path_out && file_path);

	if (git_futils_readbuffer(&file, file_path) < 0)
		return -1;

	git_buf_rtrim(&file);

	if (file.size <= prefix_len ||
		memcmp(file.ptr, GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
	{
		giterr_set(GITERR_REPOSITORY, "The `.git` file at '%s' is malformed", file_path);
		error = -1;
	}
	else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
		const char *gitlink = ((const char *)file.ptr) + prefix_len;
		while (*gitlink && git__isspace(*gitlink)) gitlink++;
		error = git_path_prettify_dir(path_out, gitlink, path_out->ptr);
	}

	git_buf_free(&file);
	return error;
}
Example #10
0
File: blob.c Project: 0CV0/libgit2
static int write_file_filtered(
	git_oid *oid,
	git_odb *odb,
	const char *full_path,
	git_vector *filters)
{
	int error;
	git_buf source = GIT_BUF_INIT;
	git_buf dest = GIT_BUF_INIT;

	if ((error = git_futils_readbuffer(&source, full_path)) < 0)
		return error;

	error = git_filters_apply(&dest, &source, filters);

	/* Free the source as soon as possible. This can be big in memory,
	 * and we don't want to ODB write to choke */
	git_buf_free(&source);

	/* Write the file to disk if it was properly filtered */
	if (!error)
		error = git_odb_write(oid, odb, dest.ptr, dest.size, GIT_OBJ_BLOB);

	git_buf_free(&dest);
	return error;
}
Example #11
0
void test_config_write__preserves_whitespace_and_comments(void)
{
	const char *file_name  = "config-duplicate-header";
	const char *n;
	git_config *cfg;
	git_buf newfile = GIT_BUF_INIT;

	/* This config can occur after removing and re-adding the origin remote */
	const char *file_content = SECTION_FOO_WITH_COMMENT SECTION_BAR;

	/* Write the test config and make sure the expected entry exists */
	cl_git_mkfile(file_name, file_content);
	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
	cl_git_pass(git_config_set_string(cfg, "section.foo.other", "otherval"));
	cl_git_pass(git_config_set_string(cfg, "newsection.newname", "new_value"));

	/* Ensure that we didn't needlessly mangle the config file */
	cl_git_pass(git_futils_readbuffer(&newfile, file_name));
	n = newfile.ptr;

	cl_assert_equal_strn(SECTION_FOO, n, strlen(SECTION_FOO));
	n += strlen(SECTION_FOO);
	cl_assert_equal_strn("\tother = otherval\n", n, strlen("\tother = otherval\n"));
	n += strlen("\tother = otherval\n");
	cl_assert_equal_strn(FOO_COMMENT, n, strlen(FOO_COMMENT));
	n += strlen(FOO_COMMENT);

	cl_assert_equal_strn(SECTION_BAR, n, strlen(SECTION_BAR));
	n += strlen(SECTION_BAR);

	cl_assert_equal_s("[newsection]\n\tnewname = new_value\n", n);

	git_buf_free(&newfile);
	git_config_free(cfg);
}
Example #12
0
void test_object_blob_fromchunks__doesnot_overwrite_an_already_existing_object(void)
{
	git_buf path = GIT_BUF_INIT;
	git_buf content = GIT_BUF_INIT;
	git_oid expected_oid, oid;
	int howmany = 7;

	cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));

	cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));

	/* Let's replace the content of the blob file storage with something else... */
	cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/32/1cbdf08803c744082332332838df6bd160f8f9"));
	cl_git_pass(p_unlink(git_buf_cstr(&path)));
	cl_git_mkfile(git_buf_cstr(&path), "boom");

	/* ...request a creation of the same blob... */
	howmany = 7;
	cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));

	/* ...and ensure the content of the faked blob file hasn't been altered */
	cl_git_pass(git_futils_readbuffer(&content, git_buf_cstr(&path)));
	cl_assert(!git__strcmp("boom", git_buf_cstr(&content)));

	git_buf_free(&path);
	git_buf_free(&content);
}
Example #13
0
File: init.c Project: Arhzi/libgit2
void test_repo_init__relative_gitdir(void)
{
	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	git_buf dot_git_content = GIT_BUF_INIT;

	opts.workdir_path = "../c_wd";
	opts.flags =
		GIT_REPOSITORY_INIT_MKPATH |
		GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;

	/* make the directory first, then it should succeed */
	cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts));

	cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/"));
	cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/"));
	cl_assert(!git_repository_is_bare(_repo));
	cl_assert(git_repository_is_empty(_repo));

	/* Verify that the gitlink and worktree entries are relative */

	/* Verify worktree */
	assert_config_entry_value(_repo, "core.worktree", "../c_wd/");

	/* Verify gitlink */
	cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
	cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);

	git_buf_free(&dot_git_content);
	cleanup_repository("root");
}
Example #14
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;

	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);

	if(fetchspec != NULL) {
		git_remote_clear_refspecs(remote);
		git_remote_add_fetch(remote, fetchspec);
	}

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote));
	cl_git_pass(git_remote_update_tips(remote, NULL, NULL));
	git_remote_disconnect(remote);
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_free(&fetchhead_buf);

	cl_assert(equals);
}
Example #15
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);
}
Example #16
0
int git_reference__read_head(
	git_reference **out,
	git_repository *repo,
	const char *path)
{
	git_buf reference = GIT_BUF_INIT;
	char *name = NULL;
	int error;

	if ((error = git_futils_readbuffer(&reference, path)) < 0)
		goto out;
	git_buf_rtrim(&reference);

	if (git__strncmp(reference.ptr, GIT_SYMREF, strlen(GIT_SYMREF)) == 0) {
		git_buf_consume(&reference, reference.ptr + strlen(GIT_SYMREF));

		name = git_path_basename(path);

		if ((*out = git_reference__alloc_symbolic(name, reference.ptr)) == NULL) {
			error = -1;
			goto out;
		}
	} else {
		if ((error = git_reference_lookup(out, repo, reference.ptr)) < 0)
			goto out;
	}

out:
	git__free(name);
	git_buf_free(&reference);

	return error;
}
Example #17
0
void test_merge_workdir_simple__union(void)
{
	git_buf conflicting_buf = GIT_BUF_INIT;

	struct merge_index_entry merge_index_entries[] = {
		ADDED_IN_MASTER_INDEX_ENTRY,
		AUTOMERGEABLE_INDEX_ENTRY,
		CHANGED_IN_BRANCH_INDEX_ENTRY,
		CHANGED_IN_MASTER_INDEX_ENTRY,

		{ 0100644, "72cdb057b340205164478565e91eb71647e66891", 0, "conflicting.txt" },

		UNCHANGED_INDEX_ENTRY,
	};

	struct merge_reuc_entry merge_reuc_entries[] = {
		AUTOMERGEABLE_REUC_ENTRY,
		CONFLICTING_REUC_ENTRY,
		REMOVED_IN_BRANCH_REUC_ENTRY,
		REMOVED_IN_MASTER_REUC_ENTRY
	};

	set_core_autocrlf_to(repo, false);

	merge_simple_branch(GIT_MERGE_FILE_FAVOR_UNION, 0);

	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
		TEST_REPO_PATH "/conflicting.txt"));
	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_UNION_FILE) == 0);
	git_buf_free(&conflicting_buf);

	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4));
}
Example #18
0
void test_merge_workdir_simple__diff3(void)
{
	git_buf conflicting_buf = GIT_BUF_INIT;

	struct merge_index_entry merge_index_entries[] = {
		ADDED_IN_MASTER_INDEX_ENTRY,
		AUTOMERGEABLE_INDEX_ENTRY,
		CHANGED_IN_BRANCH_INDEX_ENTRY,
		CHANGED_IN_MASTER_INDEX_ENTRY,

		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },

		UNCHANGED_INDEX_ENTRY,
	};

	struct merge_reuc_entry merge_reuc_entries[] = {
		AUTOMERGEABLE_REUC_ENTRY,
		REMOVED_IN_BRANCH_REUC_ENTRY,
		REMOVED_IN_MASTER_REUC_ENTRY
	};

	merge_simple_branch(0, GIT_CHECKOUT_CONFLICT_STYLE_DIFF3);

	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
		TEST_REPO_PATH "/conflicting.txt"));
	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0);
	git_buf_free(&conflicting_buf);

	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
}
Example #19
0
static int rebase_copy_notes(
	git_rebase *rebase,
	const git_signature *committer,
	const git_rebase_options *opts)
{
	git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT;
	char *pair_list, *fromstr, *tostr, *end;
	git_oid from, to;
	unsigned int linenum = 1;
	int error = 0;

	if (!opts->rewrite_notes_ref)
		goto done;

	if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
		(error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
		goto done;

	pair_list = rewritten.ptr;

	while (*pair_list) {
		fromstr = pair_list;

		if ((end = strchr(fromstr, '\n')) == NULL)
			goto on_error;

		pair_list = end+1;
		*end = '\0';

		if ((end = strchr(fromstr, ' ')) == NULL)
			goto on_error;

		tostr = end+1;
		*end = '\0';

		if (strlen(fromstr) != GIT_OID_HEXSZ ||
			strlen(tostr) != GIT_OID_HEXSZ ||
			git_oid_fromstr(&from, fromstr) < 0 ||
			git_oid_fromstr(&to, tostr) < 0)
			goto on_error;

		if ((error = rebase_copy_note(rebase, &from, &to, committer, opts)) < 0)
			goto done;

		linenum++;
	}

	goto done;

on_error:
	giterr_set(GITERR_REBASE, "Invalid rewritten file at line %d", linenum);
	error = -1;

done:
	git_buf_free(&rewritten);
	git_buf_free(&path);

	return error;
}
Example #20
0
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");
}
Example #21
0
void test_merge_workdir_simple__mergefile(void)
{
	git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;

	struct merge_index_entry merge_index_entries[] = {
		ADDED_IN_MASTER_INDEX_ENTRY,
		AUTOMERGEABLE_INDEX_ENTRY,
		CHANGED_IN_BRANCH_INDEX_ENTRY,
		CHANGED_IN_MASTER_INDEX_ENTRY,

		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },

		UNCHANGED_INDEX_ENTRY,
	};

	struct merge_reuc_entry merge_reuc_entries[] = {
		AUTOMERGEABLE_REUC_ENTRY,
		REMOVED_IN_BRANCH_REUC_ENTRY,
		REMOVED_IN_MASTER_REUC_ENTRY
	};

	set_core_autocrlf_to(repo, false);

	merge_simple_branch(0, 0);

	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
		TEST_REPO_PATH "/conflicting.txt"));
	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0);
	cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
		TEST_REPO_PATH "/.git/MERGE_MSG"));
	cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
		"Merge commit '7cb63eed597130ba4abb87b3e544b85021905520'\n" \
		"\n" \
		"Conflicts:\n" \
		"\tconflicting.txt\n") == 0);
	git_buf_dispose(&conflicting_buf);
	git_buf_dispose(&mergemsg_buf);

	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
}
Example #22
0
int git_repository_fetchhead_foreach(git_repository *repo,
	git_repository_fetchhead_foreach_cb cb,
	void *payload)
{
	git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT, name = GIT_BUF_INIT;
	const char *ref_name;
	git_oid oid;
	const char *remote_url;
	unsigned int is_merge = 0;
	char *buffer, *line;
	size_t line_num = 0;
	int error = 0;

	assert(repo && cb);

	if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
		return -1;

	if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0)
		goto done;

	buffer = file.ptr;

	while ((line = git__strsep(&buffer, "\n")) != NULL) {
		++line_num;

		if ((error = fetchhead_ref_parse(
				&oid, &is_merge, &name, &remote_url, line, line_num)) < 0)
			goto done;

		if (git_buf_len(&name) > 0)
			ref_name = git_buf_cstr(&name);
		else
			ref_name = NULL;

		error = cb(ref_name, remote_url, &oid, is_merge, payload);
		if (error) {
			giterr_set_after_callback(error);
			goto done;
		}
	}

	if (*buffer) {
		giterr_set(GITERR_FETCHHEAD, "No EOL at line %"PRIuZ, line_num+1);
		error = -1;
		goto done;
	}

done:
	git_buf_free(&file);
	git_buf_free(&path);
	git_buf_free(&name);

	return error;
}
Example #23
0
void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_returns_error(void)
{
	git_reflog *reflog;
	const git_error *error;
	const char *refname = "refs/heads/newline";
	const char *refmessage =
		"Reflog*message with a newline and enough content after it to pass the GIT_REFLOG_SIZE_MIN check inside reflog_parse.";
	git_reference *ref;
	git_oid id;
	git_buf logpath = GIT_BUF_INIT, logcontents = GIT_BUF_INIT;
	char *star;

	git_oid_fromstr(&id, current_master_tip);

	/* create a new branch */
	cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, refmessage));

	/* corrupt the branch reflog by introducing a newline inside the reflog message (we replace '*' with '\n') */
	git_buf_join_n(&logpath, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname);
	cl_git_pass(git_futils_readbuffer(&logcontents, git_buf_cstr(&logpath)));
	cl_assert((star = strchr(git_buf_cstr(&logcontents), '*')) != NULL);
	*star = '\n';
	cl_git_rewritefile(git_buf_cstr(&logpath), git_buf_cstr(&logcontents));

	/* confirm that the file was rewritten successfully and now contains a '\n' in the expected location */
	cl_git_pass(git_futils_readbuffer(&logcontents, git_buf_cstr(&logpath)));
	cl_assert(strstr(git_buf_cstr(&logcontents), "Reflog\nmessage") != NULL);

	/* clear the error state so we can capture the error generated by git_reflog_read */
	giterr_clear();

	cl_git_fail(git_reflog_read(&reflog, g_repo, refname));

	error = giterr_last();

	cl_assert(error != NULL);
	cl_assert_equal_s("unable to parse OID - contains invalid characters", error->message);

	git_reference_free(ref);
	git_buf_dispose(&logpath);
	git_buf_dispose(&logcontents);
}
Example #24
0
void test_repo_init__extended_with_template(void)
{
	git_buf expected = GIT_BUF_INIT;
	git_buf actual = GIT_BUF_INIT;
	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	int filemode;

	cl_set_cleanup(&cleanup_repository, "templated.git");
	template_sandbox("template");

	opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE |
		GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
	opts.template_path = "template";

	cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts));

	cl_assert(git_repository_is_bare(_repo));

	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/templated.git/"));

	cl_git_pass(git_futils_readbuffer(&expected, "template/description"));
	cl_git_pass(git_futils_readbuffer(
		&actual, "templated.git/description"));

	cl_assert_equal_s(expected.ptr, actual.ptr);

	git_buf_free(&expected);
	git_buf_free(&actual);

	filemode = cl_repo_get_bool(_repo, "core.filemode");

	assert_hooks_match(
		"template", git_repository_path(_repo),
		"hooks/update.sample", filemode);

	assert_hooks_match(
		"template", git_repository_path(_repo),
		"hooks/link.sample", filemode);

	cl_fixture_cleanup("template");
}
Example #25
0
static void files_are_equal(const char *a, const char *b)
{
	git_buf buf_a = GIT_BUF_INIT;
	git_buf buf_b = GIT_BUF_INIT;
	int pass;

	if (git_futils_readbuffer(&buf_a, a) < 0)
		cl_assert(0);

	if (git_futils_readbuffer(&buf_b, b) < 0) {
		git_buf_free(&buf_a);
		cl_assert(0);
	}

	pass = (buf_a.size == buf_b.size && !memcmp(buf_a.ptr, buf_b.ptr, buf_a.size));

	git_buf_free(&buf_a);
	git_buf_free(&buf_b);

	cl_assert(pass);
}
Example #26
0
static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth)
{
	git_buf alternates_path = GIT_BUF_INIT;
	git_buf alternates_buf = GIT_BUF_INIT;
	char *buffer;
	const char *alternate;
	int result = 0;

	/* Git reports an error, we just ignore anything deeper */
	if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH)
		return 0;

	if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0)
		return -1;

	if (git_path_exists(alternates_path.ptr) == false) {
		git_buf_free(&alternates_path);
		return 0;
	}

	if (git_futils_readbuffer(&alternates_buf, alternates_path.ptr) < 0) {
		git_buf_free(&alternates_path);
		return -1;
	}

	buffer = (char *)alternates_buf.ptr;

	/* add each alternate as a new backend; one alternate per line */
	while ((alternate = git__strtok(&buffer, "\r\n")) != NULL) {
		if (*alternate == '\0' || *alternate == '#')
			continue;

		/*
		 * Relative path: build based on the current `objects`
		 * folder. However, relative paths are only allowed in
		 * the current repository.
		 */
		if (*alternate == '.' && !alternate_depth) {
			if ((result = git_buf_joinpath(&alternates_path, objects_dir, alternate)) < 0)
				break;
			alternate = git_buf_cstr(&alternates_path);
		}

		if ((result = add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
			break;
	}

	git_buf_free(&alternates_path);
	git_buf_free(&alternates_buf);

	return result;
}
Example #27
0
static void ensure_workdir_contents(const char *path, const char *contents)
{
	git_buf fullpath = GIT_BUF_INIT, data_buf = GIT_BUF_INIT;

	cl_git_pass(
		git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));

	cl_git_pass(git_futils_readbuffer(&data_buf, git_buf_cstr(&fullpath)));
	cl_assert(strcmp(git_buf_cstr(&data_buf), contents) == 0);

	git_buf_free(&fullpath);
	git_buf_free(&data_buf);
}
Example #28
0
void test_checkout_tree__caches_attributes_during_checkout(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_oid oid;
	git_object *obj = NULL;
	git_buf ident1 = GIT_BUF_INIT, ident2 = GIT_BUF_INIT;
	char *ident_paths[] = { "ident1.txt", "ident2.txt" };

	opts.progress_cb = update_attr_callback;

	assert_on_branch(g_repo, "master");
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
	opts.paths.strings = ident_paths;
	opts.paths.count = 2;

	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/ident"));
	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));

	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));

	cl_git_pass(git_futils_readbuffer(&ident1, "testrepo/ident1.txt"));
	cl_git_pass(git_futils_readbuffer(&ident2, "testrepo/ident2.txt"));

	cl_assert_equal_strn(ident1.ptr, "# $Id$", 6);
	cl_assert_equal_strn(ident2.ptr, "# $Id$", 6);

	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));

	cl_git_pass(git_futils_readbuffer(&ident1, "testrepo/ident1.txt"));
	cl_git_pass(git_futils_readbuffer(&ident2, "testrepo/ident2.txt"));

	cl_assert_equal_strn(ident1.ptr, "# $Id: ", 7);
	cl_assert_equal_strn(ident2.ptr, "# $Id: ", 7);

	git_buf_free(&ident1);
	git_buf_free(&ident2);
	git_object_free(obj);
}
Example #29
0
File: init.c Project: Arhzi/libgit2
static void validate_templates(git_repository *repo, const char *template_path)
{
	git_buf template_description = GIT_BUF_INIT;
	git_buf repo_description = GIT_BUF_INIT;
	git_buf expected = GIT_BUF_INIT;
	git_buf actual = GIT_BUF_INIT;
	int filemode;

	cl_git_pass(git_buf_joinpath(&template_description, template_path,
		"description"));
	cl_git_pass(git_buf_joinpath(&repo_description, git_repository_path(repo),
		"description"));

	cl_git_pass(git_futils_readbuffer(&expected, template_description.ptr));
	cl_git_pass(git_futils_readbuffer(&actual, repo_description.ptr));

	cl_assert_equal_s(expected.ptr, actual.ptr);

	filemode = cl_repo_get_bool(repo, "core.filemode");

	assert_hooks_match(
		template_path, git_repository_path(repo),
		"hooks/update.sample", filemode);

	assert_hooks_match(
		template_path, git_repository_path(repo),
		"hooks/link.sample", filemode);

	assert_hooks_match(
		template_path, git_repository_path(repo),
		"hooks/.dotfile", filemode);

	git_buf_free(&expected);
	git_buf_free(&actual);
	git_buf_free(&repo_description);
	git_buf_free(&template_description);
}
Example #30
0
void test_config_write__to_file_with_only_comment(void)
{
	git_config *cfg;
	const char *filename = "config-file";
	git_buf result = GIT_BUF_INIT;

	cl_git_mkfile(filename, "\n\n");
	cl_git_pass(git_config_open_ondisk(&cfg, filename));
	cl_git_pass(git_config_set_string(cfg, "section.name", "value"));
	git_config_free(cfg);

	cl_git_pass(git_futils_readbuffer(&result, "config-file"));
	cl_assert_equal_s("\n\n[section]\n\tname = value\n", result.ptr);

	git_buf_free(&result);
}