예제 #1
0
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);
}
예제 #2
0
void test_diff_workdir__cannot_diff_against_a_bare_repository(void)
{
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	git_tree *tree;

	g_repo = cl_git_sandbox_init("testrepo.git");

	cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_index(g_repo, &opts, &diff));

	cl_git_pass(git_repository_head_tree(&tree, g_repo));
	cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_tree(g_repo, &opts, tree, &diff));

	git_tree_free(tree);
}
예제 #3
0
파일: workdir.c 프로젝트: Asquera/libgit2
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);
}
예제 #4
0
void test_diff_workdir__larger_hunks(void)
{
	const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
	const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
	git_tree *a, *b;
	git_diff_options opts = {0};
	size_t i, d, num_d, h, num_h, l, num_l, header_len, line_len;

	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;

	for (i = 0; i <= 2; ++i) {
		git_diff_list *diff = NULL;
		git_diff_patch *patch;
		const git_diff_range *range;
		const char *header, *line;
		char origin;

		/* okay, this is a bit silly, but oh well */
		switch (i) {
		case 0:
			cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff));
			break;
		case 1:
			cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff));
			break;
		case 2:
			cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, b, &diff));
			break;
		}

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

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

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

				/* confirm fail after the last item */
				cl_git_fail(git_diff_patch_get_line_in_hunk(
					&origin, &line, &line_len, NULL, NULL, patch, h, num_l));
			}

			/* confirm fail after the last item */
			cl_git_fail(git_diff_patch_get_hunk(
				&range, &header, &header_len, &num_l, patch, num_h));

			git_diff_patch_free(patch);
		}

		git_diff_list_free(diff);
	}

	git_tree_free(a);
	git_tree_free(b);
}