Esempio n. 1
0
void test_diff_drivers__long_lines(void)
{
	const char *base = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non nisi ligula. Ut viverra enim sed lobortis suscipit.\nPhasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissim risus. Suspendisse at nisi quis turpis fringilla rutrum id sit amet nulla.\nNam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\nMauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\nAliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n";
	git_index *idx;
	git_diff_list *diff;
	git_diff_patch *patch;
	char *actual;
	const char *expected = "diff --git a/longlines.txt b/longlines.txt\nindex c1ce6ef..0134431 100644\n--- a/longlines.txt\n+++ b/longlines.txt\n@@ -3,3 +3,5 @@ Phasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissi\n Nam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\n Mauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\n Aliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n+newline\n+newline\n";

	g_repo = cl_git_sandbox_init("empty_standard_repo");

	cl_git_mkfile("empty_standard_repo/longlines.txt", base);
	cl_git_pass(git_repository_index(&idx, g_repo));
	cl_git_pass(git_index_add_bypath(idx, "longlines.txt"));
	cl_git_pass(git_index_write(idx));
	git_index_free(idx);

	cl_git_append2file("empty_standard_repo/longlines.txt", "newline\nnewline\n");

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
	cl_assert_equal_sz(1, git_diff_num_deltas(diff));
	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&actual, patch));

	cl_assert_equal_s(expected, actual);

	free(actual);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);
}
Esempio n. 2
0
void test_diff_index__1(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
	const char *b_commit = "0017bd4ab1ec3"; /* the start */
	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;

	cl_assert(a);
	cl_assert(b);

	opts.context_lines = 1;
	opts.interhunk_lines = 1;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff));

	cl_assert_equal_i(
		GIT_EUSER,
		git_diff_foreach(diff, &exp, diff_stop_after_2_files, NULL, NULL)
	);

	cl_assert_equal_i(2, exp.files);

	git_diff_list_free(diff);
	diff = NULL;

	git_tree_free(a);
	git_tree_free(b);
}
Esempio n. 3
0
void test_diff_tree__larger_hunks(void)
{
	const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
	const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
	git_tree *a, *b;
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	size_t d, num_d, h, num_h, l, num_l, header_len, line_len;
	const git_diff_delta *delta;
	git_diff_patch *patch;
	const git_diff_range *range;
	const char *header, *line;
	char origin;

	g_repo = cl_git_sandbox_init("diff");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);

	opts.context_lines = 1;
	opts.interhunk_lines = 0;

	cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff));

	num_d = git_diff_num_deltas(diff);
	for (d = 0; d < num_d; ++d) {
		cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d));
		cl_assert(patch && delta);

		num_h = git_diff_patch_num_hunks(patch);
		for (h = 0; h < num_h; h++) {
			cl_git_pass(git_diff_patch_get_hunk(
				&range, &header, &header_len, &num_l, patch, h));

			for (l = 0; l < num_l; ++l) {
				cl_git_pass(git_diff_patch_get_line_in_hunk(
					&origin, &line, &line_len, NULL, NULL, patch, h, l));
				cl_assert(line);
			}

			cl_git_fail(git_diff_patch_get_line_in_hunk(
				&origin, &line, &line_len, NULL, NULL, patch, h, num_l));
		}

		cl_git_fail(git_diff_patch_get_hunk(
			&range, &header, &header_len, &num_l, patch, num_h));

		git_diff_patch_free(patch);
	}

	cl_git_fail(git_diff_get_patch(&patch, &delta, diff, num_d));

	cl_assert_equal_i(2, (int)num_d);

	git_diff_list_free(diff);
	diff = NULL;

	git_tree_free(a);
	git_tree_free(b);
}
void test_diff_workdir__submodules(void)
{
	const char *a_commit = "873585b94bdeabccea991ea5e3ec1a277895b698";
	git_tree *a;
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;

	g_repo = cl_git_sandbox_init("submod2");

	cl_fixture_sandbox("submod2_target");
	p_rename("submod2_target/.gitted", "submod2_target/.git");

	rewrite_gitmodules(git_repository_workdir(g_repo));
	p_rename("submod2/not_submodule/.gitted", "submod2/not_submodule/.git");

	cl_fixture_cleanup("submod2_target");

	a = resolve_commit_oid_to_tree(g_repo, a_commit);

	opts.flags =
		GIT_DIFF_INCLUDE_UNTRACKED |
		GIT_DIFF_RECURSE_UNTRACKED_DIRS |
		GIT_DIFF_INCLUDE_UNTRACKED_CONTENT;

	cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff));

	/* diff_print(stderr, diff); */

	/* essentially doing: git diff 873585b94bdeabccea991ea5e3ec1a277895b698 */

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	/* the following differs from "git diff 873585" by one "untracked" file
	 * because the diff list includes the "not_submodule/" directory which
	 * is not displayed in the text diff.
	 */

	cl_assert_equal_i(10, exp.files);

	cl_assert_equal_i(0, exp.file_adds);
	cl_assert_equal_i(0, exp.file_dels);
	cl_assert_equal_i(1, exp.file_mods);
	cl_assert_equal_i(0, exp.file_ignored);
	cl_assert_equal_i(9, exp.file_untracked);

	/* the following numbers match "git diff 873585" exactly */

	cl_assert_equal_i(9, exp.hunks);

	cl_assert_equal_i(33, exp.lines);
	cl_assert_equal_i(2, exp.line_ctxt);
	cl_assert_equal_i(30, exp.line_adds);
	cl_assert_equal_i(1, exp.line_dels);

	git_diff_list_free(diff);
	git_tree_free(a);
}
Esempio n. 5
0
void test_diff_submodules__dirty_submodule(void)
{
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff_list *diff = NULL;
	static const char *expected[] = {
		"<SKIP>", /* .gitmodules */
		NULL, /* added */
		NULL, /* ignored */
		"diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
		"diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */
		NULL, /* unmodified */
		NULL, /* untracked */
		"<END>"
	};

	setup_submodules();

	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
	cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");

	opts.flags = GIT_DIFF_INCLUDE_IGNORED |
		GIT_DIFF_INCLUDE_UNTRACKED |
		GIT_DIFF_INCLUDE_UNMODIFIED;

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
	check_diff_patches(diff, expected);
	git_diff_list_free(diff);
}
Esempio n. 6
0
void test_diff_submodules__unmodified_submodule(void)
{
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff_list *diff = NULL;
	static const char *expected[] = {
		"<SKIP>", /* .gitmodules */
		NULL, /* added */
		NULL, /* ignored */
		"diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
		NULL, /* testrepo.git */
		NULL, /* unmodified */
		NULL, /* untracked */
		"<END>"
	};

	setup_submodules();

	opts.flags = GIT_DIFF_INCLUDE_IGNORED |
		GIT_DIFF_INCLUDE_UNTRACKED |
		GIT_DIFF_INCLUDE_UNMODIFIED;

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
	check_diff_patches(diff, expected);
	git_diff_list_free(diff);
}
Esempio n. 7
0
void test_diff_diffiter__iterate_and_generate_patch_text(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_list *diff;
	size_t d, num_d;

	cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));

	num_d = git_diff_num_deltas(diff);
	cl_assert_equal_i(8, (int)num_d);

	for (d = 0; d < num_d; ++d) {
		git_diff_patch *patch;
		char *text;

		cl_git_pass(git_diff_get_patch(&patch, NULL, diff, d));
		cl_assert(patch != NULL);

		cl_git_pass(git_diff_patch_to_str(&text, patch));

		cl_assert_equal_s(expected_patch_text[d], text);

		git__free(text);
		git_diff_patch_free(patch);
	}

	git_diff_list_free(diff);
}
Esempio n. 8
0
static void
Diff_dealloc(Diff *self)
{
    git_diff_list_free(self->list);
    Py_CLEAR(self->repo);
    PyObject_Del(self);
}
Esempio n. 9
0
void test_diff_tree__merge(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "605812a";
	const char *b_commit = "370fe9ec22";
	const char *c_commit = "f5b0af1fb4f5c";
	git_tree *a, *b, *c;
	git_diff_list *diff1 = NULL, *diff2 = NULL;
	diff_expects exp;

	g_repo = cl_git_sandbox_init("attr");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);

	cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, a, b, &diff1));

	cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, c, b, &diff2));

	git_tree_free(a);
	git_tree_free(b);
	git_tree_free(c);

	cl_git_pass(git_diff_merge(diff1, diff2));

	git_diff_list_free(diff2);

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_foreach(
		diff1, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert_equal_i(6, exp.files);
	cl_assert_equal_i(2, exp.file_adds);
	cl_assert_equal_i(1, exp.file_dels);
	cl_assert_equal_i(3, exp.file_mods);

	cl_assert_equal_i(6, exp.hunks);

	cl_assert_equal_i(59, exp.lines);
	cl_assert_equal_i(1, exp.line_ctxt);
	cl_assert_equal_i(36, exp.line_adds);
	cl_assert_equal_i(22, exp.line_dels);

	git_diff_list_free(diff1);
}
void test_diff_workdir__filemode_changes_with_filemode_false(void)
{
	git_config *cfg;
	git_diff_list *diff = NULL;
	diff_expects exp;

	if (!cl_is_chmod_supported())
		return;

	g_repo = cl_git_sandbox_init("issue_592");

	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "core.filemode", false));

	/* test once with no mods */

	cl_git_pass(git_diff_workdir_to_index(g_repo, NULL, &diff));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert_equal_i(0, exp.files);
	cl_assert_equal_i(0, exp.file_mods);
	cl_assert_equal_i(0, exp.hunks);

	git_diff_list_free(diff);

	/* chmod file and test again */

	cl_assert(cl_toggle_filemode("issue_592/a.txt"));

	cl_git_pass(git_diff_workdir_to_index(g_repo, NULL, &diff));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert_equal_i(0, exp.files);
	cl_assert_equal_i(0, exp.file_mods);
	cl_assert_equal_i(0, exp.hunks);

	git_diff_list_free(diff);

	cl_assert(cl_toggle_filemode("issue_592/a.txt"));
	git_config_free(cfg);
}
Esempio n. 11
0
static void
Diff_dealloc(Diff *self)
{
    git_diff_list_free(self->diff);
    Py_XDECREF(self->repo);
    Py_XDECREF(self->diff_changes);
    PyObject_Del(self);
}
Esempio n. 12
0
File: stash.c Progetto: aep/libgit2
static int build_workdir_tree(
	git_tree **tree_out,
	git_index *index,
	git_commit *b_commit)
{
	git_repository *repo = git_index_owner(index);
	git_tree *b_tree = NULL;
	git_diff_list *diff = NULL, *diff2 = NULL;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	struct cb_data data = {0};
	int error;

	if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
		goto cleanup;

	if ((error = git_diff_tree_to_index(&diff, repo, b_tree, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_index_to_workdir(&diff2, repo, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_merge(diff, diff2)) < 0)
		goto cleanup;

	data.index = index;
	data.include_changed = true;

	if ((error = git_diff_foreach(
			diff, update_index_cb, NULL, NULL, &data)) < 0)
	{
		if (error == GIT_EUSER)
			error = data.error;
		goto cleanup;
	}


	if ((error = build_tree_from_index(tree_out, index)) < 0)
		goto cleanup;

cleanup:
	git_diff_list_free(diff);
	git_diff_list_free(diff2);
	git_tree_free(b_tree);

	return error;
}
Esempio n. 13
0
void test_diff_diffiter__iterate_all(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp = {0};
	size_t d, num_d;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));

	num_d = git_diff_num_deltas(diff);
	for (d = 0; d < num_d; ++d) {
		git_diff_patch *patch;
		const git_diff_delta *delta;
		size_t h, num_h;

		cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d));
		cl_assert(patch && delta);
		exp.files++;

		num_h = git_diff_patch_num_hunks(patch);
		for (h = 0; h < num_h; h++) {
			const git_diff_range *range;
			const char *header;
			size_t header_len, l, num_l;

			cl_git_pass(git_diff_patch_get_hunk(
				&range, &header, &header_len, &num_l, patch, h));
			cl_assert(range && header);
			exp.hunks++;

			for (l = 0; l < num_l; ++l) {
				char origin;
				const char *content;
				size_t content_len;

				cl_git_pass(git_diff_patch_get_line_in_hunk(
					&origin, &content, &content_len, NULL, NULL, patch, h, l));
				cl_assert(content);
				exp.lines++;
			}
		}

		git_diff_patch_free(patch);
	}

	cl_assert_equal_i(13, exp.files);
	cl_assert_equal_i(8, exp.hunks);
	cl_assert_equal_i(14, exp.lines);

	git_diff_list_free(diff);
}
Esempio n. 14
0
void test_diff_diffiter__iterate_files_and_hunks(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	size_t d, num_d;
	int file_count = 0, hunk_count = 0;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));

	num_d = git_diff_num_deltas(diff);

	for (d = 0; d < num_d; ++d) {
		git_diff_patch *patch;
		const git_diff_delta *delta;
		size_t h, num_h;

		cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d));

		cl_assert(delta);
		cl_assert(patch);

		file_count++;

		num_h = git_diff_patch_num_hunks(patch);

		for (h = 0; h < num_h; h++) {
			const git_diff_range *range;
			const char *header;
			size_t header_len, num_l;

			cl_git_pass(git_diff_patch_get_hunk(
				&range, &header, &header_len, &num_l, patch, h));

			cl_assert(range);
			cl_assert(header);

			hunk_count++;
		}

		git_diff_patch_free(patch);
	}

	cl_assert_equal_i(13, file_count);
	cl_assert_equal_i(8, hunk_count);

	git_diff_list_free(diff);
}
Esempio n. 15
0
File: stash.c Progetto: aep/libgit2
static int build_untracked_tree(
	git_tree **tree_out,
	git_index *index,
	git_commit *i_commit,
	uint32_t flags)
{
	git_tree *i_tree = NULL;
	git_diff_list *diff = NULL;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	struct cb_data data = {0};
	int error;

	git_index_clear(index);

	data.index = index;

	if (flags & GIT_STASH_INCLUDE_UNTRACKED) {
		opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
			GIT_DIFF_RECURSE_UNTRACKED_DIRS;
		data.include_untracked = true;
	}

	if (flags & GIT_STASH_INCLUDE_IGNORED) {
		opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
		data.include_ignored = true;
	}

	if ((error = git_commit_tree(&i_tree, i_commit)) < 0)
		goto cleanup;

	if ((error = git_diff_tree_to_workdir(
			&diff, git_index_owner(index), i_tree, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_foreach(
			diff, update_index_cb, NULL, NULL, &data)) < 0)
	{
		if (error == GIT_EUSER)
			error = data.error;
		goto cleanup;
	}

	error = build_tree_from_index(tree_out, index);

cleanup:
	git_diff_list_free(diff);
	git_tree_free(i_tree);
	return error;
}
void test_diff_workdir__to_index(void)
{
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;
	int use_iterator;

	g_repo = cl_git_sandbox_init("status");

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));

	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
		memset(&exp, 0, sizeof(exp));

		if (use_iterator)
			cl_git_pass(diff_foreach_via_iterator(
				diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
		else
			cl_git_pass(git_diff_foreach(
				diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

		/* to generate these values:
		 * - cd to tests/resources/status,
		 * - mv .gitted .git
		 * - git diff --name-status
		 * - git diff
		 * - mv .git .gitted
		 */
		cl_assert_equal_i(13, exp.files);
		cl_assert_equal_i(0, exp.file_adds);
		cl_assert_equal_i(4, exp.file_dels);
		cl_assert_equal_i(4, exp.file_mods);
		cl_assert_equal_i(1, exp.file_ignored);
		cl_assert_equal_i(4, exp.file_untracked);

		cl_assert_equal_i(8, exp.hunks);

		cl_assert_equal_i(14, exp.lines);
		cl_assert_equal_i(5, exp.line_ctxt);
		cl_assert_equal_i(4, exp.line_adds);
		cl_assert_equal_i(5, exp.line_dels);
	}

	git_diff_list_free(diff);
}
Esempio n. 17
0
void test_diff_diffiter__create(void)
{
	git_repository *repo = cl_git_sandbox_init("attr");
	git_diff_list *diff;
	size_t d, num_d;

	cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));

	num_d = git_diff_num_deltas(diff);
	for (d = 0; d < num_d; ++d) {
		const git_diff_delta *delta;
		cl_git_pass(git_diff_get_patch(NULL, &delta, diff, d));
	}

	git_diff_list_free(diff);
}
Esempio n. 18
0
void test_diff_tree__bare(void)
{
	const char *a_commit = "8496071c1b46c85";
	const char *b_commit = "be3563ae3f79";
	git_tree *a, *b;
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;

	g_repo = cl_git_sandbox_init("testrepo.git");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);

	opts.context_lines = 1;
	opts.interhunk_lines = 1;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 3);
	cl_assert(exp.file_adds == 2);
	cl_assert(exp.file_dels == 0);
	cl_assert(exp.file_mods == 1);

	cl_assert(exp.hunks == 3);

	cl_assert(exp.lines == 4);
	cl_assert(exp.line_ctxt == 0);
	cl_assert(exp.line_adds == 3);
	cl_assert(exp.line_dels == 1);

	git_diff_list_free(diff);
	git_tree_free(a);
	git_tree_free(b);
}
Esempio n. 19
0
void test_diff_diffiter__iterate_files_2(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_list *diff;
	size_t d, num_d;
	int count = 0;

	cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));

	num_d = git_diff_num_deltas(diff);
	cl_assert_equal_i(8, (int)num_d);

	for (d = 0; d < num_d; ++d) {
		const git_diff_delta *delta;
		cl_git_pass(git_diff_get_patch(NULL, &delta, diff, d));
		cl_assert(delta != NULL);
		count++;
	}
	cl_assert_equal_i(8, count);

	git_diff_list_free(diff);
}
Esempio n. 20
0
void test_diff_submodules__submod2_head_to_index(void)
{
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_tree *head;
	git_diff_list *diff = NULL;
	static const char *expected[] = {
		"<SKIP>", /* .gitmodules */
		"diff --git a/sm_added_and_uncommited b/sm_added_and_uncommited\nnew file mode 160000\nindex 0000000..4800958\n--- /dev/null\n+++ b/sm_added_and_uncommited\n@@ -0,0 +1 @@\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n", /* sm_added_and_uncommited */
		"<END>"
	};

	setup_submodules2();

	cl_git_pass(git_repository_head_tree(&head, g_repo));

	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, head, NULL, &opts));
	check_diff_patches(diff, expected);
	git_diff_list_free(diff);

	git_tree_free(head);
}
Esempio n. 21
0
void test_diff_submodules__submod2_index_to_wd(void)
{
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff_list *diff = NULL;
	static const char *expected[] = {
		"<SKIP>", /* .gitmodules */
		NULL, /* not-submodule */
		NULL, /* not */
		"diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */
		"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
		"diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */
		"diff --git a/sm_changed_untracked_file b/sm_changed_untracked_file\nindex 4800958..4800958 160000\n--- a/sm_changed_untracked_file\n+++ b/sm_changed_untracked_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_untracked_file */
		"diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
		"<END>"
	};

	setup_submodules2();

	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
	check_diff_patches(diff, expected);
	git_diff_list_free(diff);
}
Esempio n. 22
0
void test_diff_drivers__patterns(void)
{
	git_config *cfg;
	const char *one_sha = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
	git_tree *one;
	git_diff_list *diff;
	git_diff_patch *patch;
	char *text;
	const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
	const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n";
	const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";

	g_repo = cl_git_sandbox_init("renames");

	one = resolve_commit_oid_to_tree(g_repo, one_sha);

	/* no diff */

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(0, (int)git_diff_num_deltas(diff));
	git_diff_list_free(diff);

	/* default diff */

	cl_git_append2file("renames/untimely.txt", "\r\nSome new stuff\r\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&text, patch));
	cl_assert_equal_s(expected0, text);

	git__free(text);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);

	/* attribute diff set to false */

	cl_git_rewritefile("renames/.gitattributes", "untimely.txt -diff\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&text, patch));
	cl_assert_equal_s(expected1, text);

	git__free(text);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);

	/* attribute diff set to unconfigured value (should use default) */

	cl_git_rewritefile("renames/.gitattributes", "untimely.txt diff=kipling0\n");

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&text, patch));
	cl_assert_equal_s(expected0, text);

	git__free(text);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);

	/* let's define that driver */

	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 1));
	git_config_free(cfg);

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&text, patch));
	cl_assert_equal_s(expected1, text);

	git__free(text);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);

	/* let's use a real driver with some regular expressions */

	git_diff_driver_registry_free(g_repo->diff_drivers);
	g_repo->diff_drivers = NULL;

	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
	cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H"));
	git_config_free(cfg);

	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));

	cl_git_pass(git_diff_get_patch(&patch, NULL, diff, 0));
	cl_git_pass(git_diff_patch_to_str(&text, patch));
	cl_assert_equal_s(expected2, text);

	git__free(text);
	git_diff_patch_free(patch);
	git_diff_list_free(diff);

	git_tree_free(one);
}
Esempio n. 23
0
void test_diff_workdir__to_tree(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
	const char *b_commit = "0017bd4ab1ec3"; /* the start */
	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	git_diff_list *diff2 = NULL;
	diff_expects exp;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	memset(&exp, 0, sizeof(exp));

	/* You can't really generate the equivalent of git_diff_workdir_to_tree()
	 * using C git.  It really wants to interpose the index into the diff.
	 *
	 * To validate the following results with command line git, I ran the
	 * following:
	 * - git ls-tree 26a125
	 * - find . ! -path ./.git/\* -a -type f | git hash-object --stdin-paths
	 * The results are documented at the bottom of this file in the
	 * long comment entitled "PREPARATION OF TEST DATA".
	 */
	cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 13);
	cl_assert(exp.file_adds == 0);
	cl_assert(exp.file_dels == 4);
	cl_assert(exp.file_mods == 4);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 4);

	/* Since there is no git diff equivalent, let's just assume that the
	 * text diffs produced by git_diff_foreach are accurate here.  We will
	 * do more apples-to-apples test comparison below.
	 */

	git_diff_list_free(diff);
	diff = NULL;
	memset(&exp, 0, sizeof(exp));

	/* This is a compatible emulation of "git diff <sha>" which looks like
	 * a workdir to tree diff (even though it is not really).  This is what
	 * you would get from "git diff --name-status 26a125ee1bf"
	 */
	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff));
	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2));
	cl_git_pass(git_diff_merge(diff, diff2));
	git_diff_list_free(diff2);

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 14);
	cl_assert(exp.file_adds == 2);
	cl_assert(exp.file_dels == 5);
	cl_assert(exp.file_mods == 4);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 2);

	cl_assert(exp.hunks == 11);

	cl_assert(exp.lines == 17);
	cl_assert(exp.line_ctxt == 4);
	cl_assert(exp.line_adds == 8);
	cl_assert(exp.line_dels == 5);

	git_diff_list_free(diff);
	diff = NULL;
	memset(&exp, 0, sizeof(exp));

	/* Again, emulating "git diff <sha>" for testing purposes using
	 * "git diff --name-status 0017bd4ab1ec3" instead.
	 */
	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, b, &diff));
	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2));
	cl_git_pass(git_diff_merge(diff, diff2));
	git_diff_list_free(diff2);

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 15);
	cl_assert(exp.file_adds == 5);
	cl_assert(exp.file_dels == 4);
	cl_assert(exp.file_mods == 3);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 2);

	cl_assert(exp.hunks == 12);

	cl_assert(exp.lines == 19);
	cl_assert(exp.line_ctxt == 3);
	cl_assert(exp.line_adds == 12);
	cl_assert(exp.line_dels == 4);

	git_diff_list_free(diff);

	git_tree_free(a);
	git_tree_free(b);
}
Esempio n. 24
0
void test_diff_workdir__to_index_with_pathspec(void)
{
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;
	char *pathspec = NULL;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
	opts.pathspec.strings = &pathspec;
	opts.pathspec.count   = 1;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));
	cl_git_pass(git_diff_foreach(diff, &exp, diff_file_fn, NULL, NULL));

	cl_assert_equal_i(12, exp.files);
	cl_assert_equal_i(0, exp.file_adds);
	cl_assert_equal_i(4, exp.file_dels);
	cl_assert_equal_i(4, exp.file_mods);
	cl_assert_equal_i(1, exp.file_ignored);
	cl_assert_equal_i(3, exp.file_untracked);

	git_diff_list_free(diff);

	memset(&exp, 0, sizeof(exp));
	pathspec = "modified_file";

	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));
	cl_git_pass(git_diff_foreach(diff, &exp, diff_file_fn, NULL, NULL));

	cl_assert_equal_i(1, exp.files);
	cl_assert_equal_i(0, exp.file_adds);
	cl_assert_equal_i(0, exp.file_dels);
	cl_assert_equal_i(1, exp.file_mods);
	cl_assert_equal_i(0, exp.file_ignored);
	cl_assert_equal_i(0, exp.file_untracked);

	git_diff_list_free(diff);

	memset(&exp, 0, sizeof(exp));
	pathspec = "subdir";

	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));
	cl_git_pass(git_diff_foreach(diff, &exp, diff_file_fn, NULL, NULL));

	cl_assert_equal_i(3, exp.files);
	cl_assert_equal_i(0, exp.file_adds);
	cl_assert_equal_i(1, exp.file_dels);
	cl_assert_equal_i(1, exp.file_mods);
	cl_assert_equal_i(0, exp.file_ignored);
	cl_assert_equal_i(1, exp.file_untracked);

	git_diff_list_free(diff);

	memset(&exp, 0, sizeof(exp));
	pathspec = "*_deleted";

	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));
	cl_git_pass(git_diff_foreach(diff, &exp, diff_file_fn, NULL, NULL));

	cl_assert_equal_i(2, exp.files);
	cl_assert_equal_i(0, exp.file_adds);
	cl_assert_equal_i(2, exp.file_dels);
	cl_assert_equal_i(0, exp.file_mods);
	cl_assert_equal_i(0, exp.file_ignored);
	cl_assert_equal_i(0, exp.file_untracked);

	git_diff_list_free(diff);
}
int git_checkout_index(
	git_repository *repo,
	git_checkout_opts *opts,
	git_indexer_stats *stats)
{
	git_diff_list *diff = NULL;
	git_indexer_stats dummy_stats;

	git_diff_options diff_opts = {0};
	git_checkout_opts checkout_opts;

	struct checkout_diff_data data;
	git_buf workdir = GIT_BUF_INIT;

	int error;

	assert(repo);

	if ((error = git_repository__ensure_not_bare(repo, "checkout")) < 0)
		return error;

	diff_opts.flags =
		GIT_DIFF_INCLUDE_UNTRACKED |
		GIT_DIFF_INCLUDE_TYPECHANGE |
		GIT_DIFF_SKIP_BINARY_CHECK;

	if (opts && opts->paths.count > 0)
		diff_opts.pathspec = opts->paths;

	if ((error = git_diff_workdir_to_index(repo, &diff_opts, &diff)) < 0)
		goto cleanup;

	if ((error = git_buf_puts(&workdir, git_repository_workdir(repo))) < 0)
		goto cleanup;

	normalize_options(&checkout_opts, opts);

	if (!stats)
		stats = &dummy_stats;

	stats->processed = 0;
	/* total based on 3 passes, but it might be 2 if no submodules */
	stats->total = (unsigned int)git_diff_num_deltas(diff) * 3;

	memset(&data, 0, sizeof(data));

	data.path = &workdir;
	data.workdir_len = git_buf_len(&workdir);
	data.checkout_opts = &checkout_opts;
	data.stats = stats;
	data.owner = repo;

	if ((error = retrieve_symlink_capabilities(repo, &data.can_symlink)) < 0)
		goto cleanup;

	/* Checkout is best performed with three passes through the diff.
	 *
	 * 1. First do removes, because we iterate in alphabetical order, thus
	 *    a new untracked directory will end up sorted *after* a blob that
	 *    should be checked out with the same name.
	 * 2. Then checkout all blobs.
	 * 3. Then checkout all submodules in case a new .gitmodules blob was
	 *    checked out during pass #2.
	 */

	if (!(error = git_diff_foreach(
			diff, &data, checkout_remove_the_old, NULL, NULL)) &&
		!(error = git_diff_foreach(
			diff, &data, checkout_create_the_new, NULL, NULL)) &&
		data.found_submodules)
	{
		data.create_submodules = true;
		error = git_diff_foreach(
			diff, &data, checkout_create_the_new, NULL, NULL);
	}

	stats->processed = stats->total;

cleanup:
	if (error == GIT_EUSER)
		error = (data.error != 0) ? data.error : -1;

	git_diff_list_free(diff);
	git_buf_free(&workdir);

	return error;
}
Esempio n. 26
0
void test_diff_diffiter__max_size_threshold(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	int file_count = 0, binary_count = 0, hunk_count = 0;
	size_t d, num_d;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));
	num_d = git_diff_num_deltas(diff);

	for (d = 0; d < num_d; ++d) {
		git_diff_patch *patch;
		const git_diff_delta *delta;

		cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d));
		cl_assert(delta);
		cl_assert(patch);

		file_count++;
		hunk_count += (int)git_diff_patch_num_hunks(patch);

		assert(delta->binary == 0 || delta->binary == 1);
		binary_count += delta->binary;

		git_diff_patch_free(patch);
	}

	cl_assert_equal_i(13, file_count);
	cl_assert_equal_i(0, binary_count);
	cl_assert_equal_i(8, hunk_count);

	git_diff_list_free(diff);

	/* try again with low file size threshold */

	file_count = binary_count = hunk_count = 0;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
	opts.max_size = 50; /* treat anything over 50 bytes as binary! */

	cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));
	num_d = git_diff_num_deltas(diff);

	for (d = 0; d < num_d; ++d) {
		git_diff_patch *patch;
		const git_diff_delta *delta;

		cl_git_pass(git_diff_get_patch(&patch, &delta, diff, d));

		file_count++;
		hunk_count += (int)git_diff_patch_num_hunks(patch);

		assert(delta->binary == 0 || delta->binary == 1);
		binary_count += delta->binary;

		git_diff_patch_free(patch);
	}

	cl_assert_equal_i(13, file_count);
	/* Three files are over the 50 byte threshold:
	 * - staged_changes_file_deleted
	 * - staged_changes_modified_file
	 * - staged_new_file_modified_file
	 */
	cl_assert_equal_i(3, binary_count);
	cl_assert_equal_i(5, hunk_count);

	git_diff_list_free(diff);
}
Esempio n. 27
0
void test_diff_index__0(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
	const char *b_commit = "0017bd4ab1ec3"; /* the start */
	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;

	cl_assert(a);
	cl_assert(b);

	opts.context_lines = 1;
	opts.interhunk_lines = 1;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	/* to generate these values:
	 * - cd to tests/resources/status,
	 * - mv .gitted .git
	 * - git diff --name-status --cached 26a125ee1bf
	 * - git diff -U1 --cached 26a125ee1bf
	 * - mv .git .gitted
	 */
	cl_assert_equal_i(8, exp.files);
	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);

	cl_assert_equal_i(8, exp.hunks);

	cl_assert_equal_i(11, exp.lines);
	cl_assert_equal_i(3, exp.line_ctxt);
	cl_assert_equal_i(6, exp.line_adds);
	cl_assert_equal_i(2, exp.line_dels);

	git_diff_list_free(diff);
	diff = NULL;
	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, b, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	/* to generate these values:
	 * - cd to tests/resources/status,
	 * - mv .gitted .git
	 * - git diff --name-status --cached 0017bd4ab1ec3
	 * - git diff -U1 --cached 0017bd4ab1ec3
	 * - mv .git .gitted
	 */
	cl_assert_equal_i(12, exp.files);
	cl_assert_equal_i(7, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);

	cl_assert_equal_i(12, exp.hunks);

	cl_assert_equal_i(16, exp.lines);
	cl_assert_equal_i(3, exp.line_ctxt);
	cl_assert_equal_i(11, exp.line_adds);
	cl_assert_equal_i(2, exp.line_dels);

	git_diff_list_free(diff);
	diff = NULL;

	git_tree_free(a);
	git_tree_free(b);
}
Esempio n. 28
0
void test_diff_diffiter__iterate_randomly_while_saving_state(void)
{
	git_repository *repo = cl_git_sandbox_init("status");
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp = {0};
	git_diff_patch *patches[PATCH_CACHE];
	size_t p, d, num_d;

	memset(patches, 0, sizeof(patches));

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));

	num_d = git_diff_num_deltas(diff);

	/* To make sure that references counts work for diff and patch objects,
	 * this generates patches and randomly caches them.  Only when the patch
	 * is removed from the cache are hunks and lines counted.  At the end,
	 * there are still patches in the cache, so free the diff and try to
	 * process remaining patches after the diff is freed.
	 */

	srand(121212);
	p = rand() % PATCH_CACHE;

	for (d = 0; d < num_d; ++d) {
		/* take old patch */
		git_diff_patch *patch = patches[p];
		patches[p] = NULL;

		/* cache new patch */
		cl_git_pass(git_diff_get_patch(&patches[p], NULL, diff, d));
		cl_assert(patches[p] != NULL);

		/* process old patch if non-NULL */
		if (patch != NULL) {
			iterate_over_patch(patch, &exp);
			git_diff_patch_free(patch);
		}

		p = rand() % PATCH_CACHE;
	}

	/* free diff list now - refcounts should keep things safe */
	git_diff_list_free(diff);

	/* process remaining unprocessed patches */
	for (p = 0; p < PATCH_CACHE; p++) {
		git_diff_patch *patch = patches[p];

		if (patch != NULL) {
			iterate_over_patch(patch, &exp);
			git_diff_patch_free(patch);
		}
	}

	/* hopefully it all still added up right */
	cl_assert_equal_i(13, exp.files);
	cl_assert_equal_i(8, exp.hunks);
	cl_assert_equal_i(14, exp.lines);
}
Esempio n. 29
0
void test_diff_tree__options(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "6bab5c79cd5140d0";
	const char *b_commit = "605812ab7fe421fdd";
	const char *c_commit = "f5b0af1fb4f5";
	const char *d_commit = "a97cc019851";
	git_tree *a, *b, *c, *d;
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects actual;
	int test_ab_or_cd[] = { 0, 0, 0, 0, 1, 1, 1, 1, 1 };
	git_diff_options test_options[] = {
		/* a vs b tests */
		{ GIT_DIFF_NORMAL, 1, 1, NULL, NULL, {0} },
		{ GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} },
		{ GIT_DIFF_REVERSE, 2, 1, NULL, NULL, {0} },
		{ GIT_DIFF_FORCE_TEXT, 2, 1, NULL, NULL, {0} },
		/* c vs d tests */
		{ GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} },
		{ GIT_DIFF_IGNORE_WHITESPACE, 3, 1, NULL, NULL, {0} },
		{ GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3, 1, NULL, NULL, {0} },
		{ GIT_DIFF_IGNORE_WHITESPACE_EOL, 3, 1, NULL, NULL, {0} },
		{ GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1, 1, NULL, NULL, {0} },
	};
	/* to generate these values:
	 * - cd to tests/resources/attr,
	 * - mv .gitted .git
	 * - git diff [options] 6bab5c79cd5140d0 605812ab7fe421fdd
	 * - mv .git .gitted
	 */
	diff_expects test_expects[] = {
		/* a vs b tests */
		{ 5, 3, 0, 2, 0, 0, 0, 4, 0, 0, 51, 2, 46, 3 },
		{ 5, 3, 0, 2, 0, 0, 0, 4, 0, 0, 53, 4, 46, 3 },
		{ 5, 0, 3, 2, 0, 0, 0, 4, 0, 0, 52, 3, 3, 46 },
		{ 5, 3, 0, 2, 0, 0, 0, 5, 0, 0, 54, 3, 48, 3 },
		/* c vs d tests */
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 22, 9, 10, 3 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 19, 12, 7, 0 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 20, 11, 8, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 20, 11, 8, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18, 11, 0, 7 },
		{ 0 },
	};
	diff_expects *expected;
	int i;

	g_repo = cl_git_sandbox_init("attr");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);
	cl_assert((d = resolve_commit_oid_to_tree(g_repo, d_commit)) != NULL);

	for (i = 0; test_expects[i].files > 0; i++) {
		memset(&actual, 0, sizeof(actual)); /* clear accumulator */
		opts = test_options[i];

		if (test_ab_or_cd[i] == 0)
			cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff));
		else
			cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, c, d, &diff));

		cl_git_pass(git_diff_foreach(
			diff, &actual, diff_file_fn, diff_hunk_fn, diff_line_fn));

		expected = &test_expects[i];
		cl_assert_equal_i(actual.files,     expected->files);
		cl_assert_equal_i(actual.file_adds, expected->file_adds);
 		cl_assert_equal_i(actual.file_dels, expected->file_dels);
		cl_assert_equal_i(actual.file_mods, expected->file_mods);
		cl_assert_equal_i(actual.hunks,     expected->hunks);
		cl_assert_equal_i(actual.lines,     expected->lines);
		cl_assert_equal_i(actual.line_ctxt, expected->line_ctxt);
		cl_assert_equal_i(actual.line_adds, expected->line_adds);
		cl_assert_equal_i(actual.line_dels, expected->line_dels);

		git_diff_list_free(diff);
		diff = NULL;
	}

	git_tree_free(a);
	git_tree_free(b);
	git_tree_free(c);
	git_tree_free(d);
}
Esempio n. 30
0
void test_diff_tree__0(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "605812a";
	const char *b_commit = "370fe9ec22";
	const char *c_commit = "f5b0af1fb4f5c";
	git_tree *a, *b, *c;
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;

	g_repo = cl_git_sandbox_init("attr");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);

	opts.context_lines = 1;
	opts.interhunk_lines = 1;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, a, b, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 5);
	cl_assert(exp.file_adds == 2);
	cl_assert(exp.file_dels == 1);
	cl_assert(exp.file_mods == 2);

	cl_assert(exp.hunks == 5);

	cl_assert(exp.lines == 7 + 24 + 1 + 6 + 6);
	cl_assert(exp.line_ctxt == 1);
	cl_assert(exp.line_adds == 24 + 1 + 5 + 5);
	cl_assert(exp.line_dels == 7 + 1);

	git_diff_list_free(diff);
	diff = NULL;

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_tree_to_tree(g_repo, &opts, c, b, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 2);
	cl_assert(exp.file_adds == 0);
	cl_assert(exp.file_dels == 0);
	cl_assert(exp.file_mods == 2);

	cl_assert(exp.hunks == 2);

	cl_assert(exp.lines == 8 + 15);
	cl_assert(exp.line_ctxt == 1);
	cl_assert(exp.line_adds == 1);
	cl_assert(exp.line_dels == 7 + 14);

	git_diff_list_free(diff);

	git_tree_free(a);
	git_tree_free(b);
	git_tree_free(c);
}