*/
void *delta;
unsigned long delta_size, base_size, src_copied, literal_added;
+ unsigned long delta_limit;
int score;
/* We deal only with regular files. Symlink renames are handled
if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
return 0; /* error but caught downstream */
+ delta_limit = base_size * (MAX_SCORE-minimum_score) / MAX_SCORE;
delta = diff_delta(src->data, src->size,
dst->data, dst->size,
- &delta_size);
+ &delta_size, delta_limit);
+ if (!delta)
+ /* If delta_limit is exceeded, we have too much differences */
+ return 0;
/* A delta that has a lot of literal additions would have
* big delta_size no matter what else it does.
continue; /* unmerged */
else
locate_rename_dst(p->two, 1);
- else if (!DIFF_FILE_VALID(p->two))
- register_rename_src(p->one, 0);
+ else if (!DIFF_FILE_VALID(p->two)) {
+ /* If the source is a broken "delete", and
+ * they did not really want to get broken,
+ * that means the source actually stays.
+ */
+ int stays = (p->broken_pair && !p->score);
+ register_rename_src(p->one, stays);
+ }
else if (detect_rename == DIFF_DETECT_COPY)
register_rename_src(p->one, 1);
}