Esempio n. 1
0
void test_diff_binary__delta_append(void)
{
	git_index *index;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	const char *expected =
		"diff --git a/untimely.txt b/untimely.txt\n" \
		"index 9a69d960ae94b060f56c2a8702545e2bb1abb935..1111d4f11f4b35bf6759e0fb714fe09731ef0840 100644\n" \
		"GIT binary patch\n" \
		"delta 32\n" \
		"nc%1vf+QYWt3zLL@hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW\n" \
		"\n" \
		"delta 7\n" \
		"Oc%18D`@*{63ljhg(E~C7\n" \
		"\n";

	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
	opts.id_abbrev = GIT_OID_HEXSZ;

	repo = cl_git_sandbox_init("renames");
	cl_git_pass(git_repository_index(&index, repo));

	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
	cl_git_pass(git_index_write(index));

	test_patch(
		"19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13",
		NULL,
		&opts,
		expected);

	git_index_free(index);
}
Esempio n. 2
0
void test_diff_binary__print_patch_from_diff(void)
{
	git_index *index;
	git_diff *diff;
	git_buf actual = GIT_BUF_INIT;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	const char *expected =
		"diff --git a/untimely.txt b/untimely.txt\n" \
		"index 9a69d960ae94b060f56c2a8702545e2bb1abb935..1111d4f11f4b35bf6759e0fb714fe09731ef0840 100644\n" \
		"GIT binary patch\n" \
		"delta 32\n" \
		"nc%1vf+QYWt3zLL@hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW\n" \
		"\n" \
		"delta 7\n" \
		"Oc%18D`@*{63ljhg(E~C7\n" \
		"\n";

	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
	opts.id_abbrev = GIT_OID_HEXSZ;

	repo = cl_git_sandbox_init("renames");
	cl_git_pass(git_repository_index(&index, repo));

	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");

	cl_git_pass(git_diff_index_to_workdir(&diff, repo, index, &opts));

	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, print_cb, &actual));

	cl_assert_equal_s(expected, actual.ptr);

	git_buf_dispose(&actual);
	git_diff_free(diff);
	git_index_free(index);
}
Esempio n. 3
0
void test_apply_both__index_must_match_workdir(void)
{
	git_diff *diff;
	git_index *index;
	git_index_entry idx_entry;

	const char *diff_file = DIFF_MODIFY_TWO_FILES;

	/*
	 * Append a line to the end of the file in both the index and the
	 * working directory.  Although the appended line would allow for
	 * patch application in each, the line appended is different in
	 * each, so the application should not be allowed.
	 */
	cl_git_append2file("merge-recursive/asparagus.txt",
	    "This is a modification.\n");

	cl_git_pass(git_repository_index(&index, repo));

	memset(&idx_entry, 0, sizeof(git_index_entry));
	idx_entry.mode = 0100644;
	idx_entry.path = "asparagus.txt";
	cl_git_pass(git_oid_fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538"));
	cl_git_pass(git_index_add(index, &idx_entry));

	cl_git_pass(git_index_write(index));
	git_index_free(index);

	cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
	cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));

	git_diff_free(diff);
}
Esempio n. 4
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);
}
Esempio n. 5
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. 6
0
static void commit_and_tag(
	git_time_t *time,
	const char *commit_msg,
	const char *tag_name)
{
	git_index *index;
	git_oid commit_id;
	git_reference *ref;
	
	cl_git_pass(git_repository_index__weakptr(&index, repo));

	cl_git_append2file("describe/file", "\n");
	
	cl_git_pass(git_index_add_bypath(index, "file"));
	cl_git_pass(git_index_write(index));

	*time += 10;
	cl_repo_commit_from_index(&commit_id, repo, NULL, *time, commit_msg);

	if (tag_name == NULL)
		return;

	cl_git_pass(git_reference_create(&ref, repo, tag_name, &commit_id, 0, NULL));
	git_reference_free(ref);
}
Esempio n. 7
0
void test_diff_binary__blob_to_blob(void)
{
	git_index *index;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_blob *old_blob, *new_blob;
	git_oid old_id, new_id;
	struct diff_data diff_data = {0};

	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
	opts.id_abbrev = GIT_OID_HEXSZ;

	repo = cl_git_sandbox_init("renames");
	cl_git_pass(git_repository_index__weakptr(&index, repo));

	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
	cl_git_pass(git_index_write(index));

	git_oid_fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935");
	git_oid_fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840");

	cl_git_pass(git_blob_lookup(&old_blob, repo, &old_id));
	cl_git_pass(git_blob_lookup(&new_blob, repo, &new_id));

	cl_git_pass(git_diff_blobs(old_blob,
		"untimely.txt", new_blob, "untimely.txt", &opts,
		file_cb, binary_cb, hunk_cb, line_cb, &diff_data));

	cl_assert_equal_s("untimely.txt", diff_data.old_path);
	cl_assert_equal_oid(&old_id, &diff_data.old_id);
	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.old_binary_type);
	cl_assert_equal_i(7, diff_data.old_binary_inflatedlen);
	cl_assert_equal_s("c%18D`@*{63ljhg(E~C7",
		diff_data.old_binary_base85.ptr);

	cl_assert_equal_s("untimely.txt", diff_data.new_path);
	cl_assert_equal_oid(&new_id, &diff_data.new_id);
	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.new_binary_type);
	cl_assert_equal_i(32, diff_data.new_binary_inflatedlen);
	cl_assert_equal_s("c%1vf+QYWt3zLL@hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW",
		diff_data.new_binary_base85.ptr);

	git_blob_free(old_blob);
	git_blob_free(new_blob);

	git__free(diff_data.old_path);
	git__free(diff_data.new_path);

	git_buf_dispose(&diff_data.old_binary_base85);
	git_buf_dispose(&diff_data.new_binary_base85);
}
Esempio n. 8
0
void test_repo_hashfile__filtered(void)
{
	git_oid a, b;
	git_config *config;

	cl_git_pass(git_repository_config(&config, _repo));
	cl_git_pass(git_config_set_bool(config, "core.autocrlf", true));
	git_config_free(config);

	cl_git_append2file("status/.gitattributes", "*.txt text\n*.bin binary\n\n");

	/* create some sample content with CRLF in it */
	cl_git_mkfile("status/testfile.txt", "content\r\n");
	cl_git_mkfile("status/testfile.bin", "other\r\nstuff\r\n");

	/* not equal hashes because of filtering */
	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, NULL));
	cl_assert(git_oid_cmp(&a, &b));

	/* equal hashes because filter is binary */
	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, NULL));
	cl_assert(git_oid_equal(&a, &b));

	/* equal hashes when 'as_file' points to binary filtering */
	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, "foo.bin"));
	cl_assert(git_oid_equal(&a, &b));

	/* not equal hashes when 'as_file' points to text filtering */
	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, "foo.txt"));
	cl_assert(git_oid_cmp(&a, &b));

	/* equal hashes when 'as_file' is empty and turns off filtering */
	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, ""));
	cl_assert(git_oid_equal(&a, &b));

	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, ""));
	cl_assert(git_oid_equal(&a, &b));

	/* some hash type failures */
	cl_git_fail(git_odb_hashfile(&a, "status/testfile.txt", 0));
	cl_git_fail(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_ANY, NULL));
}
Esempio n. 9
0
void test_stash_save__untracked_skips_ignored(void)
{
	cl_git_append2file("stash/.gitignore", "bundle/vendor/\n");
	cl_must_pass(p_mkdir("stash/bundle", 0777));
	cl_must_pass(p_mkdir("stash/bundle/vendor", 0777));
	cl_git_mkfile("stash/bundle/vendor/blah", "contents\n");

	cl_assert(git_path_exists("stash/when")); /* untracked */
	cl_assert(git_path_exists("stash/just.ignore")); /* ignored */
	cl_assert(git_path_exists("stash/bundle/vendor/blah")); /* ignored */

	cl_git_pass(git_stash_save(
		&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));

	cl_assert(!git_path_exists("stash/when"));
	cl_assert(git_path_exists("stash/bundle/vendor/blah"));
	cl_assert(git_path_exists("stash/just.ignore"));
}
Esempio n. 10
0
void test_object_blob_filter__to_odb(void)
{
	git_filter_list *fl = NULL;
	git_config *cfg;
	int i;
	git_blob *blob;
	git_buf out = GIT_BUF_INIT, zeroed;

	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_assert(cfg);

	git_attr_cache_flush(g_repo);
	cl_git_append2file("empty_standard_repo/.gitattributes", "*.txt text\n");

	cl_git_pass(git_filter_list_load(
		&fl, g_repo, NULL, "filename.txt", GIT_FILTER_TO_ODB, 0));
	cl_assert(fl != NULL);

	for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
		cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));

		/* try once with allocated blob */
		cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));
		cl_assert_equal_sz(g_crlf_filtered[i].size, out.size);
		cl_assert_equal_i(
			0, memcmp(out.ptr, g_crlf_filtered[i].ptr, out.size));

		/* try again with zeroed blob */
		memset(&zeroed, 0, sizeof(zeroed));
		cl_git_pass(git_filter_list_apply_to_blob(&zeroed, fl, blob));
		cl_assert_equal_sz(g_crlf_filtered[i].size, zeroed.size);
		cl_assert_equal_i(
			0, memcmp(zeroed.ptr, g_crlf_filtered[i].ptr, zeroed.size));
		git_buf_free(&zeroed);

		git_blob_free(blob);
	}

	git_filter_list_free(fl);
	git_buf_free(&out);
	git_config_free(cfg);
}
Esempio n. 11
0
void test_apply_both__can_apply_nonconflicting_file_changes(void)
{
	git_diff *diff;
	git_index *index;

	const char *diff_file = DIFF_MODIFY_TWO_FILES;

	struct merge_index_entry both_expected[] = {
		{ 0100644, "f8a701c8a1a22c1729ee50faff1111f2d64f96fc", 0, "asparagus.txt" },
		{ 0100644, "68f6182f4c85d39e1309d97c7e456156dc9c0096", 0, "beef.txt" },
		{ 0100644, "4b7c5650008b2e747fe1809eeb5a1dde0e80850a", 0, "bouilli.txt" },
		{ 0100644, "c4e6cca3ec6ae0148ed231f97257df8c311e015f", 0, "gravy.txt" },
		{ 0100644, "68af1fc7407fd9addf1701a87eb1c95c7494c598", 0, "oyster.txt" },
		{ 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" },
	};
	size_t both_expected_cnt = sizeof(both_expected) /
		sizeof(struct merge_index_entry);

	/*
	 * Replace the workdir file with a version that is different than
	 * HEAD but such that the patch still applies cleanly.  This item
	 * has a new line appended.
	 */
	cl_git_append2file("merge-recursive/asparagus.txt",
	    "This line is added in the index and the workdir.\n");

	cl_git_pass(git_repository_index(&index, repo));
	cl_git_pass(git_index_add_bypath(index, "asparagus.txt"));
	cl_git_pass(git_index_write(index));
	git_index_free(index);

	cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
	cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));

	validate_apply_index(repo, both_expected, both_expected_cnt);
	validate_apply_workdir(repo, both_expected, both_expected_cnt);

	git_diff_free(diff);
}
Esempio n. 12
0
void test_submodule_lookup__just_added(void)
{
	git_submodule *sm;
	git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT;
	git_reference *original_head = NULL;

	refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
	baseline_tests();

	cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules"));
	cl_git_pass(git_repository_head(&original_head, g_repo));

	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
		"https://github.com/libgit2/libgit2.git", "sm_just_added", 1));
	git_submodule_free(sm);
	assert_submodule_exists(g_repo, "sm_just_added");

	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
		"https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1));
	assert_submodule_exists(g_repo, "sm_just_added_2");
	cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */
	git_submodule_free(sm);

	add_submodule_with_commit("sm_just_added_head");
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head");
	assert_submodule_exists(g_repo, "sm_just_added_head");

	add_submodule_with_commit("sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_idx");

	cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules"));

	cl_git_append2file(
		"submod2/.gitmodules",
		"\n[submodule \"mismatch_name\"]\n"
		"\tpath = mismatch_path\n"
		"\turl = https://example.com/example.git\n\n");

	assert_submodule_exists(g_repo, "mismatch_name");
	assert_submodule_exists(g_repo, "mismatch_path");
	assert_submodule_exists(g_repo, "sm_just_added");
	assert_submodule_exists(g_repo, "sm_just_added_2");
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();

	cl_git_rewritefile("submod2/.gitmodules", snap2.ptr);
	git_buf_free(&snap2);

	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
	assert_submodule_exists(g_repo, "sm_just_added");
	assert_submodule_exists(g_repo, "sm_just_added_2");
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();

	cl_git_rewritefile("submod2/.gitmodules", snap1.ptr);
	git_buf_free(&snap1);

	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
	/* note error code change, because add_setup made a repo in the workdir */
	refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS);
	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS);
	/* these still exist in index and head respectively */
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();

	{
		git_index *idx;
		cl_git_pass(git_repository_index(&idx, g_repo));
		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx"));
		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head"));
		cl_git_pass(git_index_write(idx));
		git_index_free(idx);
	}

	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS);
	assert_submodule_exists(g_repo, "sm_just_added_head");

	{
		git_signature *sig;
		cl_git_pass(git_signature_now(&sig, "resetter", "*****@*****.**"));
		cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, sig, "move head back"));
		git_signature_free(sig);
		git_reference_free(original_head);
	}

	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS);
}
Esempio n. 13
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. 14
0
void test_checkout_tree__case_changing_rename(void)
{
	git_index *index;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_oid master_id, dir_commit_id, tree_id, commit_id;
	git_commit *master_commit, *dir_commit;
	git_tree *tree;
	git_signature *signature;
	const git_index_entry *index_entry;
	bool case_sensitive;

	assert_on_branch(g_repo, "master");

	cl_git_pass(git_repository_index(&index, g_repo));

	/* Switch branches and perform a case-changing rename */

	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_pass(git_reference_name_to_id(&dir_commit_id, g_repo, "refs/heads/dir"));
	cl_git_pass(git_commit_lookup(&dir_commit, g_repo, &dir_commit_id));

	cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts));
	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));

	cl_assert(git_path_isfile("testrepo/README"));
	case_sensitive = !git_path_isfile("testrepo/readme");

	cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
	cl_assert_equal_s("README", index_entry->path);

	cl_git_pass(git_index_remove_bypath(index, "README"));
	cl_git_pass(p_rename("testrepo/README", "testrepo/__readme__"));
	cl_git_pass(p_rename("testrepo/__readme__", "testrepo/readme"));
	cl_git_append2file("testrepo/readme", "An addendum...");
	cl_git_pass(git_index_add_bypath(index, "readme"));

	cl_git_pass(git_index_write(index));

	cl_git_pass(git_index_write_tree(&tree_id, index));
	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));

	cl_git_pass(git_signature_new(&signature, "Renamer", "*****@*****.**", time(NULL), 0));

	cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit));

	cl_assert(git_path_isfile("testrepo/readme"));
	if (case_sensitive)
		cl_assert(!git_path_isfile("testrepo/README"));

	cl_assert(index_entry = git_index_get_bypath(index, "readme", 0));
	cl_assert_equal_s("readme", index_entry->path);

	/* Switching back to master should rename readme -> README */
	opts.checkout_strategy = GIT_CHECKOUT_SAFE;

	cl_git_pass(git_reference_name_to_id(&master_id, g_repo, "refs/heads/master"));
	cl_git_pass(git_commit_lookup(&master_commit, g_repo, &master_id));

	cl_git_pass(git_checkout_tree(g_repo, (git_object *)master_commit, &opts));
	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
	
	assert_on_branch(g_repo, "master");

	cl_assert(git_path_isfile("testrepo/README"));
	if (case_sensitive)
		cl_assert(!git_path_isfile("testrepo/readme"));

	cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
	cl_assert_equal_s("README", index_entry->path);

	git_index_free(index);
	git_signature_free(signature);
	git_tree_free(tree);
	git_commit_free(dir_commit);
	git_commit_free(master_commit);
}
Esempio n. 15
0
void test_diff_blob__using_path_and_attributes(void)
{
	git_config *cfg;
	git_blob *bin, *nonbin;
	git_oid oid;
	const char *nonbin_content = "Hello from the root\n";
	const char *bin_content =
		"0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
	size_t bin_len = 33;
	const char *changed;
	git_patch *p;
	git_buf buf = GIT_BUF_INIT;

	/* set up custom diff drivers and 'diff' attribute mappings for them */

	cl_git_pass(git_repository_config(&cfg, g_repo));
	cl_git_pass(git_config_set_bool(cfg, "diff.iam_binary.binary", 1));
	cl_git_pass(git_config_set_bool(cfg, "diff.iam_text.binary", 0));
	cl_git_pass(git_config_set_string(
		cfg, "diff.iam_alphactx.xfuncname", "^[A-Za-z].*$"));
	cl_git_pass(git_config_set_bool(cfg, "diff.iam_textalpha.binary", 0));
	cl_git_pass(git_config_set_string(
		cfg, "diff.iam_textalpha.xfuncname", "^[A-Za-z].*$"));
	cl_git_pass(git_config_set_string(
		cfg, "diff.iam_numctx.funcname", "^[0-9][0-9]*"));
	cl_git_pass(git_config_set_bool(cfg, "diff.iam_textnum.binary", 0));
	cl_git_pass(git_config_set_string(
		cfg, "diff.iam_textnum.funcname", "^[0-9][0-9]*"));
	git_config_free(cfg);

	cl_git_append2file(
		"attr/.gitattributes",
		"\n\n# test_diff_blob__using_path_and_attributes extra\n\n"
		"*.binary  diff=iam_binary\n"
		"*.textary diff=iam_text\n"
		"*.alphary diff=iam_alphactx\n"
		"*.textalphary diff=iam_textalpha\n"
		"*.textnumary diff=iam_textnum\n"
		"*.numary  diff=iam_numctx\n\n");

	opts.context_lines = 0;
	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;

	cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
	cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8));
	/* 20b: "Hello from the root\n" */

	cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
	cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8));
	/* 33b: "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\n0123456789\n" */

	/* non-binary to reference content */

	quick_diff_blob_to_str(nonbin, NULL, nonbin_content, 0, NULL);
	assert_identical_blobs_comparison(&expected);
	cl_assert_equal_i(0, expected.files_binary);

	/* binary to reference content */

	quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
	assert_identical_blobs_comparison(&expected);
	cl_assert_equal_i(1, expected.files_binary);

	/* add some text */

	changed = "Hello from the root\nMore lines\nAnd more\nGo here\n";

	quick_diff_blob_to_str(nonbin, NULL, changed, 0, NULL);
	assert_one_modified(1, 3, 0, 3, 0, &expected);

	quick_diff_blob_to_str(nonbin, "foo/bar.binary", changed, 0, NULL);
	cl_assert_equal_i(1, expected.files);
	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_MODIFIED]);
	cl_assert_equal_i(1, expected.files_binary);
	cl_assert_equal_i(0, expected.hunks);
	cl_assert_equal_i(0, expected.lines);

	quick_diff_blob_to_str(nonbin, "foo/bar.textary", changed, 0, NULL);
	assert_one_modified(1, 3, 0, 3, 0, &expected);

	quick_diff_blob_to_str(nonbin, "foo/bar.alphary", changed, 0, NULL);
	assert_one_modified(1, 3, 0, 3, 0, &expected);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, nonbin, "zzz.normal", changed, strlen(changed), NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.normal b/zzz.normal\n"
		"index 45141a7..75b0dbb 100644\n"
		"--- a/zzz.normal\n"
		"+++ b/zzz.normal\n"
		"@@ -1,0 +2,3 @@ Hello from the root\n"
		"+More lines\n"
		"+And more\n"
		"+Go here\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, nonbin, "zzz.binary", changed, strlen(changed), NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.binary b/zzz.binary\n"
		"index 45141a7..75b0dbb 100644\n"
		"Binary files a/zzz.binary and b/zzz.binary differ\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, nonbin, "zzz.alphary", changed, strlen(changed), NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.alphary b/zzz.alphary\n"
		"index 45141a7..75b0dbb 100644\n"
		"--- a/zzz.alphary\n"
		"+++ b/zzz.alphary\n"
		"@@ -1,0 +2,3 @@ Hello from the root\n"
		"+More lines\n"
		"+And more\n"
		"+Go here\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, nonbin, "zzz.numary", changed, strlen(changed), NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.numary b/zzz.numary\n"
		"index 45141a7..75b0dbb 100644\n"
		"--- a/zzz.numary\n"
		"+++ b/zzz.numary\n"
		"@@ -1,0 +2,3 @@\n"
		"+More lines\n"
		"+And more\n"
		"+Go here\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	/* "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n"
	 * 33 bytes
	 */

	changed = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\nreplace a line\n";

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, bin, "zzz.normal", changed, 37, NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.normal b/zzz.normal\n"
		"index b435cd5..1604519 100644\n"
		"Binary files a/zzz.normal and b/zzz.normal differ\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, bin, "zzz.textary", changed, 37, NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.textary b/zzz.textary\n"
		"index b435cd5..1604519 100644\n"
		"--- a/zzz.textary\n"
		"+++ b/zzz.textary\n"
		"@@ -3 +3 @@\n"
		"-0123456789\n"
		"+replace a line\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, bin, "zzz.textalphary", changed, 37, NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.textalphary b/zzz.textalphary\n"
		"index b435cd5..1604519 100644\n"
		"--- a/zzz.textalphary\n"
		"+++ b/zzz.textalphary\n"
		"@@ -3 +3 @@\n"
		"-0123456789\n"
		"+replace a line\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	cl_git_pass(git_patch_from_blob_and_buffer(
		&p, bin, "zzz.textnumary", changed, 37, NULL, &opts));
	cl_git_pass(git_patch_to_buf(&buf, p));
	cl_assert_equal_s(
		"diff --git a/zzz.textnumary b/zzz.textnumary\n"
		"index b435cd5..1604519 100644\n"
		"--- a/zzz.textnumary\n"
		"+++ b/zzz.textnumary\n"
		"@@ -3 +3 @@ 0123456789\n"
		"-0123456789\n"
		"+replace a line\n", buf.ptr);
	git_buf_clear(&buf);
	git_patch_free(p);

	git_buf_free(&buf);
	git_blob_free(nonbin);
	git_blob_free(bin);
}
void test_diff_workdir__eof_newline_changes(void)
{
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	diff_expects exp;
	char *pathspec = "current_file";
	int use_iterator;

	g_repo = cl_git_sandbox_init("status");

	opts.pathspec.strings = &pathspec;
	opts.pathspec.count   = 1;

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

		cl_assert_equal_i(0, exp.files);
		cl_assert_equal_i(0, exp.file_adds);
		cl_assert_equal_i(0, exp.file_dels);
		cl_assert_equal_i(0, exp.file_mods);
		cl_assert_equal_i(0, exp.hunks);
		cl_assert_equal_i(0, exp.lines);
		cl_assert_equal_i(0, exp.line_ctxt);
		cl_assert_equal_i(0, exp.line_adds);
		cl_assert_equal_i(0, exp.line_dels);
	}

	git_diff_list_free(diff);

	cl_git_append2file("status/current_file", "\n");

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

		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(1, exp.hunks);
		cl_assert_equal_i(2, exp.lines);
		cl_assert_equal_i(1, exp.line_ctxt);
		cl_assert_equal_i(1, exp.line_adds);
		cl_assert_equal_i(0, exp.line_dels);
	}

	git_diff_list_free(diff);

	cl_git_rewritefile("status/current_file", "current_file");

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

		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(1, exp.hunks);
		cl_assert_equal_i(3, exp.lines);
		cl_assert_equal_i(0, exp.line_ctxt);
		cl_assert_equal_i(1, exp.line_adds);
		cl_assert_equal_i(2, exp.line_dels);
	}

	git_diff_list_free(diff);
}