Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Ungureanu <marius.ungureanu@xamarin.com>2016-03-08 17:23:00 +0300
committerMarius Ungureanu <marius.ungureanu@xamarin.com>2016-03-08 17:23:00 +0300
commit17cbab953ae626685cc045fff08954c9d3a0389e (patch)
treef19da7c54ec5865f3dc71c06c31f2e220b9a5646
parentb7809b84692b4df7f11d603cc5da0860609e0555 (diff)
parentab8e88a96b5b9e1a59a6f8742fe0136b13158717 (diff)
Merge commit 'ab8e88a96b5b9e1a59a6f8742fe0136b13158717' into xs-6.0-v2xs-6.0-v2
-rw-r--r--CHANGELOG.md6
-rw-r--r--include/git2/blame.h12
-rw-r--r--include/git2/diff.h3
-rw-r--r--src/blame_git.c5
-rw-r--r--src/diff_tform.c3
-rw-r--r--tests/blame/simple.c49
6 files changed, 73 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21f972d2e..30161821a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -281,6 +281,12 @@ v0.23
* `git_submodule_set_branch()` allows to set the configured branch for
a submodule.
+* `git_blame_options` has been taught how to handle diff find options
+ through its find_options field.
+
+* `git_diff_find_t` has now been taught how to ignore rename handling
+ completely through `GIT_DIFF_FIND_NO_RENAMES`.
+
### API removals
* `git_remote_save()` and `git_remote_clear_refspecs()` have been
diff --git a/include/git2/blame.h b/include/git2/blame.h
index 84bb7f94c..f33a38933 100644
--- a/include/git2/blame.h
+++ b/include/git2/blame.h
@@ -9,6 +9,7 @@
#define INCLUDE_git_blame_h__
#include "common.h"
+#include "diff.h"
#include "oid.h"
/**
@@ -52,6 +53,9 @@ typedef enum {
* `GIT_BLAME_OPTIONS_INIT` macro:
* git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
*
+ *- `find_options` specifies what strategies should be used for
+ * rename detection. The default is rename with threshold
+ * heuristics.
* - `flags` is a combination of the `git_blame_flag_t` values above.
* - `min_match_characters` is the lower bound on the number of alphanumeric
* characters that must be detected as moving/copying within a file for it to
@@ -70,6 +74,8 @@ typedef enum {
typedef struct git_blame_options {
unsigned int version;
+ git_diff_find_options find_options;
+
uint32_t flags;
uint16_t min_match_characters;
git_oid newest_commit;
@@ -78,8 +84,12 @@ typedef struct git_blame_options {
size_t max_line;
} git_blame_options;
+#define GIT_BLAME_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION, \
+ GIT_DIFF_FIND_RENAMES }
+
#define GIT_BLAME_OPTIONS_VERSION 1
-#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
+#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION, \
+ GIT_BLAME_DIFF_FIND_OPTIONS_INIT }
/**
* Initializes a `git_blame_options` with default values. Equivalent to
diff --git a/include/git2/diff.h b/include/git2/diff.h
index c35701a46..67ce666ef 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -611,6 +611,9 @@ typedef enum {
/** Turn on all finding features. */
GIT_DIFF_FIND_ALL = (0x0ff),
+ /** Does no work on trying to find renames. */
+ GIT_DIFF_FIND_NO_RENAMES = (1u << 8),
+
/** Measure similarity ignoring leading whitespace (default) */
GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
/** Measure similarity ignoring all whitespace */
diff --git a/src/blame_git.c b/src/blame_git.c
index b8b568285..328259709 100644
--- a/src/blame_git.c
+++ b/src/blame_git.c
@@ -438,7 +438,6 @@ static git_blame__origin* find_origin(
/* No changes; copy data */
git_blame__get_origin(&porigin, blame, parent, origin->path);
} else {
- git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
int i;
/* Generate a full diff between the two trees */
@@ -447,9 +446,7 @@ static git_blame__origin* find_origin(
if (0 != git_diff_tree_to_tree(&difflist, blame->repository, ptree, otree, &diffopts))
goto cleanup;
- /* Let diff find renames */
- findopts.flags = GIT_DIFF_FIND_RENAMES;
- if (0 != git_diff_find_similar(difflist, &findopts))
+ if (0 != git_diff_find_similar(difflist, &blame->options.find_options))
goto cleanup;
/* Find one that matches */
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 8577f06b8..f6c8b58d6 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -301,6 +301,9 @@ static int normalize_find_opts(
if (opts->flags & GIT_DIFF_BREAK_REWRITES)
opts->flags |= GIT_DIFF_FIND_REWRITES;
+ if (opts->flags & GIT_DIFF_FIND_NO_RENAMES)
+ opts->flags &= ~GIT_DIFF_FIND_ALL;
+
#define USE_DEFAULT(X) ((X) == 0 || (X) > 100)
if (USE_DEFAULT(opts->rename_threshold))
diff --git a/tests/blame/simple.c b/tests/blame/simple.c
index 30b78168f..0cd3abef3 100644
--- a/tests/blame/simple.c
+++ b/tests/blame/simple.c
@@ -334,3 +334,52 @@ void test_blame_simple__can_restrict_to_first_parent_commits(void)
check_blame_hunk_index(g_repo, g_blame, 2, 6, 5, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_blame, 3, 11, 5, 0, "bc7c5ac2", "b.txt");
}
+
+void test_blame_simple__can_follow_renames(void)
+{
+ git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+ cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "c_exact.txt", &opts));
+ cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 10, 0, "e348f517", "c.txt");
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "d_similar.txt", &opts));
+ cl_assert_equal_i(3, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 5, 0, "e348f517", "d.txt");
+ check_blame_hunk_index(g_repo, g_blame, 1, 6, 4, 0, "fa2ae14c", "d_similar.txt");
+ check_blame_hunk_index(g_repo, g_blame, 2, 10, 1, 0, "e348f517", "d.txt");
+}
+
+void test_blame_simple__can_follow_only_exact_renames(void)
+{
+ git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+ opts.find_options.flags = GIT_DIFF_FIND_EXACT_MATCH_ONLY;
+
+ cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "c_exact.txt", &opts));
+ cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 10, 0, "e348f517", "c.txt");
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "d_similar.txt", &opts));
+ cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 10, 0, "fa2ae14c", "d_similar.txt");
+}
+
+void test_blame_simple__does_not_follow_renames(void)
+{
+ git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+ opts.find_options.flags = GIT_DIFF_FIND_NO_RENAMES;
+
+ cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "c_exact.txt", &opts));
+ cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 10, 0, "dc0ba436", "c_exact.txt");
+
+ cl_git_pass(git_blame_file(&g_blame, g_repo, "d_similar.txt", &opts));
+ cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
+ check_blame_hunk_index(g_repo, g_blame, 0, 1, 10, 0, "fa2ae14c", "d_similar.txt");
+}