/*
 *
 * Copyright (C) 2005 Junio C Hamano
 */
#include "cache.h"
#include "diff.h"
#include "diffcore.h"
#include "object-store.h"
#include "hashmap.h"
#include "progress.h"
#include "promisor-remote.h"
#include "strmap.h"

/* Table of rename/copy destinations */

static struct diff_rename_dst {
	struct diff_filepair *p;
	struct diff_filespec *filespec_to_free;
	int is_rename; /* false -> just a create; true -> rename or copy */
} *rename_dst;
static int rename_dst_nr, rename_dst_alloc;
/* Mapping from break source pathname to break destination index */
static struct strintmap *break_idx = NULL;

static struct diff_rename_dst *locate_rename_dst(struct diff_filepair *p)
{
	/* Lookup by p->ONE->path */
	int idx = break_idx ? strintmap_get(break_idx, p->one->path) : -1;
	return (idx == -1) ? NULL : &rename_dst[idx];
}

/*
 * Returns 0 on success, -1 if we found a duplicate.
 */
static int add_rename_dst(struct diff_filepair *p)
{
	ALLOC_GROW(rename_dst, rename_dst_nr + 1, rename_dst_alloc);
	rename_dst[rename_dst_nr].p = p;
	rename_dst[rename_dst_nr].filespec_to_free = NULL;
	rename_dst[rename_dst_nr].is_rename = 0;
	rename_dst_nr++;
	return 0;
}

/* Table of rename/copy src files */
static struct diff_rename_src {
	struct diff_filepair *p;
	unsigned short score; /* to remember the break score */
} *rename_src;
static int rename_src_nr, rename_src_alloc;

static void register_rename_src(struct diff_filepair *p)
{
	if (p->broken_pair) {
		if (!break_idx) {
			break_idx = xmalloc(sizeof(*break_idx));
			strintmap_init_with_options(break_idx, -1, NULL, 0);
		}
		strintmap_set(break_idx, p->one->path, rename_dst_nr);
	}

	ALLOC_GROW(rename_src, rename_src_nr + 1, rename_src_alloc);
	rename_src[rename_src_nr].p = p;
	rename_src[rename_src_nr].score = p->score;
	rename_src_nr++;
}

static int basename_same(struct diff_filespec *src, struct diff_filespec *dst)
{
	int src_len = strlen(src->path), dst_len = strlen(dst->path);
	while (src_len && dst_len) {
		char c1 = src->path[--src_len];
		char c2 = dst->path[--dst_len];
		if (c1 != c2)
			return 0;
		if (c1 == '/')
			return 1;
	}
	return (!src_len || src->path[src_len - 1] == '/') &&
		(!dst_len || dst->path[dst_len - 1] == '/');
}

struct diff_score {
	int src; /* index in rename_src */
	int dst; /* index in rename_dst */
	unsigned short score;
	short name_score;
};

struct inexact_prefetch_options {
	struct repository *repo;
	int skip_unmodified;
};
static void inexact_prefetch(void *prefetch_options)
{
	struct inexact_prefetch_options *options = prefetch_options;
	int i;
	struct oid_array to_fetch = OID_ARRAY_INIT;

	for (i = 0; i < rename_dst_nr; i++) {
		if (rename_dst[i].p->renamed_pair)
			/*
			 * The loop in diffcore_rename() will not need these
			 * blobs, so skip prefetching.
			 */
			continue; /* already found exact match */
		diff_add_if_missing(options->repo, &to_fetch,
				    rename_dst[i].p->two);
	}
	for (i = 0; i < rename_src_nr; i++) {
		if (options->skip_unmodified &&
		    diff_unmodified_pair(rename_src[i].p))
			/*
			 * The loop in diffcore_rename() will not need these
			 * blobs, so skip prefetching.
			 */
			continue;
		diff_add_if_missing(options->repo, &to_fetch,
				    rename_src[i].p->one);
	}
	promisor_remote_get_direct(options->repo, to_fetch.oid, to_fetch.nr);
	oid_array_clear(&to_fetch);
}

static int estimate_similarity(struct repository *r,
			       struct diff_filespec *src,
			       struct diff_filespec *dst,
			       int minimum_score,
			       struct diff_populate_filespec_options *dpf_opt)
{
	/* src points at a file that existed in the original tree (or
	 * optionally a file in the destination tree) and dst points
	 * at a newly created file.  They may be quite similar, in which
	 * case we want to say src is renamed to dst or src is copied into
	 * dst, and then some edit has been applied to dst.
	 *
	 * Compare them and return how similar they are, representing
	 * the score as an integer between 0 and MAX_SCORE.
	 *
	 * When there is an exact match, it is considered a better
	 * match than anything else; the destination does not even
	 * call into this function in that case.
	 */
	unsigned long max_size, delta_size, base_size, src_copied, literal_added;
	int score;

	/* We deal only with regular files.  Symlink renames are handled
	 * only when they are exact matches --- in other words, no edits
	 * after renaming.
	 */
	if (!S_ISREG(src->mode) || !S_ISREG(dst->mode))
		return 0;

	/*
	 * Need to check that source and destination sizes are
	 * filled in before comparing them.
	 *
	 * If we already have "cnt_data" filled in, we know it's
	 * all good (avoid checking the size for zero, as that
	 * is a possible size - we really should have a flag to
	 * say whether the size is valid or not!)
	 */
	dpf_opt->check_size_only = 1;

	if (!src->cnt_data &&
	    diff_populate_filespec(r, src, dpf_opt))
		return 0;
	if (!dst->cnt_data &&
	    diff_populate_filespec(r, dst, dpf_opt))
		return 0;

	max_size = ((src->size > dst->size) ? src->size : dst->size);
	base_size = ((src->size < dst->size) ? src->size : dst->size);
	delta_size = max_size - base_size;

	/* We would not consider edits that change the file size so
	 * drastically.  delta_size must be smaller than
	 * (MAX_SCORE-minimum_score)/MAX_SCORE * min(src->size, dst->size).
	 *
	 * Note that base_size == 0 case is handled here already
	 * and the final score computation below would not have a
	 * divide-by-zero issue.
	 */
	if (max_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
		return 0;

	dpf_opt->check_size_only = 0;

	if (!src->cnt_data && diff_populate_filespec(r, src, dpf_opt))
		return 0;
	if (!dst->cnt_data && diff_populate_filespec(r, dst, dpf_opt))
		return 0;

	if (diffcore_count_changes(r, src, dst,
				   &src->cnt_data, &dst->cnt_data,
				   &src_copied, &literal_added))
		return 0;

	/* How similar are they?
	 * what percentage of material in dst are from source?
	 */
	if (!dst->size)
		score = 0; /* should not happen */
	else
		score = (int)(src_copied * MAX_SCORE / max_size);
	return score;
}

static void record_rename_pair(int dst_index, int src_index, int score)
{
	struct diff_filepair *src = rename_src[src_index].p;
	struct diff_filepair *dst = rename_dst[dst_index].p;

	if (dst->renamed_pair)
		die("internal error: dst already matched.");

	src->one->rename_used++;
	src->one->count++;

	rename_dst[dst_index].filespec_to_free = dst->one;
	rename_dst[dst_index].is_rename = 1;

	dst->one = src->one;
	dst->renamed_pair = 1;
	if (!strcmp(dst->one->path, dst->two->path))
		dst->score = rename_src[src_index].score;
	else
		dst->score = score;
}

/*
 * We sort the rename similarity matrix with the score, in descending
 * order (the most similar first).
 */
static int score_compare(const void *a_, const void *b_)
{
	const struct diff_score *a = a_, *b = b_;

	/* sink the unused ones to the bottom */
	if (a->dst < 0)
		return (0 <= b->dst);
	else if (b->dst < 0)
		return -1;

	if (a->score == b->score)
		return b->name_score - a->name_score;

	return b->score - a->score;
}

struct file_similarity {
	struct hashmap_entry entry;
	int index;
	struct diff_filespec *filespec;
};

static unsigned int hash_filespec(struct repository *r,
				  struct diff_filespec *filespec)
{
	if (!filespec->oid_valid) {
		if (diff_populate_filespec(r, filespec, NULL))
			return 0;
		hash_object_file(r->hash_algo, filespec->data, filespec->size,
				 OBJ_BLOB, &filespec->oid);
	}
	return oidhash(&filespec->oid);
}

static int find_identical_files(struct hashmap *srcs,
				int dst_index,
				struct diff_options *options)
{
	int renames = 0;
	struct diff_filespec *target = rename_dst[dst_index].p->two;
	struct file_similarity *p, *best = NULL;
	int i = 100, best_score = -1;
	unsigned int hash = hash_filespec(options->repo, target);

	/*
	 * Find the best source match for specified destination.
	 */
	p = hashmap_get_entry_from_hash(srcs, hash, NULL,
					struct file_similarity, entry);
	hashmap_for_each_entry_from(srcs, p, entry) {
		int score;
		struct diff_filespec *source = p->filespec;

		/* False hash collision? */
		if (!oideq(&source->oid, &target->oid))
			continue;
		/* Non-regular files? If so, the modes must match! */
		if (!S_ISREG(source->mode) || !S_ISREG(target->mode)) {
			if (source->mode != target->mode)
				continue;
		}
		/* Give higher scores to sources that haven't been used already */
		score = !source->rename_used;
		if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY)
			continue;
		score += basename_same(source, target);
		if (score > best_score) {
			best = p;
			best_score = score;
			if (score == 2)
				break;
		}

		/* Too many identical alternatives? Pick one */
		if (!--i)
			break;
	}
	if (best) {
		record_rename_pair(dst_index, best->index, MAX_SCORE);
		renames++;
	}
	return renames;
}

static void insert_file_table(struct repository *r,
			      struct mem_pool *pool,
			      struct hashmap *table, int index,
			      struct diff_filespec *filespec)
{
	struct file_similarity *entry = mem_pool_alloc(pool, sizeof(*entry));

	entry->index = index;
	entry->filespec = filespec;

	hashmap_entry_init(&entry->entry, hash_filespec(r, filespec));
	hashmap_add(table, &entry->entry);
}

/*
 * Find exact renames first.
 *
 * The first round matches up the up-to-date entries,
 * and then during the second round we try to match
 * cache-dirty entries as well.
 */
static int find_exact_renames(struct diff_options *options,
			      struct mem_pool *pool)
{
	int i, renames = 0;
	struct hashmap file_table;

	/* Add all sources to the hash table in reverse order, because
	 * later on they will be retrieved in LIFO order.
	 */
	hashmap_init(&file_table, NULL, NULL, rename_src_nr);
	for (i = rename_src_nr-1; i >= 0; i--)
		insert_file_table(options->repo, pool,
				  &file_table, i,
				  rename_src[i].p->one);

	/* Walk the destinations and find best source match */
	for (i = 0; i < rename_dst_nr; i++)
		renames += find_identical_files(&file_table, i, options);

	/* Free the hash data structure (entries will be freed with the pool) */
	hashmap_clear(&file_table);

	return renames;
}

struct dir_rename_info {
	struct strintmap idx_map;
	struct strmap dir_rename_guess;
	struct strmap *dir_rename_count;
	struct strintmap *relevant_source_dirs;
	unsigned setup;
};

static char *get_dirname(const char *filename)
{
	char *slash = strrchr(filename, '/');
	return slash ? xstrndup(filename, slash - filename) : xstrdup("");
}

static void dirname_munge(char *filename)
{
	char *slash = strrchr(filename, '/');
	if (!slash)
		slash = filename;
	*slash = '\0';
}

static const char *get_highest_rename_path(struct strintmap *counts)
{
	int highest_count = 0;
	const char *highest_destination_dir = NULL;
	struct hashmap_iter iter;
	struct strmap_entry *entry;

	strintmap_for_each_entry(counts, &iter, entry) {
		const char *destination_dir = entry->key;
		intptr_t count = (intptr_t)entry->value;
		if (count > highest_count) {
			highest_count = count;
			highest_destination_dir = destination_dir;
		}
	}
	return highest_destination_dir;
}

static char *UNKNOWN_DIR = "/";  /* placeholder -- short, illegal directory */

static int dir_rename_already_determinable(struct strintmap *counts)
{
	struct hashmap_iter iter;
	struct strmap_entry *entry;
	int first = 0, second = 0, unknown = 0;
	strintmap_for_each_entry(counts, &iter, entry) {
		const char *destination_dir = entry->key;
		intptr_t count = (intptr_t)entry->value;
		if (!strcmp(destination_dir, UNKNOWN_DIR)) {
			unknown = count;
		} else if (count >= first) {
			second = first;
			first = count;
		} else if (count >= second) {
			second = count;
		}
	}
	return first > second + unknown;
}

static void increment_count(struct dir_rename_info *info,
			    char *old_dir,
			    char *new_dir)
{
	struct strintmap *counts;
	struct strmap_entry *e;

	/* Get the {new_dirs -> counts} mapping using old_dir */
	e = strmap_get_entry(info->dir_rename_count, old_dir);
	if (e) {
		counts = e->value;
	} else {
		counts = xmalloc(sizeof(*counts));
		strintmap_init_with_options(counts, 0, NULL, 1);
		strmap_put(info->dir_rename_count, old_dir, counts);
	}

	/* Increment the count for new_dir */
	strintmap_incr(counts, new_dir, 1);
}

static void update_dir_rename_counts(struct dir_rename_info *info,
				     struct strintmap *dirs_removed,
				     const char *oldname,
				     const char *newname)
{
	char *old_dir;
	char *new_dir;
	const char new_dir_first_char = newname[0];
	int first_time_in_loop = 1;

	if (!info->setup)
		/*
		 * info->setup is 0 here in two cases: (1) all auxiliary
		 * vars (like dirs_removed) were NULL so
		 * initialize_dir_rename_info() returned early, or (2)
		 * either break detection or copy detection are active so
		 * that we never called initialize_dir_rename_info().  In
		 * the former case, we don't have enough info to know if
		 * directories were renamed (because dirs_removed lets us
		 * know about a necessary prerequisite, namely if they were
		 * removed), and in the latter, we don't care about
		 * directory renames or find_basename_matches.
		 *
		 * This matters because both basename and inexact matching
		 * will also call update_dir_rename_counts().  In either of
		 * the above two cases info->dir_rename_counts will not
		 * have been properly initialized which prevents us from
		 * updating it, but in these two cases we don't care about
		 * dir_rename_counts anyway, so we can just exit early.
		 */
		return;


	old_dir = xstrdup(oldname);
	new_dir = xstrdup(newname);

	while (1) {
		int drd_flag = NOT_RELEVANT;

		/* Get old_dir, skip if its directory isn't relevant. */
		dirname_munge(old_dir);
		if (info->relevant_source_dirs &&
		    !strintmap_contains(info->relevant_source_dirs, old_dir))
			break;

		/* Get new_dir */
		dirname_munge(new_dir);

		/*
		 * When renaming
		 *   "a/b/c/d/e/foo.c" -> "a/b/some/thing/else/e/foo.c"
		 * then this suggests that both
		 *   a/b/c/d/e/ => a/b/some/thing/else/e/
		 *   a/b/c/d/   => a/b/some/thing/else/
		 * so we want to increment counters for both.  We do NOT,
		 * however, also want to suggest that there was the following
		 * rename:
		 *   a/b/c/ => a/b/some/thing/
		 * so we need to quit at that point.
		 *
		 * Note the when first_time_in_loop, we only strip off the
		 * basename, and we don't care if that's different.
		 */
		if (!first_time_in_loop) {
			char *old_sub_dir = strchr(old_dir, '\0')+1;
			char *new_sub_dir = strchr(new_dir, '\0')+1;
			if (!*new_dir) {
				/*
				 * Special case when renaming to root directory,
				 * i.e. when new_dir == "".  In this case, we had
				 * something like
				 *    a/b/subdir => subdir
				 * and so dirname_munge() sets things up so that
				 *    old_dir = "a/b\0subdir\0"
				 *    new_dir = "\0ubdir\0"
				 * We didn't have a '/' to overwrite a '\0' onto
				 * in new_dir, so we have to compare differently.
				 */
				if (new_dir_first_char != old_sub_dir[0] ||
				    strcmp(old_sub_dir+1, new_sub_dir))
					break;
			} else {
				if (strcmp(old_sub_dir, new_sub_dir))
					break;
			}
		}

		/*
		 * Above we suggested that we'd keep recording renames for
		 * all ancestor directories where the trailing directories
		 * matched, i.e. for
		 *   "a/b/c/d/e/foo.c" -> "a/b/some/thing/else/e/foo.c"
		 * we'd increment rename counts for each of
		 *   a/b/c/d/e/ => a/b/some/thing/else/e/
		 *   a/b/c/d/   => a/b/some/thing/else/
		 * However, we only need the rename counts for directories
		 * in dirs_removed whose value is RELEVANT_FOR_SELF.
		 * However, we add one special case of also recording it for
		 * first_time_in_loop because find_basename_matches() can
		 * use that as a hint to find a good pairing.
		 */
		if (dirs_removed)
			drd_flag = strintmap_get(dirs_removed, old_dir);
		if (drd_flag == RELEVANT_FOR_SELF || first_time_in_loop)
			increment_count(info, old_dir, new_dir);

		first_time_in_loop = 0;
		if (drd_flag == NOT_RELEVANT)
			break;
		/* If we hit toplevel directory ("") for old or new dir, quit */
		if (!*old_dir || !*new_dir)
			break;
	}

	/* Free resources we don't need anymore */
	free(old_dir);
	free(new_dir);
}

static void initialize_dir_rename_info(struct dir_rename_info *info,
				       struct strintmap *relevant_sources,
				       struct strintmap *dirs_removed,
				       struct strmap *dir_rename_count,
				       struct strmap *cached_pairs)
{
	struct hashmap_iter iter;
	struct strmap_entry *entry;
	int i;

	if (!dirs_removed && !relevant_sources) {
		info->setup = 0;
		return;
	}
	info->setup = 1;

	info->dir_rename_count = dir_rename_count;
	if (!info->dir_rename_count) {
		info->dir_rename_count = xmalloc(sizeof(*dir_rename_count));
		strmap_init(info->dir_rename_count);
	}
	strintmap_init_with_options(&info->idx_map, -1, NULL, 0);
	strmap_init_with_options(&info->dir_rename_guess, NULL, 0);

	/* Setup info->relevant_source_dirs */
	info->relevant_source_dirs = NULL;
	if (dirs_removed || !relevant_sources) {
		info->relevant_source_dirs = dirs_removed; /* might be NULL */
	} else {
		info->relevant_source_dirs = xmalloc(sizeof(struct strintmap));
		strintmap_init(info->relevant_source_dirs, 0 /* unused */);
		strintmap_for_each_entry(relevant_sources, &iter, entry) {
			char *dirname = get_dirname(entry->key);
			if (!dirs_removed ||
			    strintmap_contains(dirs_removed, dirname))
				strintmap_set(info->relevant_source_dirs,
					      dirname, 0 /* value irrelevant */);
			free(dirname);
		}
	}

	/*
	 * Loop setting up both info->idx_map, and doing setup of
	 * info->dir_rename_count.
	 */
	for (i = 0; i < rename_dst_nr; ++i) {
		/*
		 * For non-renamed files, make idx_map contain mapping of
		 *   filename -> index (index within rename_dst, that is)
		 */
		if (!rename_dst[i].is_rename) {
			char *filename = rename_dst[i].p->two->path;
			strintmap_set(&info->idx_map, filename, i);
			continue;
		}

		/*
		 * For everything else (i.e. renamed files), make
		 * dir_rename_count contain a map of a map:
		 *   old_directory -> {new_directory -> count}
		 * In other words, for every pair look at the directories for
		 * the old filename and the new filename and count how many
		 * times that pairing occurs.
		 */
		update_dir_rename_counts(info, dirs_removed,
					 rename_dst[i].p->one->path,
					 rename_dst[i].p->two->path);
	}

	/* Add cached_pairs to counts */
	strmap_for_each_entry(cached_pairs, &iter, entry) {
		const char *old_name = entry->key;
		const char *new_name = entry->value;
		if (!new_name)
			/* known delete; ignore it */
			continue;

		update_dir_rename_counts(info, dirs_removed, old_name, new_name);
	}

	/*
	 * Now we collapse
	 *    dir_rename_count: old_directory -> {new_directory -> count}
	 * down to
	 *    dir_rename_guess: old_directory -> best_new_directory
	 * where best_new_directory is the one with the highest count.
	 */
	strmap_for_each_entry(info->dir_rename_count, &iter, entry) {
		/* entry->key is source_dir */
		struct strintmap *counts = entry->value;
		char *best_newdir;

		best_newdir = xstrdup(get_highest_rename_path(counts));
		strmap_put(&info->dir_rename_guess, entry->key,
			   best_newdir);
	}
}

void partial_clear_dir_rename_count(struct strmap *dir_rename_count)
{
	struct hashmap_iter iter;
	struct strmap_entry *entry;

	strmap_for_each_entry(dir_rename_count, &iter, entry) {
		struct strintmap *counts = entry->value;
		strintmap_clear(counts);
	}
	strmap_partial_clear(dir_rename_count, 1);
}

static void cleanup_dir_rename_info(struct dir_rename_info *info,
				    struct strintmap *dirs_removed,
				    int keep_dir_rename_count)
{
	struct hashmap_iter iter;
	struct strmap_entry *entry;
	struct string_list to_remove = STRING_LIST_INIT_NODUP;
	int i;

	if (!info->setup)
		return;

	/* idx_map */
	strintmap_clear(&info->idx_map);

	/* dir_rename_guess */
	strmap_clear(&info->dir_rename_guess, 1);

	/* relevant_source_dirs */
	if (info->relevant_source_dirs &&
	    info->relevant_source_dirs != dirs_removed) {
		strintmap_clear(info->relevant_source_dirs);
		FREE_AND_NULL(info->relevant_source_dirs);
	}

	/* dir_rename_count */
	if (!keep_dir_rename_count) {
		partial_clear_dir_rename_count(info->dir_rename_count);
		strmap_clear(info->dir_rename_count, 1);
		FREE_AND_NULL(info->dir_rename_count);
		return;
	}

	/*
	 * Although dir_rename_count was passed in
	 * diffcore_rename_extended() and we want to keep it around and
	 * return it to that caller, we first want to remove any counts in
	 * the maps associated with UNKNOWN_DIR entries and any data
	 * associated with directories that weren't renamed.
	 */
	strmap_for_each_entry(info->dir_rename_count, &iter, entry) {
		const char *source_dir = entry->key;
		struct strintmap *counts = entry->value;

		if (!strintmap_get(dirs_removed, source_dir)) {
			string_list_append(&to_remove, source_dir);
			strintmap_clear(counts);
			continue;
		}

		if (strintmap_contains(counts, UNKNOWN_DIR))
			strintmap_remove(counts, UNKNOWN_DIR);
	}
	for (i = 0; i < to_remove.nr; ++i)
		strmap_remove(info->dir_rename_count,
			      to_remove.items[i].string, 1);
	string_list_clear(&to_remove, 0);
}

static const char *get_basename(const char *filename)
{
	/*
	 * gitbasename() has to worry about special drives, multiple
	 * directory separator characters, trailing slashes, NULL or
	 * empty strings, etc.  We only work on filenames as stored in
	 * git, and thus get to ignore all those complications.
	 */
	const char *base = strrchr(filename, '/');
	return base ? base + 1 : filename;
}

static int idx_possible_rename(char *filename, struct dir_rename_info *info)
{
	/*
	 * Our comparison of files with the same basename (see
	 * find_basename_matches() below), is only helpful when after exact
	 * rename detection we have exactly one file with a given basename
	 * among the rename sources and also only exactly one file with
	 * that basename among the rename destinations.  When we have
	 * multiple files with the same basename in either set, we do not
	 * know which to compare against.  However, there are some
	 * filenames that occur in large numbers (particularly
	 * build-related filenames such as 'Makefile', '.gitignore', or
	 * 'build.gradle' that potentially exist within every single
	 * subdirectory), and for performance we want to be able to quickly
	 * find renames for these files too.
	 *
	 * The reason basename comparisons are a useful heuristic was that it
	 * is common for people to move files across directories while keeping
	 * their filename the same.  If we had a way of determining or even
	 * making a good educated guess about which directory these non-unique
	 * basename files had moved the file to, we could check it.
	 * Luckily...
	 *
	 * When an entire directory is in fact renamed, we have two factors
	 * helping us out:
	 *   (a) the original directory disappeared giving us a hint
	 *       about when we can apply an extra heuristic.
	 *   (a) we often have several files within that directory and
	 *       subdirectories that are renamed without changes
	 * So, rules for a heuristic:
	 *   (0) If there basename matches are non-unique (the condition under
	 *       which this function is called) AND
	 *   (1) the directory in which the file was found has disappeared
	 *       (i.e. dirs_removed is non-NULL and has a relevant entry) THEN
	 *   (2) use exact renames of files within the directory to determine
	 *       where the directory is likely to have been renamed to.  IF
	 *       there is at least one exact rename from within that
	 *       directory, we can proceed.
	 *   (3) If there are multiple places the directory could have been
	 *       renamed to based on exact renames, ignore all but one of them.
	 *       Just use the destination with the most renames going to it.
	 *   (4) Check if applying that directory rename to the original file
	 *       would result in a destination filename that is in the
	 *       potential rename set.  If so, return the index of the
	 *       destination file (the index within rename_dst).
	 *   (5) Compare the original file and returned destination for
	 *       similarity, and if they are sufficiently similar, record the
	 *       rename.
	 *
	 * This function, idx_possible_rename(), is only responsible for (4).
	 * The conditions/steps in (1)-(3) are handled via setting up
	 * dir_rename_count and dir_rename_guess in
	 * initialize_dir_rename_info().  Steps (0) and (5) are handled by
	 * the caller of this function.
	 */
	char *old_dir, *new_dir;
	struct strbuf new_path = STRBUF_INIT;
	int idx;

	if (!info->setup)
		return -1;

	old_dir = get_dirname(filename);
	new_dir = strmap_get(&info->dir_rename_guess, old_dir);
	free(old_dir);
	if (!new_dir)
		return -1;

	strbuf_addstr(&new_path, new_dir);
	strbuf_addch(&new_path, '/');
	strbuf_addstr(&new_path, get_basename(filename));

	idx = strintmap_get(&info->idx_map, new_path.buf);
	strbuf_release(&new_path);
	return idx;
}

struct basename_prefetch_options {
	struct repository *repo;
	struct strintmap *relevant_sources;
	struct strintmap *sources;
	struct strintmap *dests;
	struct dir_rename_info *info;
};
static void basename_prefetch(void *prefetch_options)
{
	struct basename_prefetch_options *options = prefetch_options;
	struct strintmap *relevant_sources = options->relevant_sources;
	struct strintmap *sources = options->sources;
	struct strintmap *dests = options->dests;
	struct dir_rename_info *info = options->info;
	int i;
	struct oid_array to_fetch = OID_ARRAY_INIT;

	/*
	 * TODO: The following loops mirror the code/logic from
	 * find_basename_matches(), though not quite exactly.  Maybe
	 * abstract the iteration logic out somehow?
	 */
	for (i = 0; i < rename_src_nr; ++i) {
		char *filename = rename_src[i].p->one->path;
		const char *base = NULL;
		intptr_t src_index;
		intptr_t dst_index;

		/* Skip irrelevant sources */
		if (relevant_sources &&
		    !strintmap_contains(relevant_sources, filename))
			continue;

		/*
		 * If the basename is unique among remaining sources, then
		 * src_index will equal 'i' and we can attempt to match it
		 * to a unique basename in the destinations.  Otherwise,
		 * use directory rename heuristics, if possible.
		 */
		base = get_basename(filename);
		src_index = strintmap_get(sources, base);
		assert(src_index == -1 || src_index == i);

		if (strintmap_contains(dests, base)) {
			struct diff_filespec *one, *two;

			/* Find a matching destination, if possible */
			dst_index = strintmap_get(dests, base);
			if (src_index == -1 || dst_index == -1) {
				src_index = i;
				dst_index = idx_possible_rename(filename, info);
			}
			if (dst_index == -1)
				continue;

			/* Ignore this dest if already used in a rename */
			if (rename_dst[dst_index].is_rename)
				continue; /* already used previously */

			one = rename_src[src_index].p->one;
			two = rename_dst[dst_index].p->two;

			/* Add the pairs */
			diff_add_if_missing(options->repo, &to_fetch, two);
			diff_add_if_missing(options->repo, &to_fetch, one);
		}
	}

	promisor_remote_get_direct(options->repo, to_fetch.oid, to_fetch.nr);
	oid_array_clear(&to_fetch);
}

static int find_basename_matches(struct diff_options *options,
				 int minimum_score,
				 struct dir_rename_info *info,
				 struct strintmap *relevant_sources,
				 struct strintmap *dirs_removed)
{
	/*
	 * When I checked in early 2020, over 76% of file renames in linux
	 * just moved files to a different directory but kept the same
	 * basename.  gcc did that with over 64% of renames, gecko did it
	 * with over 79%, and WebKit did it with over 89%.
	 *
	 * Therefore we can bypass the normal exhaustive NxM matrix
	 * comparison of similarities between all potential rename sources
	 * and destinations by instead using file basename as a hint (i.e.
	 * the portion of the filename after the last '/'), checking for
	 * similarity between files with the same basename, and if we find
	 * a pair that are sufficiently similar, record the rename pair and
	 * exclude those two from the NxM matrix.
	 *
	 * This *might* cause us to find a less than optimal pairing (if
	 * there is another file that we are even more similar to but has a
	 * different basename).  Given the huge performance advantage
	 * basename matching provides, and given the frequency with which
	 * people use the same basename in real world projects, that's a
	 * trade-off we are willing to accept when doing just rename
	 * detection.
	 *
	 * If someone wants copy detection that implies they are willing to
	 * spend more cycles to find similarities between files, so it may
	 * be less likely that this heuristic is wanted.  If someone is
	 * doing break detection, that means they do not want filename
	 * similarity to imply any form of content similiarity, and thus
	 * this heuristic would definitely be incompatible.
	 */

	int i, renames = 0;
	struct strintmap sources;
	struct strintmap dests;
	struct diff_populate_filespec_options dpf_options = {
		.check_binary = 0,
		.missing_object_cb = NULL,
		.missing_object_data = NULL
	};
	struct basename_prefetch_options prefetch_options = {
		.repo = options->repo,
		.relevant_sources = relevant_sources,
		.sources = &sources,
		.dests = &dests,
		.info = info
	};

	/*
	 * Create maps of basename -> fullname(s) for remaining sources and
	 * dests.
	 */
	strintmap_init_with_options(&sources, -1, NULL, 0);
	strintmap_init_with_options(&dests, -1, NULL, 0);
	for (i = 0; i < rename_src_nr; ++i) {
		char *filename = rename_src[i].p->one->path;
		const char *base;

		/* exact renames removed in remove_unneeded_paths_from_src() */
		assert(!rename_src[i].p->one->rename_used);

		/* Record index within rename_src (i) if basename is unique */
		base = get_basename(filename);
		if (strintmap_contains(&sources, base))
			strintmap_set(&sources, base, -1);
		else
			strintmap_set(&sources, base, i);
	}
	for (i = 0; i < rename_dst_nr; ++i) {
		char *filename = rename_dst[i].p->two->path;
		const char *base;

		if (rename_dst[i].is_rename)
			continue; /* involved in exact match already. */

		/* Record index within rename_dst (i) if basename is unique */
		base = get_basename(filename);
		if (strintmap_contains(&dests, base))
			strintmap_set(&dests, base, -1);
		else
			strintmap_set(&dests, base, i);
	}

	if (options->repo == the_repository && has_promisor_remote()) {
		dpf_options.missing_object_cb = basename_prefetch;
		dpf_options.missing_object_data = &prefetch_options;
	}

	/* Now look for basename matchups and do similarity estimation */
	for (i = 0; i < rename_src_nr; ++i) {
		char *filename = rename_src[i].p->one->path;
		const char *base = NULL;
		intptr_t src_index;
		intptr_t dst_index;

		/* Skip irrelevant sources */
		if (relevant_sources &&
		    !strintmap_contains(relevant_sources, filename))
			continue;

		/*
		 * If the basename is unique among remaining sources, then
		 * src_index will equal 'i' and we can attempt to match it
		 * to a unique basename in the destinations.  Otherwise,
		 * use directory rename heuristics, if possible.
		 */
		base = get_basename(filename);
		src_index = strintmap_get(&sources, base);
		assert(src_index == -1 || src_index == i);

		if (strintmap_contains(&dests, base)) {
			struct diff_filespec *one, *two;
			int score;

			/* Find a matching destination, if possible */
			dst_index = strintmap_get(&dests, base);
			if (src_index == -1 || dst_index == -1) {
				src_index = i;
				dst_index = idx_possible_rename(filename, info);
			}
			if (dst_index == -1)
				continue;

			/* Ignore this dest if already used in a rename */
			if (rename_dst[dst_index].is_rename)
				continue; /* already used previously */

			/* Estimate the similarity */
			one = rename_src[src_index].p->one;
			two = rename_dst[dst_index].p->two;
			score = estimate_similarity(options->repo, one, two,
						    minimum_score, &dpf_options);

			/* If sufficiently similar, record as rename pair */
			if (score < minimum_score)
				continue;
			record_rename_pair(dst_index, src_index, score);
			renames++;
			update_dir_rename_counts(info, dirs_removed,
						 one->path, two->path);

			/*
			 * Found a rename so don't need text anymore; if we
			 * didn't find a rename, the filespec_blob would get
			 * re-used when doing the matrix of comparisons.
			 */
			diff_free_filespec_blob(one);
			diff_free_filespec_blob(two);
		}
	}

	strintmap_clear(&sources);
	strintmap_clear(&dests);

	return renames;
}

#define NUM_CANDIDATE_PER_DST 4
static void record_if_better(struct diff_score m[], struct diff_score *o)
{
	int i, worst;

	/* find the worst one */
	worst = 0;
	for (i = 1; i < NUM_CANDIDATE_PER_DST; i++)
		if (score_compare(&m[i], &m[worst]) > 0)
			worst = i;

	/* is it better than the worst one? */
	if (score_compare(&m[worst], o) > 0)
		m[worst] = *o;
}

/*
 * Returns:
 * 0 if we are under the limit;
 * 1 if we need to disable inexact rename detection;
 * 2 if we would be under the limit if we were given -C instead of -C -C.
 */
static int too_many_rename_candidates(int num_destinations, int num_sources,
				      struct diff_options *options)
{
	int rename_limit = options->rename_limit;
	int i, limited_sources;

	options->needed_rename_limit = 0;

	/*
	 * This basically does a test for the rename matrix not
	 * growing larger than a "rename_limit" square matrix, ie:
	 *
	 *    num_destinations * num_sources > rename_limit * rename_limit
	 *
	 * We use st_mult() to check overflow conditions; in the
	 * exceptional circumstance that size_t isn't large enough to hold
	 * the multiplication, the system won't be able to allocate enough
	 * memory for the matrix anyway.
	 */
	if (rename_limit <= 0)
		return 0; /* treat as unlimited */
	if (st_mult(num_destinations, num_sources)
	    <= st_mult(rename_limit, rename_limit))
		return 0;

	options->needed_rename_limit =
		num_sources > num_destinations ? num_sources : num_destinations;

	/* Are we running under -C -C? */
	if (!options->flags.find_copies_harder)
		return 1;

	/* Would we bust the limit if we were running under -C? */
	for (limited_sources = i = 0; i < num_sources; i++) {
		if (diff_unmodified_pair(rename_src[i].p))
			continue;
		limited_sources++;
	}
	if (st_mult(num_destinations, limited_sources)
	    <= st_mult(rename_limit, rename_limit))
		return 2;
	return 1;
}

static int find_renames(struct diff_score *mx,
			int dst_cnt,
			int minimum_score,
			int copies,
			struct dir_rename_info *info,
			struct strintmap *dirs_removed)
{
	int count = 0, i;

	for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
		struct diff_rename_dst *dst;

		if ((mx[i].dst < 0) ||
		    (mx[i].score < minimum_score))
			break; /* there is no more usable pair. */
		dst = &rename_dst[mx[i].dst];
		if (dst->is_rename)
			continue; /* already done, either exact or fuzzy. */
		if (!copies && rename_src[mx[i].src].p->one->rename_used)
			continue;
		record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
		count++;
		update_dir_rename_counts(info, dirs_removed,
					 rename_src[mx[i].src].p->one->path,
					 rename_dst[mx[i].dst].p->two->path);
	}
	return count;
}

static void remove_unneeded_paths_from_src(int detecting_copies,
					   struct strintmap *interesting)
{
	int i, new_num_src;

	if (detecting_copies && !interesting)
		return; /* nothing to remove */
	if (break_idx)
		return; /* culling incompatible with break detection */

	/*
	 * Note on reasons why we cull unneeded sources but not destinations:
	 *   1) Pairings are stored in rename_dst (not rename_src), which we
	 *      need to keep around.  So, we just can't cull rename_dst even
	 *      if we wanted to.  But doing so wouldn't help because...
	 *
	 *   2) There is a matrix pairwise comparison that follows the
	 *      "Performing inexact rename detection" progress message.
	 *      Iterating over the destinations is done in the outer loop,
	 *      hence we only iterate over each of those once and we can
	 *      easily skip the outer loop early if the destination isn't
	 *      relevant.  That's only one check per destination path to
	 *      skip.
	 *
	 *      By contrast, the sources are iterated in the inner loop; if
	 *      we check whether a source can be skipped, then we'll be
	 *      checking it N separate times, once for each destination.
	 *      We don't want to have to iterate over known-not-needed
	 *      sources N times each, so avoid that by removing the sources
	 *      from rename_src here.
	 */
	for (i = 0, new_num_src = 0; i < rename_src_nr; i++) {
		struct diff_filespec *one = rename_src[i].p->one;

		/*
		 * renames are stored in rename_dst, so if a rename has
		 * already been detected using this source, we can just
		 * remove the source knowing rename_dst has its info.
		 */
		if (!detecting_copies && one->rename_used)
			continue;

		/* If we don't care about the source path, skip it */
		if (interesting && !strintmap_contains(interesting, one->path))
			continue;

		if (new_num_src < i)
			memcpy(&rename_src[new_num_src], &rename_src[i],
			       sizeof(struct diff_rename_src));
		new_num_src++;
	}

	rename_src_nr = new_num_src;
}

static void handle_early_known_dir_renames(struct dir_rename_info *info,
					   struct strintmap *relevant_sources,
					   struct strintmap *dirs_removed)
{
	/*
	 * Directory renames are determined via an aggregate of all renames
	 * under them and using a "majority wins" rule.  The fact that
	 * "majority wins", though, means we don't need all the renames
	 * under the given directory, we only need enough to ensure we have
	 * a majority.
	 */

	int i, new_num_src;
	struct hashmap_iter iter;
	struct strmap_entry *entry;

	if (!dirs_removed || !relevant_sources)
		return; /* nothing to cull */
	if (break_idx)
		return; /* culling incompatbile with break detection */

	/*
	 * Supplement dir_rename_count with number of potential renames,
	 * marking all potential rename sources as mapping to UNKNOWN_DIR.
	 */
	for (i = 0; i < rename_src_nr; i++) {
		char *old_dir;
		struct diff_filespec *one = rename_src[i].p->one;

		/*
		 * sources that are part of a rename will have already been
		 * removed by a prior call to remove_unneeded_paths_from_src()
		 */
		assert(!one->rename_used);

		old_dir = get_dirname(one->path);
		while (*old_dir != '\0' &&
		       NOT_RELEVANT != strintmap_get(dirs_removed, old_dir)) {
			char *freeme = old_dir;

			increment_count(info, old_dir, UNKNOWN_DIR);
			old_dir = get_dirname(old_dir);

			/* Free resources we don't need anymore */
			free(freeme);
		}
		/*
		 * old_dir and new_dir free'd in increment_count, but
		 * get_dirname() gives us a new pointer we need to free for
		 * old_dir.  Also, if the loop runs 0 times we need old_dir
		 * to be freed.
		 */
		free(old_dir);
	}

	/*
	 * For any directory which we need a potential rename detected for
	 * (i.e. those marked as RELEVANT_FOR_SELF in dirs_removed), check
	 * whether we have enough renames to satisfy the "majority rules"
	 * requirement such that detecting any more renames of files under
	 * it won't change the result.  For any such directory, mark that
	 * we no longer need to detect a rename for it.  However, since we
	 * might need to still detect renames for an ancestor of that
	 * directory, use RELEVANT_FOR_ANCESTOR.
	 */
	strmap_for_each_entry(info->dir_rename_count, &iter, entry) {
		/* entry->key is source_dir */
		struct strintmap *counts = entry->value;

		if (strintmap_get(dirs_removed, entry->key) ==
		    RELEVANT_FOR_SELF &&
		    dir_rename_already_determinable(counts)) {
			strintmap_set(dirs_removed, entry->key,
				      RELEVANT_FOR_ANCESTOR);
		}
	}

	for (i = 0, new_num_src = 0; i < rename_src_nr; i++) {
		struct diff_filespec *one = rename_src[i].p->one;
		int val;

		val = strintmap_get(relevant_sources, one->path);

		/*
		 * sources that were not found in relevant_sources should
		 * have already been removed by a prior call to
		 * remove_unneeded_paths_from_src()
		 */
		assert(val != -1);

		if (val == RELEVANT_LOCATION) {
			int removable = 1;
			char *dir = get_dirname(one->path);
			while (1) {
				char *freeme = dir;
				int res = strintmap_get(dirs_removed, dir);

				/* Quit if not found or irrelevant */
				if (res == NOT_RELEVANT)
					break;
				/* If RELEVANT_FOR_SELF, can't remove */
				if (res == RELEVANT_FOR_SELF) {
					removable = 0;
					break;
				}
				/* Else continue searching upwards */
				assert(res == RELEVANT_FOR_ANCESTOR);
				dir = get_dirname(dir);
				free(freeme);
			}
			free(dir);
			if (removable) {
				strintmap_set(relevant_sources, one->path,
					      RELEVANT_NO_MORE);
				continue;
			}
		}

		if (new_num_src < i)
			memcpy(&rename_src[new_num_src], &rename_src[i],
			       sizeof(struct diff_rename_src));
		new_num_src++;
	}

	rename_src_nr = new_num_src;
}

static void free_filespec_data(struct diff_filespec *spec)
{
	if (!--spec->count)
		diff_free_filespec_data(spec);
}

static void pool_free_filespec(struct mem_pool *pool,
			       struct diff_filespec *spec)
{
	if (!pool) {
		free_filespec(spec);
		return;
	}

	/*
	 * Similar to free_filespec(), but only frees the data.  The spec
	 * itself was allocated in the pool and should not be individually
	 * freed.
	 */
	free_filespec_data(spec);
}

void pool_diff_free_filepair(struct mem_pool *pool,
			     struct diff_filepair *p)
{
	if (!pool) {
		diff_free_filepair(p);
		return;
	}

	/*
	 * Similar to diff_free_filepair() but only frees the data from the
	 * filespecs; not the filespecs or the filepair which were
	 * allocated from the pool.
	 */
	free_filespec_data(p->one);
	free_filespec_data(p->two);
}

void diffcore_rename_extended(struct diff_options *options,
			      struct mem_pool *pool,
			      struct strintmap *relevant_sources,
			      struct strintmap *dirs_removed,
			      struct strmap *dir_rename_count,
			      struct strmap *cached_pairs)
{
	int detect_rename = options->detect_rename;
	int minimum_score = options->rename_score;
	struct diff_queue_struct *q = &diff_queued_diff;
	struct diff_queue_struct outq;
	struct diff_score *mx;
	int i, j, rename_count, skip_unmodified = 0;
	int num_destinations, dst_cnt;
	int num_sources, want_copies;
	struct progress *progress = NULL;
	struct mem_pool local_pool;
	struct dir_rename_info info;
	struct diff_populate_filespec_options dpf_options = {
		.check_binary = 0,
		.missing_object_cb = NULL,
		.missing_object_data = NULL
	};
	struct inexact_prefetch_options prefetch_options = {
		.repo = options->repo
	};

	trace2_region_enter("diff", "setup", options->repo);
	info.setup = 0;
	assert(!dir_rename_count || strmap_empty(dir_rename_count));
	want_copies = (detect_rename == DIFF_DETECT_COPY);
	if (dirs_removed && (break_idx || want_copies))
		BUG("dirs_removed incompatible with break/copy detection");
	if (break_idx && relevant_sources)
		BUG("break detection incompatible with source specification");
	if (!minimum_score)
		minimum_score = DEFAULT_RENAME_SCORE;

	for (i = 0; i < q->nr; i++) {
		struct diff_filepair *p = q->queue[i];
		if (!DIFF_FILE_VALID(p->one)) {
			if (!DIFF_FILE_VALID(p->two))
				continue; /* unmerged */
			else if (options->single_follow &&
				 strcmp(options->single_follow, p->two->path))
				continue; /* not interested */
			else if (!options->flags.rename_empty &&
				 is_empty_blob_oid(&p->two->oid))
				continue;
			else if (add_rename_dst(p) < 0) {
				warning("skipping rename detection, detected"
					" duplicate destination '%s'",
					p->two->path);
				goto cleanup;
			}
		}
		else if (!options->flags.rename_empty &&
			 is_empty_blob_oid(&p->one->oid))
			continue;
		else if (!DIFF_PAIR_UNMERGED(p) && !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.
			 * So we increment the "rename_used" score
			 * by one, to indicate ourselves as a user
			 */
			if (p->broken_pair && !p->score)
				p->one->rename_used++;
			register_rename_src(p);
		}
		else if (want_copies) {
			/*
			 * Increment the "rename_used" score by
			 * one, to indicate ourselves as a user.
			 */
			p->one->rename_used++;
			register_rename_src(p);
		}
	}
	trace2_region_leave("diff", "setup", options->repo);
	if (rename_dst_nr == 0 || rename_src_nr == 0)
		goto cleanup; /* nothing to do */

	trace2_region_enter("diff", "exact renames", options->repo);
	mem_pool_init(&local_pool, 32*1024);
	/*
	 * We really want to cull the candidates list early
	 * with cheap tests in order to avoid doing deltas.
	 */
	rename_count = find_exact_renames(options, &local_pool);
	/*
	 * Discard local_pool immediately instead of at "cleanup:" in order
	 * to reduce maximum memory usage; inexact rename detection uses up
	 * a fair amount of memory, and mem_pools can too.
	 */
	mem_pool_discard(&local_pool, 0);
	trace2_region_leave("diff", "exact renames", options->repo);

	/* Did we only want exact renames? */
	if (minimum_score == MAX_SCORE)
		goto cleanup;

	num_sources = rename_src_nr;

	if (want_copies || break_idx) {
		/*
		 * Cull sources:
		 *   - remove ones corresponding to exact renames
		 *   - remove ones not found in relevant_sources
		 */
		trace2_region_enter("diff", "cull after exact", options->repo);
		remove_unneeded_paths_from_src(want_copies, relevant_sources);
		trace2_region_leave("diff", "cull after exact", options->repo);
	} else {
		/* Determine minimum score to match basenames */
		double factor = 0.5;
		char *basename_factor = getenv("GIT_BASENAME_FACTOR");
		int min_basename_score;

		if (basename_factor)
			factor = strtol(basename_factor, NULL, 10)/100.0;
		assert(factor >= 0.0 && factor <= 1.0);
		min_basename_score = minimum_score +
			(int)(factor * (MAX_SCORE - minimum_score));

		/*
		 * Cull sources:
		 *   - remove ones involved in renames (found via exact match)
		 */
		trace2_region_enter("diff", "cull after exact", options->repo);
		remove_unneeded_paths_from_src(want_copies, NULL);
		trace2_region_leave("diff", "cull after exact", options->repo);

		/* Preparation for basename-driven matching. */
		trace2_region_enter("diff", "dir rename setup", options->repo);
		initialize_dir_rename_info(&info, relevant_sources,
					   dirs_removed, dir_rename_count,
					   cached_pairs);
		trace2_region_leave("diff", "dir rename setup", options->repo);

		/* Utilize file basenames to quickly find renames. */
		trace2_region_enter("diff", "basename matches", options->repo);
		rename_count += find_basename_matches(options,
						      min_basename_score,
						      &info,
						      relevant_sources,
						      dirs_removed);
		trace2_region_leave("diff", "basename matches", options->repo);

		/*
		 * Cull sources, again:
		 *   - remove ones involved in renames (found via basenames)
		 *   - remove ones not found in relevant_sources
		 * and
		 *   - remove ones in relevant_sources which are needed only
		 *     for directory renames IF no ancestory directory
		 *     actually needs to know any more individual path
		 *     renames under them
		 */
		trace2_region_enter("diff", "cull basename", options->repo);
		remove_unneeded_paths_from_src(want_copies, relevant_sources);
		handle_early_known_dir_renames(&info, relevant_sources,
					       dirs_removed);
		trace2_region_leave("diff", "cull basename", options->repo);
	}

	/* Calculate how many rename destinations are left */
	num_destinations = (rename_dst_nr - rename_count);
	num_sources = rename_src_nr; /* rename_src_nr reflects lower number */

	/* All done? */
	if (!num_destinations || !num_sources)
		goto cleanup;

	switch (too_many_rename_candidates(num_destinations, num_sources,
					   options)) {
	case 1:
		goto cleanup;
	case 2:
		options->degraded_cc_to_c = 1;
		skip_unmodified = 1;
		break;
	default:
		break;
	}

	trace2_region_enter("diff", "inexact renames", options->repo);
	if (options->show_rename_progress) {
		progress = start_delayed_progress(
				_("Performing inexact rename detection"),
				(uint64_t)num_destinations * (uint64_t)num_sources);
	}

	/* Finish setting up dpf_options */
	prefetch_options.skip_unmodified = skip_unmodified;
	if (options->repo == the_repository && has_promisor_remote()) {
		dpf_options.missing_object_cb = inexact_prefetch;
		dpf_options.missing_object_data = &prefetch_options;
	}

	CALLOC_ARRAY(mx, st_mult(NUM_CANDIDATE_PER_DST, num_destinations));
	for (dst_cnt = i = 0; i < rename_dst_nr; i++) {
		struct diff_filespec *two = rename_dst[i].p->two;
		struct diff_score *m;

		if (rename_dst[i].is_rename)
			continue; /* exact or basename match already handled */

		m = &mx[dst_cnt * NUM_CANDIDATE_PER_DST];
		for (j = 0; j < NUM_CANDIDATE_PER_DST; j++)
			m[j].dst = -1;

		for (j = 0; j < rename_src_nr; j++) {
			struct diff_filespec *one = rename_src[j].p->one;
			struct diff_score this_src;

			assert(!one->rename_used || want_copies || break_idx);

			if (skip_unmodified &&
			    diff_unmodified_pair(rename_src[j].p))
				continue;

			this_src.score = estimate_similarity(options->repo,
							     one, two,
							     minimum_score,
							     &dpf_options);
			this_src.name_score = basename_same(one, two);
			this_src.dst = i;
			this_src.src = j;
			record_if_better(m, &this_src);
			/*
			 * Once we run estimate_similarity,
			 * We do not need the text anymore.
			 */
			diff_free_filespec_blob(one);
			diff_free_filespec_blob(two);
		}
		dst_cnt++;
		display_progress(progress,
				 (uint64_t)dst_cnt * (uint64_t)num_sources);
	}
	stop_progress(&progress);

	/* cost matrix sorted by most to least similar pair */
	STABLE_QSORT(mx, dst_cnt * NUM_CANDIDATE_PER_DST, score_compare);

	rename_count += find_renames(mx, dst_cnt, minimum_score, 0,
				     &info, dirs_removed);
	if (want_copies)
		rename_count += find_renames(mx, dst_cnt, minimum_score, 1,
					     &info, dirs_removed);
	free(mx);
	trace2_region_leave("diff", "inexact renames", options->repo);

 cleanup:
	/* At this point, we have found some renames and copies and they
	 * are recorded in rename_dst.  The original list is still in *q.
	 */
	trace2_region_enter("diff", "write back to queue", options->repo);
	DIFF_QUEUE_CLEAR(&outq);
	for (i = 0; i < q->nr; i++) {
		struct diff_filepair *p = q->queue[i];
		struct diff_filepair *pair_to_free = NULL;

		if (DIFF_PAIR_UNMERGED(p)) {
			diff_q(&outq, p);
		}
		else if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
			/* Creation */
			diff_q(&outq, p);
		}
		else if (DIFF_FILE_VALID(p->one) && !DIFF_FILE_VALID(p->two)) {
			/*
			 * Deletion
			 *
			 * We would output this delete record if:
			 *
			 * (1) this is a broken delete and the counterpart
			 *     broken create remains in the output; or
			 * (2) this is not a broken delete, and rename_dst
			 *     does not have a rename/copy to move p->one->path
			 *     out of existence.
			 *
			 * Otherwise, the counterpart broken create
			 * has been turned into a rename-edit; or
			 * delete did not have a matching create to
			 * begin with.
			 */
			if (DIFF_PAIR_BROKEN(p)) {
				/* broken delete */
				struct diff_rename_dst *dst = locate_rename_dst(p);
				if (!dst)
					BUG("tracking failed somehow; failed to find associated dst for broken pair");
				if (dst->is_rename)
					/* counterpart is now rename/copy */
					pair_to_free = p;
			}
			else {
				if (p->one->rename_used)
					/* this path remains */
					pair_to_free = p;
			}

			if (!pair_to_free)
				diff_q(&outq, p);
		}
		else if (!diff_unmodified_pair(p))
			/* all the usual ones need to be kept */
			diff_q(&outq, p);
		else
			/* no need to keep unmodified pairs */
			pair_to_free = p;

		if (pair_to_free)
			pool_diff_free_filepair(pool, pair_to_free);
	}
	diff_debug_queue("done copying original", &outq);

	free(q->queue);
	*q = outq;
	diff_debug_queue("done collapsing", q);

	for (i = 0; i < rename_dst_nr; i++)
		if (rename_dst[i].filespec_to_free)
			pool_free_filespec(pool, rename_dst[i].filespec_to_free);

	cleanup_dir_rename_info(&info, dirs_removed, dir_rename_count != NULL);
	FREE_AND_NULL(rename_dst);
	rename_dst_nr = rename_dst_alloc = 0;
	FREE_AND_NULL(rename_src);
	rename_src_nr = rename_src_alloc = 0;
	if (break_idx) {
		strintmap_clear(break_idx);
		FREE_AND_NULL(break_idx);
	}
	trace2_region_leave("diff", "write back to queue", options->repo);
	return;
}

void diffcore_rename(struct diff_options *options)
{
	diffcore_rename_extended(options, NULL, NULL, NULL, NULL, NULL);
}
