summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-10-21 15:36:38 -0700
committerRussell Belfer <rb@github.com>2013-10-21 15:36:38 -0700
commit5de4ec810492178095897f726bfaf879994aaf11 (patch)
tree266f521ca7fc71f871794d27ec9cc7ea5b1f122d
parent623460ab139bbb0360f51b26ac27fb6932569278 (diff)
downloadlibgit2-5de4ec810492178095897f726bfaf879994aaf11.tar.gz
Implement patience and minimal diff flags
It seems that to implement these options, we just have to pass the appropriate flags through to the libxdiff code taken from core git. So let's do it (and add a test).
-rw-r--r--include/git2/diff.h5
-rw-r--r--src/diff_xdiff.c5
-rw-r--r--tests-clar/diff/workdir.c47
3 files changed, 56 insertions, 1 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index ed9f71355..505c3e793 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -175,8 +175,11 @@ typedef enum {
*/
GIT_DIFF_SHOW_UNMODIFIED = (1u << 26),
- /** Use the "patience diff" algorithm (currently unimplemented) */
+ /** Use the "patience diff" algorithm */
GIT_DIFF_PATIENCE = (1u << 28),
+ /** Take extra time to find minimal diff */
+ GIT_DIFF_MINIMAL = (1 << 29),
+
} git_diff_option_t;
/**
diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c
index d07a33221..2aca76f87 100644
--- a/src/diff_xdiff.c
+++ b/src/diff_xdiff.c
@@ -222,6 +222,11 @@ void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts)
if (flags & GIT_DIFF_IGNORE_WHITESPACE_EOL)
xo->params.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+ if (flags & GIT_DIFF_PATIENCE)
+ xo->params.flags |= XDF_PATIENCE_DIFF;
+ if (flags & GIT_DIFF_MINIMAL)
+ xo->params.flags |= XDF_NEED_MINIMAL;
+
memset(&xo->callback, 0, sizeof(xo->callback));
xo->callback.outf = git_xdiff_cb;
}
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 474891c16..e72acdb03 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -1282,3 +1282,50 @@ void test_diff_workdir__untracked_with_bom(void)
git_diff_free(diff);
}
+
+void test_diff_workdir__patience_diff(void)
+{
+ git_index *index;
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff *diff = NULL;
+ git_patch *patch = NULL;
+ char *as_str = NULL;
+ const char *expected_normal = "diff --git a/test.txt b/test.txt\nindex 34a5acc..d52725f 100644\n--- a/test.txt\n+++ b/test.txt\n@@ -1,10 +1,7 @@\n When I wrote this\n I did not know\n-how to create\n-a patience diff\n I did not know\n how to create\n+a patience diff\n another problem\n-I did not know\n-how to create\n a minimal diff\n";
+ const char *expected_patience = "diff --git a/test.txt b/test.txt\nindex 34a5acc..d52725f 100644\n--- a/test.txt\n+++ b/test.txt\n@@ -1,10 +1,7 @@\n When I wrote this\n I did not know\n+I did not know\n how to create\n a patience diff\n-I did not know\n-how to create\n another problem\n-I did not know\n-how to create\n a minimal diff\n";
+
+ g_repo = cl_git_sandbox_init("empty_standard_repo");
+ cl_repo_set_bool(g_repo, "core.autocrlf", true);
+ cl_git_pass(git_repository_index(&index, g_repo));
+
+ cl_git_mkfile(
+ "empty_standard_repo/test.txt",
+ "When I wrote this\nI did not know\nhow to create\na patience diff\nI did not know\nhow to create\nanother problem\nI did not know\nhow to create\na minimal diff\n");
+ cl_git_pass(git_index_add_bypath(index, "test.txt"));
+ cl_repo_commit_from_index(NULL, g_repo, NULL, 1372350000, "Base");
+
+ cl_git_rewritefile(
+ "empty_standard_repo/test.txt",
+ "When I wrote this\nI did not know\nI did not know\nhow to create\na patience diff\nanother problem\na minimal diff\n");
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_assert_equal_i(1, git_diff_num_deltas(diff));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_git_pass(git_patch_to_str(&as_str, patch));
+
+ cl_assert_equal_s(expected_normal, as_str);
+ git__free(as_str);
+ git_patch_free(patch);
+ git_diff_free(diff);
+
+ opts.flags |= GIT_DIFF_PATIENCE;
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+ cl_assert_equal_i(1, git_diff_num_deltas(diff));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_git_pass(git_patch_to_str(&as_str, patch));
+
+ cl_assert_equal_s(expected_patience, as_str);
+ git__free(as_str);
+ git_patch_free(patch);
+ git_diff_free(diff);
+}