зеркало из https://github.com/mono/libgit2.git
Introduce git_blame_options diff find configurability
This introduces a git_diff_find_options structure into
git_blame_options that can be used to filter out what
kind of file diffing to take place.
Added a new entry GIT_DIFF_FIND_NO_RENAMES which discards
any attempt of the library to check for renames.
The blobs added have the following steps:
Commit 'H': 49aed320fb734fe132f8a0723743b78ab369b17c
Added c.txt and d.txt, files with 2 blocks of text.
Commit 'I': c347c9265f655dcd26dd0d41a244d4c1bb6cb8c6
Renamed c.txt to c_exact.txt.
Commit 'J': c66b79ec0ee8f5aa0e981168c4c96e5e2483d361
Renamed d.txt to d_similar.txt and modified a block of text.
(cherry picked from commit 933a7b17c9
)
This commit is contained in:
Родитель
32dc763c11
Коммит
71efcb3158
|
@ -720,6 +720,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -627,6 +627,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 */
|
||||
|
|
|
@ -440,7 +440,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 */
|
||||
|
@ -449,9 +448,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 */
|
||||
|
|
|
@ -302,6 +302,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))
|
||||
|
|
|
@ -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, "49aed320", "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, "49aed320", "d.txt");
|
||||
check_blame_hunk_index(g_repo, g_blame, 1, 6, 4, 0, "c66b79ec", "d_similar.txt");
|
||||
check_blame_hunk_index(g_repo, g_blame, 2, 10, 1, 0, "49aed320", "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, "49aed320", "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, "c66b79ec", "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, "c347c926", "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, "c66b79ec", "d_similar.txt");
|
||||
}
|
||||
|
|
Двоичные данные
tests/resources/blametest.git/objects/49/aed320fb734fe132f8a0723743b78ab369b17c
Normal file
Двоичные данные
tests/resources/blametest.git/objects/49/aed320fb734fe132f8a0723743b78ab369b17c
Normal file
Двоичный файл не отображается.
Двоичные данные
tests/resources/blametest.git/objects/68/6d51de188b5a542c9af7f64a4ac5f31b4c43aa
Normal file
Двоичные данные
tests/resources/blametest.git/objects/68/6d51de188b5a542c9af7f64a4ac5f31b4c43aa
Normal file
Двоичный файл не отображается.
Двоичные данные
tests/resources/blametest.git/objects/6c/90a25d65273c4599f00fa396082b7cc9e5b749
Normal file
Двоичные данные
tests/resources/blametest.git/objects/6c/90a25d65273c4599f00fa396082b7cc9e5b749
Normal file
Двоичный файл не отображается.
Двоичные данные
tests/resources/blametest.git/objects/7e/18c1f0e766379f588fcee7ec7c2e45295d8df7
Normal file
Двоичные данные
tests/resources/blametest.git/objects/7e/18c1f0e766379f588fcee7ec7c2e45295d8df7
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,2 @@
|
|||
x5<>½j1„Së)¶s0{Zét&\…<>2é%<25>ä¶NF'…<~äüT;;3>§´T<C2B4>Šj FÏh¥žG-
y¥™#b´Ä#NÒï9hg‹›-a ؆™$FgHÅ0<C385>Œ“E#É(rf²ŽFvƒñ¶ú‘¼çV‚]¼Ú²´
éçîÛpü²wkÝûœž`PDˆ
|
||||
5Á#v%ºÛ×Pà}Ÿùšgxi—|…Ãý½´cZ|É[Žõ KÆÞ¾†§ßÉ»ç<C2BB>øO¶M™
|
|
@ -0,0 +1,2 @@
|
|||
x5ŹËj1E»öWh—E!ř!{f ”@v-]¶{Yö¤CâqđŘĄź_§Ź•¤sá Ë9ĄĄ‚FóPKŚŕF¬
|
||||
QŤŁ·dQóDó0;$$¶łQ
‘¸Q‰k68𤝝ťµ<C5A5><C2B5>v!Č€Š4b@VŢ;ö#;A~äoëą•Hk<48>W*KŰŕ<C5B0>~ćľýÇ/şŁuĎ9=<3D>Bc¤D9đ(ű&:í×Xŕ}‹źůšĽ´KľÂá~^Ú1-\ň–çú'°8éI*Ą»@u<>8ýVŢ=ďÄ7]RO
|
Двоичные данные
tests/resources/blametest.git/objects/f7/fe99763e059cb1989222c230c8a0102d0efc56
Normal file
Двоичные данные
tests/resources/blametest.git/objects/f7/fe99763e059cb1989222c230c8a0102d0efc56
Normal file
Двоичный файл не отображается.
|
@ -1 +1 @@
|
|||
6653ff42313eb5c82806f145391b18a9699800c7
|
||||
c66b79ec0ee8f5aa0e981168c4c96e5e2483d361
|
||||
|
|
Загрузка…
Ссылка в новой задаче