Skip to content

Commit eef7e80

Browse files
author
Edward Thomson
committed
Merge pull request nodegit#1407 from ethomson/tform_small_files
handle small files in similarity metrics
2 parents d768f9a + aa408cb commit eef7e80

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

src/diff_tform.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,34 @@ static int find_similar__hashsig_for_file(
174174
void **out, const git_diff_file *f, const char *path, void *p)
175175
{
176176
git_hashsig_option_t opt = (git_hashsig_option_t)p;
177+
int error = 0;
178+
177179
GIT_UNUSED(f);
178-
return git_hashsig_create_fromfile((git_hashsig **)out, path, opt);
180+
error = git_hashsig_create_fromfile((git_hashsig **)out, path, opt);
181+
182+
if (error == GIT_EBUFS) {
183+
error = 0;
184+
giterr_clear();
185+
}
186+
187+
return error;
179188
}
180189

181190
static int find_similar__hashsig_for_buf(
182191
void **out, const git_diff_file *f, const char *buf, size_t len, void *p)
183192
{
184193
git_hashsig_option_t opt = (git_hashsig_option_t)p;
194+
int error = 0;
195+
185196
GIT_UNUSED(f);
186-
return git_hashsig_create((git_hashsig **)out, buf, len, opt);
197+
error = git_hashsig_create((git_hashsig **)out, buf, len, opt);
198+
199+
if (error == GIT_EBUFS) {
200+
error = 0;
201+
giterr_clear();
202+
}
203+
204+
return error;
187205
}
188206

189207
static void find_similar__hashsig_free(void *sig, void *payload)
@@ -414,6 +432,10 @@ static int similarity_measure(
414432
return -1;
415433
if (!cache[b_idx] && similarity_calc(diff, opts, b_idx, cache) < 0)
416434
return -1;
435+
436+
/* some metrics may not wish to process this file (too big / too small) */
437+
if (!cache[a_idx] || !cache[b_idx])
438+
return 0;
417439

418440
/* compare signatures */
419441
if (opts->metric->similarity(

tests-clar/diff/rename.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,39 @@ void test_diff_rename__not_exact_match(void)
352352
git_tree_free(new_tree);
353353
}
354354

355+
void test_diff_rename__handles_small_files(void)
356+
{
357+
const char *tree_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
358+
git_index *index;
359+
git_tree *tree;
360+
git_diff_list *diff;
361+
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
362+
git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
363+
364+
cl_git_pass(git_repository_index(&index, g_repo));
365+
366+
tree = resolve_commit_oid_to_tree(g_repo, tree_sha);
367+
368+
cl_git_rewritefile("renames/songof7cities.txt", "single line\n");
369+
cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
370+
371+
cl_git_rewritefile("renames/untimely.txt", "untimely\n");
372+
cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
373+
374+
/* Tests that we can invoke find_similar on small files
375+
* and that the GIT_EBUFS (too small) error code is not
376+
* propagated to the caller.
377+
*/
378+
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
379+
380+
opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES | GIT_DIFF_FIND_AND_BREAK_REWRITES;
381+
cl_git_pass(git_diff_find_similar(diff, &opts));
382+
383+
git_diff_list_free(diff);
384+
git_tree_free(tree);
385+
git_index_free(index);
386+
}
387+
355388
void test_diff_rename__working_directory_changes(void)
356389
{
357390
/* let's rewrite some files in the working directory on demand */

0 commit comments

Comments
 (0)