PyObject * Diff_patch__get__(Diff *self) { git_patch* patch; git_buf buf = {NULL}; int err = GIT_ERROR; size_t i, len, num; PyObject *py_patch = NULL; num = git_diff_num_deltas(self->list); if (num == 0) Py_RETURN_NONE; for (i = 0, len = 1; i < num ; ++i) { err = git_patch_from_diff(&patch, self->list, i); if (err < 0) goto cleanup; /* This appends to the current buf, so we can simply keep passing it */ err = git_patch_to_buf(&buf, patch); if (err < 0) goto cleanup; git_patch_free(patch); } py_patch = to_unicode(buf.ptr, NULL, NULL); git_buf_free(&buf); cleanup: git_buf_free(&buf); return (err < 0) ? Error_set(err) : py_patch; }
void test_diff_blob__patch_with_freed_blobs(void) { git_oid a_oid, b_oid; git_blob *a, *b; git_patch *p; git_buf buf = GIT_BUF_INIT; /* tests/resources/attr/root_test1 */ cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8)); cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4)); /* tests/resources/attr/root_test2 */ cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8)); cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4)); cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, NULL)); git_blob_free(a); git_blob_free(b); cl_git_pass(git_patch_to_buf(&buf, p)); cl_assert_equal_s(buf.ptr, BLOB_DIFF); git_patch_free(p); git_buf_free(&buf); }
void test_patch( const char *one, const char *two, const git_diff_options *opts, const char *expected) { git_oid id_one, id_two; git_index *index = NULL; git_commit *commit_one, *commit_two = NULL; git_tree *tree_one, *tree_two; git_diff *diff; git_patch *patch; git_buf actual = GIT_BUF_INIT; cl_git_pass(git_oid_fromstr(&id_one, one)); cl_git_pass(git_commit_lookup(&commit_one, repo, &id_one)); cl_git_pass(git_commit_tree(&tree_one, commit_one)); if (two) { cl_git_pass(git_oid_fromstr(&id_two, two)); cl_git_pass(git_commit_lookup(&commit_two, repo, &id_two)); cl_git_pass(git_commit_tree(&tree_two, commit_two)); } else { cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_write_tree(&id_two, index)); cl_git_pass(git_tree_lookup(&tree_two, repo, &id_two)); } cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree_one, tree_two, opts)); cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_to_buf(&actual, patch)); cl_assert_equal_s(expected, actual.ptr); git_buf_clear(&actual); cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual)); cl_assert_equal_s(expected, actual.ptr); git_buf_dispose(&actual); git_patch_free(patch); git_diff_free(diff); git_tree_free(tree_one); git_tree_free(tree_two); git_commit_free(commit_one); git_commit_free(commit_two); git_index_free(index); }
void test_diff_binary__index_to_workdir(void) { git_index *index; git_diff *diff; git_patch *patch; 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_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_to_buf(&actual, patch)); cl_assert_equal_s(expected, actual.ptr); cl_git_pass(git_index_add_bypath(index, "untimely.txt")); cl_git_pass(git_index_write(index)); test_patch( "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13", NULL, &opts, expected); git_buf_dispose(&actual); git_patch_free(patch); git_diff_free(diff); git_index_free(index); }
void test_diff_parse__patch_roundtrip_succeeds(void) { const char buf1[] = "a\n", buf2[] = "b\n"; git_buf patchbuf = GIT_BUF_INIT, diffbuf = GIT_BUF_INIT; git_patch *patch; git_diff *diff; cl_git_pass(git_patch_from_buffers(&patch, buf1, strlen(buf1), "obj1", buf2, strlen(buf2), "obj2", NULL)); cl_git_pass(git_patch_to_buf(&patchbuf, patch)); cl_git_pass(git_diff_from_buffer(&diff, patchbuf.ptr, patchbuf.size)); cl_git_pass(git_diff_to_buf(&diffbuf, diff, GIT_DIFF_FORMAT_PATCH)); cl_assert_equal_s(patchbuf.ptr, diffbuf.ptr); git_patch_free(patch); git_diff_free(diff); git_buf_free(&patchbuf); git_buf_free(&diffbuf); }
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); }