#include "git-compat-util.h"
#include "refs.h"
#include "object-store-ll.h"
#include "cache-tree.h"
#include "mergesort.h"
#include "commit.h"
#include "convert.h"
#include "diff.h"
#include "diffcore.h"
#include "gettext.h"
#include "hex.h"
#include "path.h"
#include "read-cache.h"
#include "revision.h"
#include "setup.h"
#include "tag.h"
#include "trace2.h"
#include "blame.h"
#include "alloc.h"
#include "commit-slab.h"
#include "bloom.h"
#include "commit-graph.h"

define_commit_slab(blame_suspects, struct blame_origin *);
static struct blame_suspects blame_suspects;

struct blame_origin *get_blame_suspects(struct commit *commit)
{
	struct blame_origin **result;

	result = blame_suspects_peek(&blame_suspects, commit);

	return result ? *result : NULL;
}

static void set_blame_suspects(struct commit *commit, struct blame_origin *origin)
{
	*blame_suspects_at(&blame_suspects, commit) = origin;
}

void blame_origin_decref(struct blame_origin *o)
{
	if (o && --o->refcnt <= 0) {
		struct blame_origin *p, *l = NULL;
		if (o->previous)
			blame_origin_decref(o->previous);
		free(o->file.ptr);
		/* Should be present exactly once in commit chain */
		for (p = get_blame_suspects(o->commit); p; l = p, p = p->next) {
			if (p == o) {
				if (l)
					l->next = p->next;
				else
					set_blame_suspects(o->commit, p->next);
				free(o);
				return;
			}
		}
		die("internal error in blame_origin_decref");
	}
}

/*
 * Given a commit and a path in it, create a new origin structure.
 * The callers that add blame to the scoreboard should use
 * get_origin() to obtain shared, refcounted copy instead of calling
 * this function directly.
 */
static struct blame_origin *make_origin(struct commit *commit, const char *path)
{
	struct blame_origin *o;
	FLEX_ALLOC_STR(o, path, path);
	o->commit = commit;
	o->refcnt = 1;
	o->next = get_blame_suspects(commit);
	set_blame_suspects(commit, o);
	return o;
}

/*
 * Locate an existing origin or create a new one.
 * This moves the origin to front position in the commit util list.
 */
static struct blame_origin *get_origin(struct commit *commit, const char *path)
{
	struct blame_origin *o, *l;

	for (o = get_blame_suspects(commit), l = NULL; o; l = o, o = o->next) {
		if (!strcmp(o->path, path)) {
			/* bump to front */
			if (l) {
				l->next = o->next;
				o->next = get_blame_suspects(commit);
				set_blame_suspects(commit, o);
			}
			return blame_origin_incref(o);
		}
	}
	return make_origin(commit, path);
}



static void verify_working_tree_path(struct repository *r,
				     struct commit *work_tree, const char *path)
{
	struct commit_list *parents;
	int pos;

	for (parents = work_tree->parents; parents; parents = parents->next) {
		const struct object_id *commit_oid = &parents->item->object.oid;
		struct object_id blob_oid;
		unsigned short mode;

		if (!get_tree_entry(r, commit_oid, path, &blob_oid, &mode) &&
		    oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB)
			return;
	}

	pos = index_name_pos(r->index, path, strlen(path));
	if (pos >= 0)
		; /* path is in the index */
	else if (-1 - pos < r->index->cache_nr &&
		 !strcmp(r->index->cache[-1 - pos]->name, path))
		; /* path is in the index, unmerged */
	else
		die("no such path '%s' in HEAD", path);
}

static struct commit_list **append_parent(struct repository *r,
					  struct commit_list **tail,
					  const struct object_id *oid)
{
	struct commit *parent;

	parent = lookup_commit_reference(r, oid);
	if (!parent)
		die("no such commit %s", oid_to_hex(oid));
	return &commit_list_insert(parent, tail)->next;
}

static void append_merge_parents(struct repository *r,
				 struct commit_list **tail)
{
	int merge_head;
	struct strbuf line = STRBUF_INIT;

	merge_head = open(git_path_merge_head(r), O_RDONLY);
	if (merge_head < 0) {
		if (errno == ENOENT)
			return;
		die("cannot open '%s' for reading",
		    git_path_merge_head(r));
	}

	while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
		struct object_id oid;
		if (get_oid_hex(line.buf, &oid))
			die("unknown line in '%s': %s",
			    git_path_merge_head(r), line.buf);
		tail = append_parent(r, tail, &oid);
	}
	close(merge_head);
	strbuf_release(&line);
}

/*
 * This isn't as simple as passing sb->buf and sb->len, because we
 * want to transfer ownership of the buffer to the commit (so we
 * must use detach).
 */
static void set_commit_buffer_from_strbuf(struct repository *r,
					  struct commit *c,
					  struct strbuf *sb)
{
	size_t len;
	void *buf = strbuf_detach(sb, &len);
	set_commit_buffer(r, c, buf, len);
}

/*
 * Prepare a dummy commit that represents the work tree (or staged) item.
 * Note that annotating work tree item never works in the reverse.
 */
static struct commit *fake_working_tree_commit(struct repository *r,
					       struct diff_options *opt,
					       const char *path,
					       const char *contents_from,
					       struct object_id *oid)
{
	struct commit *commit;
	struct blame_origin *origin;
	struct commit_list **parent_tail, *parent;
	struct strbuf buf = STRBUF_INIT;
	const char *ident;
	time_t now;
	int len;
	struct cache_entry *ce;
	unsigned mode;
	struct strbuf msg = STRBUF_INIT;

	repo_read_index(r);
	time(&now);
	commit = alloc_commit_node(r);
	commit->object.parsed = 1;
	commit->date = now;
	parent_tail = &commit->parents;

	parent_tail = append_parent(r, parent_tail, oid);
	append_merge_parents(r, parent_tail);
	verify_working_tree_path(r, commit, path);

	origin = make_origin(commit, path);

	if (contents_from)
		ident = fmt_ident("External file (--contents)", "external.file",
				  WANT_BLANK_IDENT, NULL, 0);
	else
		ident = fmt_ident("Not Committed Yet", "not.committed.yet",
				  WANT_BLANK_IDENT, NULL, 0);
	strbuf_addstr(&msg, "tree 0000000000000000000000000000000000000000\n");
	for (parent = commit->parents; parent; parent = parent->next)
		strbuf_addf(&msg, "parent %s\n",
			    oid_to_hex(&parent->item->object.oid));
	strbuf_addf(&msg,
		    "author %s\n"
		    "committer %s\n\n"
		    "Version of %s from %s\n",
		    ident, ident, path,
		    (!contents_from ? path :
		     (!strcmp(contents_from, "-") ? "standard input" : contents_from)));
	set_commit_buffer_from_strbuf(r, commit, &msg);

	if (!contents_from || strcmp("-", contents_from)) {
		struct stat st;
		const char *read_from;
		char *buf_ptr;
		unsigned long buf_len;

		if (contents_from) {
			if (stat(contents_from, &st) < 0)
				die_errno("Cannot stat '%s'", contents_from);
			read_from = contents_from;
		}
		else {
			if (lstat(path, &st) < 0)
				die_errno("Cannot lstat '%s'", path);
			read_from = path;
		}
		mode = canon_mode(st.st_mode);

		switch (st.st_mode & S_IFMT) {
		case S_IFREG:
			if (opt->flags.allow_textconv &&
			    textconv_object(r, read_from, mode, null_oid(), 0, &buf_ptr, &buf_len))
				strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
			else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
				die_errno("cannot open or read '%s'", read_from);
			break;
		case S_IFLNK:
			if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
				die_errno("cannot readlink '%s'", read_from);
			break;
		default:
			die("unsupported file type %s", read_from);
		}
	}
	else {
		/* Reading from stdin */
		mode = 0;
		if (strbuf_read(&buf, 0, 0) < 0)
			die_errno("failed to read from stdin");
	}
	convert_to_git(r->index, path, buf.buf, buf.len, &buf, 0);
	origin->file.ptr = buf.buf;
	origin->file.size = buf.len;
	pretend_object_file(buf.buf, buf.len, OBJ_BLOB, &origin->blob_oid);

	/*
	 * Read the current index, replace the path entry with
	 * origin->blob_sha1 without mucking with its mode or type
	 * bits; we are not going to write this index out -- we just
	 * want to run "diff-index --cached".
	 */
	discard_index(r->index);
	repo_read_index(r);

	len = strlen(path);
	if (!mode) {
		int pos = index_name_pos(r->index, path, len);
		if (0 <= pos)
			mode = r->index->cache[pos]->ce_mode;
		else
			/* Let's not bother reading from HEAD tree */
			mode = S_IFREG | 0644;
	}
	ce = make_empty_cache_entry(r->index, len);
	oidcpy(&ce->oid, &origin->blob_oid);
	memcpy(ce->name, path, len);
	ce->ce_flags = create_ce_flags(0);
	ce->ce_namelen = len;
	ce->ce_mode = create_ce_mode(mode);
	add_index_entry(r->index, ce,
			ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);

	cache_tree_invalidate_path(r->index, path);

	return commit;
}



static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
		      xdl_emit_hunk_consume_func_t hunk_func, void *cb_data, int xdl_opts)
{
	xpparam_t xpp = {0};
	xdemitconf_t xecfg = {0};
	xdemitcb_t ecb = {NULL};

	xpp.flags = xdl_opts;
	xecfg.hunk_func = hunk_func;
	ecb.priv = cb_data;
	return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
}

static const char *get_next_line(const char *start, const char *end)
{
	const char *nl = memchr(start, '\n', end - start);

	return nl ? nl + 1 : end;
}

static int find_line_starts(int **line_starts, const char *buf,
			    unsigned long len)
{
	const char *end = buf + len;
	const char *p;
	int *lineno;
	int num = 0;

	for (p = buf; p < end; p = get_next_line(p, end))
		num++;

	ALLOC_ARRAY(*line_starts, num + 1);
	lineno = *line_starts;

	for (p = buf; p < end; p = get_next_line(p, end))
		*lineno++ = p - buf;

	*lineno = len;

	return num;
}

struct fingerprint_entry;

/* A fingerprint is intended to loosely represent a string, such that two
 * fingerprints can be quickly compared to give an indication of the similarity
 * of the strings that they represent.
 *
 * A fingerprint is represented as a multiset of the lower-cased byte pairs in
 * the string that it represents. Whitespace is added at each end of the
 * string. Whitespace pairs are ignored. Whitespace is converted to '\0'.
 * For example, the string "Darth   Radar" will be converted to the following
 * fingerprint:
 * {"\0d", "da", "da", "ar", "ar", "rt", "th", "h\0", "\0r", "ra", "ad", "r\0"}
 *
 * The similarity between two fingerprints is the size of the intersection of
 * their multisets, including repeated elements. See fingerprint_similarity for
 * examples.
 *
 * For ease of implementation, the fingerprint is implemented as a map
 * of byte pairs to the count of that byte pair in the string, instead of
 * allowing repeated elements in a set.
 */
struct fingerprint {
	struct hashmap map;
	/* As we know the maximum number of entries in advance, it's
	 * convenient to store the entries in a single array instead of having
	 * the hashmap manage the memory.
	 */
	struct fingerprint_entry *entries;
};

/* A byte pair in a fingerprint. Stores the number of times the byte pair
 * occurs in the string that the fingerprint represents.
 */
struct fingerprint_entry {
	/* The hashmap entry - the hash represents the byte pair in its
	 * entirety so we don't need to store the byte pair separately.
	 */
	struct hashmap_entry entry;
	/* The number of times the byte pair occurs in the string that the
	 * fingerprint represents.
	 */
	int count;
};

/* See `struct fingerprint` for an explanation of what a fingerprint is.
 * \param result the fingerprint of the string is stored here. This must be
 * 		 freed later using free_fingerprint.
 * \param line_begin the start of the string
 * \param line_end the end of the string
 */
static void get_fingerprint(struct fingerprint *result,
			    const char *line_begin,
			    const char *line_end)
{
	unsigned int hash, c0 = 0, c1;
	const char *p;
	int max_map_entry_count = 1 + line_end - line_begin;
	struct fingerprint_entry *entry = xcalloc(max_map_entry_count,
		sizeof(struct fingerprint_entry));
	struct fingerprint_entry *found_entry;

	hashmap_init(&result->map, NULL, NULL, max_map_entry_count);
	result->entries = entry;
	for (p = line_begin; p <= line_end; ++p, c0 = c1) {
		/* Always terminate the string with whitespace.
		 * Normalise whitespace to 0, and normalise letters to
		 * lower case. This won't work for multibyte characters but at
		 * worst will match some unrelated characters.
		 */
		if ((p == line_end) || isspace(*p))
			c1 = 0;
		else
			c1 = tolower(*p);
		hash = c0 | (c1 << 8);
		/* Ignore whitespace pairs */
		if (hash == 0)
			continue;
		hashmap_entry_init(&entry->entry, hash);

		found_entry = hashmap_get_entry(&result->map, entry,
						/* member name */ entry, NULL);
		if (found_entry) {
			found_entry->count += 1;
		} else {
			entry->count = 1;
			hashmap_add(&result->map, &entry->entry);
			++entry;
		}
	}
}

static void free_fingerprint(struct fingerprint *f)
{
	hashmap_clear(&f->map);
	free(f->entries);
}

/* Calculates the similarity between two fingerprints as the size of the
 * intersection of their multisets, including repeated elements. See
 * `struct fingerprint` for an explanation of the fingerprint representation.
 * The similarity between "cat mat" and "father rather" is 2 because "at" is
 * present twice in both strings while the similarity between "tim" and "mit"
 * is 0.
 */
static int fingerprint_similarity(struct fingerprint *a, struct fingerprint *b)
{
	int intersection = 0;
	struct hashmap_iter iter;
	const struct fingerprint_entry *entry_a, *entry_b;

	hashmap_for_each_entry(&b->map, &iter, entry_b,
				entry /* member name */) {
		entry_a = hashmap_get_entry(&a->map, entry_b, entry, NULL);
		if (entry_a) {
			intersection += entry_a->count < entry_b->count ?
					entry_a->count : entry_b->count;
		}
	}
	return intersection;
}

/* Subtracts byte-pair elements in B from A, modifying A in place.
 */
static void fingerprint_subtract(struct fingerprint *a, struct fingerprint *b)
{
	struct hashmap_iter iter;
	struct fingerprint_entry *entry_a;
	const struct fingerprint_entry *entry_b;

	hashmap_iter_init(&b->map, &iter);

	hashmap_for_each_entry(&b->map, &iter, entry_b,
				entry /* member name */) {
		entry_a = hashmap_get_entry(&a->map, entry_b, entry, NULL);
		if (entry_a) {
			if (entry_a->count <= entry_b->count)
				hashmap_remove(&a->map, &entry_b->entry, NULL);
			else
				entry_a->count -= entry_b->count;
		}
	}
}

/* Calculate fingerprints for a series of lines.
 * Puts the fingerprints in the fingerprints array, which must have been
 * preallocated to allow storing line_count elements.
 */
static void get_line_fingerprints(struct fingerprint *fingerprints,
				  const char *content, const int *line_starts,
				  long first_line, long line_count)
{
	int i;
	const char *linestart, *lineend;

	line_starts += first_line;
	for (i = 0; i < line_count; ++i) {
		linestart = content + line_starts[i];
		lineend = content + line_starts[i + 1];
		get_fingerprint(fingerprints + i, linestart, lineend);
	}
}

static void free_line_fingerprints(struct fingerprint *fingerprints,
				   int nr_fingerprints)
{
	int i;

	for (i = 0; i < nr_fingerprints; i++)
		free_fingerprint(&fingerprints[i]);
}

/* This contains the data necessary to linearly map a line number in one half
 * of a diff chunk to the line in the other half of the diff chunk that is
 * closest in terms of its position as a fraction of the length of the chunk.
 */
struct line_number_mapping {
	int destination_start, destination_length,
		source_start, source_length;
};

/* Given a line number in one range, offset and scale it to map it onto the
 * other range.
 * Essentially this mapping is a simple linear equation but the calculation is
 * more complicated to allow performing it with integer operations.
 * Another complication is that if a line could map onto many lines in the
 * destination range then we want to choose the line at the center of those
 * possibilities.
 * Example: if the chunk is 2 lines long in A and 10 lines long in B then the
 * first 5 lines in B will map onto the first line in the A chunk, while the
 * last 5 lines will all map onto the second line in the A chunk.
 * Example: if the chunk is 10 lines long in A and 2 lines long in B then line
 * 0 in B will map onto line 2 in A, and line 1 in B will map onto line 7 in A.
 */
static int map_line_number(int line_number,
	const struct line_number_mapping *mapping)
{
	return ((line_number - mapping->source_start) * 2 + 1) *
	       mapping->destination_length /
	       (mapping->source_length * 2) +
	       mapping->destination_start;
}

/* Get a pointer to the element storing the similarity between a line in A
 * and a line in B.
 *
 * The similarities are stored in a 2-dimensional array. Each "row" in the
 * array contains the similarities for a line in B. The similarities stored in
 * a row are the similarities between the line in B and the nearby lines in A.
 * To keep the length of each row the same, it is padded out with values of -1
 * where the search range extends beyond the lines in A.
 * For example, if max_search_distance_a is 2 and the two sides of a diff chunk
 * look like this:
 * a | m
 * b | n
 * c | o
 * d | p
 * e | q
 * Then the similarity array will contain:
 * [-1, -1, am, bm, cm,
 *  -1, an, bn, cn, dn,
 *  ao, bo, co, do, eo,
 *  bp, cp, dp, ep, -1,
 *  cq, dq, eq, -1, -1]
 * Where similarities are denoted either by -1 for invalid, or the
 * concatenation of the two lines in the diff being compared.
 *
 * \param similarities array of similarities between lines in A and B
 * \param line_a the index of the line in A, in the same frame of reference as
 *	closest_line_a.
 * \param local_line_b the index of the line in B, relative to the first line
 *		       in B that similarities represents.
 * \param closest_line_a the index of the line in A that is deemed to be
 *			 closest to local_line_b. This must be in the same
 *			 frame of reference as line_a. This value defines
 *			 where similarities is centered for the line in B.
 * \param max_search_distance_a maximum distance in lines from the closest line
 * 				in A for other lines in A for which
 * 				similarities may be calculated.
 */
static int *get_similarity(int *similarities,
			   int line_a, int local_line_b,
			   int closest_line_a, int max_search_distance_a)
{
	assert(abs(line_a - closest_line_a) <=
	       max_search_distance_a);
	return similarities + line_a - closest_line_a +
	       max_search_distance_a +
	       local_line_b * (max_search_distance_a * 2 + 1);
}

#define CERTAIN_NOTHING_MATCHES -2
#define CERTAINTY_NOT_CALCULATED -1

/* Given a line in B, first calculate its similarities with nearby lines in A
 * if not already calculated, then identify the most similar and second most
 * similar lines. The "certainty" is calculated based on those two
 * similarities.
 *
 * \param start_a the index of the first line of the chunk in A
 * \param length_a the length in lines of the chunk in A
 * \param local_line_b the index of the line in B, relative to the first line
 * 		       in the chunk.
 * \param fingerprints_a array of fingerprints for the chunk in A
 * \param fingerprints_b array of fingerprints for the chunk in B
 * \param similarities 2-dimensional array of similarities between lines in A
 * 		       and B. See get_similarity() for more details.
 * \param certainties array of values indicating how strongly a line in B is
 * 		      matched with some line in A.
 * \param second_best_result array of absolute indices in A for the second
 * 			     closest match of a line in B.
 * \param result array of absolute indices in A for the closest match of a line
 * 		 in B.
 * \param max_search_distance_a maximum distance in lines from the closest line
 * 				in A for other lines in A for which
 * 				similarities may be calculated.
 * \param map_line_number_in_b_to_a parameter to map_line_number().
 */
static void find_best_line_matches(
	int start_a,
	int length_a,
	int start_b,
	int local_line_b,
	struct fingerprint *fingerprints_a,
	struct fingerprint *fingerprints_b,
	int *similarities,
	int *certainties,
	int *second_best_result,
	int *result,
	const int max_search_distance_a,
	const struct line_number_mapping *map_line_number_in_b_to_a)
{

	int i, search_start, search_end, closest_local_line_a, *similarity,
		best_similarity = 0, second_best_similarity = 0,
		best_similarity_index = 0, second_best_similarity_index = 0;

	/* certainty has already been calculated so no need to redo the work */
	if (certainties[local_line_b] != CERTAINTY_NOT_CALCULATED)
		return;

	closest_local_line_a = map_line_number(
		local_line_b + start_b, map_line_number_in_b_to_a) - start_a;

	search_start = closest_local_line_a - max_search_distance_a;
	if (search_start < 0)
		search_start = 0;

	search_end = closest_local_line_a + max_search_distance_a + 1;
	if (search_end > length_a)
		search_end = length_a;

	for (i = search_start; i < search_end; ++i) {
		similarity = get_similarity(similarities,
					    i, local_line_b,
					    closest_local_line_a,
					    max_search_distance_a);
		if (*similarity == -1) {
			/* This value will never exceed 10 but assert just in
			 * case
			 */
			assert(abs(i - closest_local_line_a) < 1000);
			/* scale the similarity by (1000 - distance from
			 * closest line) to act as a tie break between lines
			 * that otherwise are equally similar.
			 */
			*similarity = fingerprint_similarity(
				fingerprints_b + local_line_b,
				fingerprints_a + i) *
				(1000 - abs(i - closest_local_line_a));
		}
		if (*similarity > best_similarity) {
			second_best_similarity = best_similarity;
			second_best_similarity_index = best_similarity_index;
			best_similarity = *similarity;
			best_similarity_index = i;
		} else if (*similarity > second_best_similarity) {
			second_best_similarity = *similarity;
			second_best_similarity_index = i;
		}
	}

	if (best_similarity == 0) {
		/* this line definitely doesn't match with anything. Mark it
		 * with this special value so it doesn't get invalidated and
		 * won't be recalculated.
		 */
		certainties[local_line_b] = CERTAIN_NOTHING_MATCHES;
		result[local_line_b] = -1;
	} else {
		/* Calculate the certainty with which this line matches.
		 * If the line matches well with two lines then that reduces
		 * the certainty. However we still want to prioritise matching
		 * a line that matches very well with two lines over matching a
		 * line that matches poorly with one line, hence doubling
		 * best_similarity.
		 * This means that if we have
		 * line X that matches only one line with a score of 3,
		 * line Y that matches two lines equally with a score of 5,
		 * and line Z that matches only one line with a score or 2,
		 * then the lines in order of certainty are X, Y, Z.
		 */
		certainties[local_line_b] = best_similarity * 2 -
			second_best_similarity;

		/* We keep both the best and second best results to allow us to
		 * check at a later stage of the matching process whether the
		 * result needs to be invalidated.
		 */
		result[local_line_b] = start_a + best_similarity_index;
		second_best_result[local_line_b] =
			start_a + second_best_similarity_index;
	}
}

/*
 * This finds the line that we can match with the most confidence, and
 * uses it as a partition. It then calls itself on the lines on either side of
 * that partition. In this way we avoid lines appearing out of order, and
 * retain a sensible line ordering.
 * \param start_a index of the first line in A with which lines in B may be
 * 		  compared.
 * \param start_b index of the first line in B for which matching should be
 * 		  done.
 * \param length_a number of lines in A with which lines in B may be compared.
 * \param length_b number of lines in B for which matching should be done.
 * \param fingerprints_a mutable array of fingerprints in A. The first element
 * 			 corresponds to the line at start_a.
 * \param fingerprints_b array of fingerprints in B. The first element
 * 			 corresponds to the line at start_b.
 * \param similarities 2-dimensional array of similarities between lines in A
 * 		       and B. See get_similarity() for more details.
 * \param certainties array of values indicating how strongly a line in B is
 * 		      matched with some line in A.
 * \param second_best_result array of absolute indices in A for the second
 * 			     closest match of a line in B.
 * \param result array of absolute indices in A for the closest match of a line
 * 		 in B.
 * \param max_search_distance_a maximum distance in lines from the closest line
 * 			      in A for other lines in A for which
 * 			      similarities may be calculated.
 * \param max_search_distance_b an upper bound on the greatest possible
 * 			      distance between lines in B such that they will
 *                              both be compared with the same line in A
 * 			      according to max_search_distance_a.
 * \param map_line_number_in_b_to_a parameter to map_line_number().
 */
static void fuzzy_find_matching_lines_recurse(
	int start_a, int start_b,
	int length_a, int length_b,
	struct fingerprint *fingerprints_a,
	struct fingerprint *fingerprints_b,
	int *similarities,
	int *certainties,
	int *second_best_result,
	int *result,
	int max_search_distance_a,
	int max_search_distance_b,
	const struct line_number_mapping *map_line_number_in_b_to_a)
{
	int i, invalidate_min, invalidate_max, offset_b,
		second_half_start_a, second_half_start_b,
		second_half_length_a, second_half_length_b,
		most_certain_line_a, most_certain_local_line_b = -1,
		most_certain_line_certainty = -1,
		closest_local_line_a;

	for (i = 0; i < length_b; ++i) {
		find_best_line_matches(start_a,
				       length_a,
				       start_b,
				       i,
				       fingerprints_a,
				       fingerprints_b,
				       similarities,
				       certainties,
				       second_best_result,
				       result,
				       max_search_distance_a,
				       map_line_number_in_b_to_a);

		if (certainties[i] > most_certain_line_certainty) {
			most_certain_line_certainty = certainties[i];
			most_certain_local_line_b = i;
		}
	}

	/* No matches. */
	if (most_certain_local_line_b == -1)
		return;

	most_certain_line_a = result[most_certain_local_line_b];

	/*
	 * Subtract the most certain line's fingerprint in B from the matched
	 * fingerprint in A. This means that other lines in B can't also match
	 * the same parts of the line in A.
	 */
	fingerprint_subtract(fingerprints_a + most_certain_line_a - start_a,
			     fingerprints_b + most_certain_local_line_b);

	/* Invalidate results that may be affected by the choice of most
	 * certain line.
	 */
	invalidate_min = most_certain_local_line_b - max_search_distance_b;
	invalidate_max = most_certain_local_line_b + max_search_distance_b + 1;
	if (invalidate_min < 0)
		invalidate_min = 0;
	if (invalidate_max > length_b)
		invalidate_max = length_b;

	/* As the fingerprint in A has changed, discard previously calculated
	 * similarity values with that fingerprint.
	 */
	for (i = invalidate_min; i < invalidate_max; ++i) {
		closest_local_line_a = map_line_number(
			i + start_b, map_line_number_in_b_to_a) - start_a;

		/* Check that the lines in A and B are close enough that there
		 * is a similarity value for them.
		 */
		if (abs(most_certain_line_a - start_a - closest_local_line_a) >
			max_search_distance_a) {
			continue;
		}

		*get_similarity(similarities, most_certain_line_a - start_a,
				i, closest_local_line_a,
				max_search_distance_a) = -1;
	}

	/* More invalidating of results that may be affected by the choice of
	 * most certain line.
	 * Discard the matches for lines in B that are currently matched with a
	 * line in A such that their ordering contradicts the ordering imposed
	 * by the choice of most certain line.
	 */
	for (i = most_certain_local_line_b - 1; i >= invalidate_min; --i) {
		/* In this loop we discard results for lines in B that are
		 * before most-certain-line-B but are matched with a line in A
		 * that is after most-certain-line-A.
		 */
		if (certainties[i] >= 0 &&
		    (result[i] >= most_certain_line_a ||
		     second_best_result[i] >= most_certain_line_a)) {
			certainties[i] = CERTAINTY_NOT_CALCULATED;
		}
	}
	for (i = most_certain_local_line_b + 1; i < invalidate_max; ++i) {
		/* In this loop we discard results for lines in B that are
		 * after most-certain-line-B but are matched with a line in A
		 * that is before most-certain-line-A.
		 */
		if (certainties[i] >= 0 &&
		    (result[i] <= most_certain_line_a ||
		     second_best_result[i] <= most_certain_line_a)) {
			certainties[i] = CERTAINTY_NOT_CALCULATED;
		}
	}

	/* Repeat the matching process for lines before the most certain line.
	 */
	if (most_certain_local_line_b > 0) {
		fuzzy_find_matching_lines_recurse(
			start_a, start_b,
			most_certain_line_a + 1 - start_a,
			most_certain_local_line_b,
			fingerprints_a, fingerprints_b, similarities,
			certainties, second_best_result, result,
			max_search_distance_a,
			max_search_distance_b,
			map_line_number_in_b_to_a);
	}
	/* Repeat the matching process for lines after the most certain line.
	 */
	if (most_certain_local_line_b + 1 < length_b) {
		second_half_start_a = most_certain_line_a;
		offset_b = most_certain_local_line_b + 1;
		second_half_start_b = start_b + offset_b;
		second_half_length_a =
			length_a + start_a - second_half_start_a;
		second_half_length_b =
			length_b + start_b - second_half_start_b;
		fuzzy_find_matching_lines_recurse(
			second_half_start_a, second_half_start_b,
			second_half_length_a, second_half_length_b,
			fingerprints_a + second_half_start_a - start_a,
			fingerprints_b + offset_b,
			similarities +
				offset_b * (max_search_distance_a * 2 + 1),
			certainties + offset_b,
			second_best_result + offset_b, result + offset_b,
			max_search_distance_a,
			max_search_distance_b,
			map_line_number_in_b_to_a);
	}
}

/* Find the lines in the parent line range that most closely match the lines in
 * the target line range. This is accomplished by matching fingerprints in each
 * blame_origin, and choosing the best matches that preserve the line ordering.
 * See struct fingerprint for details of fingerprint matching, and
 * fuzzy_find_matching_lines_recurse for details of preserving line ordering.
 *
 * The performance is believed to be O(n log n) in the typical case and O(n^2)
 * in a pathological case, where n is the number of lines in the target range.
 */
static int *fuzzy_find_matching_lines(struct blame_origin *parent,
				      struct blame_origin *target,
				      int tlno, int parent_slno, int same,
				      int parent_len)
{
	/* We use the terminology "A" for the left hand side of the diff AKA
	 * parent, and "B" for the right hand side of the diff AKA target. */
	int start_a = parent_slno;
	int length_a = parent_len;
	int start_b = tlno;
	int length_b = same - tlno;

	struct line_number_mapping map_line_number_in_b_to_a = {
		start_a, length_a, start_b, length_b
	};

	struct fingerprint *fingerprints_a = parent->fingerprints;
	struct fingerprint *fingerprints_b = target->fingerprints;

	int i, *result, *second_best_result,
		*certainties, *similarities, similarity_count;

	/*
	 * max_search_distance_a means that given a line in B, compare it to
	 * the line in A that is closest to its position, and the lines in A
	 * that are no greater than max_search_distance_a lines away from the
	 * closest line in A.
	 *
	 * max_search_distance_b is an upper bound on the greatest possible
	 * distance between lines in B such that they will both be compared
	 * with the same line in A according to max_search_distance_a.
	 */
	int max_search_distance_a = 10, max_search_distance_b;

	if (length_a <= 0)
		return NULL;

	if (max_search_distance_a >= length_a)
		max_search_distance_a = length_a ? length_a - 1 : 0;

	max_search_distance_b = ((2 * max_search_distance_a + 1) * length_b
				 - 1) / length_a;

	CALLOC_ARRAY(result, length_b);
	CALLOC_ARRAY(second_best_result, length_b);
	CALLOC_ARRAY(certainties, length_b);

	/* See get_similarity() for details of similarities. */
	similarity_count = length_b * (max_search_distance_a * 2 + 1);
	CALLOC_ARRAY(similarities, similarity_count);

	for (i = 0; i < length_b; ++i) {
		result[i] = -1;
		second_best_result[i] = -1;
		certainties[i] = CERTAINTY_NOT_CALCULATED;
	}

	for (i = 0; i < similarity_count; ++i)
		similarities[i] = -1;

	fuzzy_find_matching_lines_recurse(start_a, start_b,
					  length_a, length_b,
					  fingerprints_a + start_a,
					  fingerprints_b + start_b,
					  similarities,
					  certainties,
					  second_best_result,
					  result,
					  max_search_distance_a,
					  max_search_distance_b,
					  &map_line_number_in_b_to_a);

	free(similarities);
	free(certainties);
	free(second_best_result);

	return result;
}

static void fill_origin_fingerprints(struct blame_origin *o)
{
	int *line_starts;

	if (o->fingerprints)
		return;
	o->num_lines = find_line_starts(&line_starts, o->file.ptr,
					o->file.size);
	CALLOC_ARRAY(o->fingerprints, o->num_lines);
	get_line_fingerprints(o->fingerprints, o->file.ptr, line_starts,
			      0, o->num_lines);
	free(line_starts);
}

static void drop_origin_fingerprints(struct blame_origin *o)
{
	if (o->fingerprints) {
		free_line_fingerprints(o->fingerprints, o->num_lines);
		o->num_lines = 0;
		FREE_AND_NULL(o->fingerprints);
	}
}

/*
 * Given an origin, prepare mmfile_t structure to be used by the
 * diff machinery
 */
static void fill_origin_blob(struct diff_options *opt,
			     struct blame_origin *o, mmfile_t *file,
			     int *num_read_blob, int fill_fingerprints)
{
	if (!o->file.ptr) {
		enum object_type type;
		unsigned long file_size;

		(*num_read_blob)++;
		if (opt->flags.allow_textconv &&
		    textconv_object(opt->repo, o->path, o->mode,
				    &o->blob_oid, 1, &file->ptr, &file_size))
			;
		else
			file->ptr = repo_read_object_file(the_repository,
							  &o->blob_oid, &type,
							  &file_size);
		file->size = file_size;

		if (!file->ptr)
			die("Cannot read blob %s for path %s",
			    oid_to_hex(&o->blob_oid),
			    o->path);
		o->file = *file;
	}
	else
		*file = o->file;
	if (fill_fingerprints)
		fill_origin_fingerprints(o);
}

static void drop_origin_blob(struct blame_origin *o)
{
	FREE_AND_NULL(o->file.ptr);
	drop_origin_fingerprints(o);
}

/*
 * Any merge of blames happens on lists of blames that arrived via
 * different parents in a single suspect.  In this case, we want to
 * sort according to the suspect line numbers as opposed to the final
 * image line numbers.  The function body is somewhat longish because
 * it avoids unnecessary writes.
 */

static struct blame_entry *blame_merge(struct blame_entry *list1,
				       struct blame_entry *list2)
{
	struct blame_entry *p1 = list1, *p2 = list2,
		**tail = &list1;

	if (!p1)
		return p2;
	if (!p2)
		return p1;

	if (p1->s_lno <= p2->s_lno) {
		do {
			tail = &p1->next;
			if (!(p1 = *tail)) {
				*tail = p2;
				return list1;
			}
		} while (p1->s_lno <= p2->s_lno);
	}
	for (;;) {
		*tail = p2;
		do {
			tail = &p2->next;
			if (!(p2 = *tail))  {
				*tail = p1;
				return list1;
			}
		} while (p1->s_lno > p2->s_lno);
		*tail = p1;
		do {
			tail = &p1->next;
			if (!(p1 = *tail)) {
				*tail = p2;
				return list1;
			}
		} while (p1->s_lno <= p2->s_lno);
	}
}

DEFINE_LIST_SORT(static, sort_blame_entries, struct blame_entry, next);

/*
 * Final image line numbers are all different, so we don't need a
 * three-way comparison here.
 */

static int compare_blame_final(const struct blame_entry *e1,
			       const struct blame_entry *e2)
{
	return e1->lno > e2->lno ? 1 : -1;
}

static int compare_blame_suspect(const struct blame_entry *s1,
				 const struct blame_entry *s2)
{
	/*
	 * to allow for collating suspects, we sort according to the
	 * respective pointer value as the primary sorting criterion.
	 * The actual relation is pretty unimportant as long as it
	 * establishes a total order.  Comparing as integers gives us
	 * that.
	 */
	if (s1->suspect != s2->suspect)
		return (intptr_t)s1->suspect > (intptr_t)s2->suspect ? 1 : -1;
	if (s1->s_lno == s2->s_lno)
		return 0;
	return s1->s_lno > s2->s_lno ? 1 : -1;
}

void blame_sort_final(struct blame_scoreboard *sb)
{
	sort_blame_entries(&sb->ent, compare_blame_final);
}

static int compare_commits_by_reverse_commit_date(const void *a,
						  const void *b,
						  void *c)
{
	return -compare_commits_by_commit_date(a, b, c);
}

/*
 * For debugging -- origin is refcounted, and this asserts that
 * we do not underflow.
 */
static void sanity_check_refcnt(struct blame_scoreboard *sb)
{
	int baa = 0;
	struct blame_entry *ent;

	for (ent = sb->ent; ent; ent = ent->next) {
		/* Nobody should have zero or negative refcnt */
		if (ent->suspect->refcnt <= 0) {
			fprintf(stderr, "%s in %s has negative refcnt %d\n",
				ent->suspect->path,
				oid_to_hex(&ent->suspect->commit->object.oid),
				ent->suspect->refcnt);
			baa = 1;
		}
	}
	if (baa)
		sb->on_sanity_fail(sb, baa);
}

/*
 * If two blame entries that are next to each other came from
 * contiguous lines in the same origin (i.e. <commit, path> pair),
 * merge them together.
 */
void blame_coalesce(struct blame_scoreboard *sb)
{
	struct blame_entry *ent, *next;

	for (ent = sb->ent; ent && (next = ent->next); ent = next) {
		if (ent->suspect == next->suspect &&
		    ent->s_lno + ent->num_lines == next->s_lno &&
		    ent->lno + ent->num_lines == next->lno &&
		    ent->ignored == next->ignored &&
		    ent->unblamable == next->unblamable) {
			ent->num_lines += next->num_lines;
			ent->next = next->next;
			blame_origin_decref(next->suspect);
			free(next);
			ent->score = 0;
			next = ent; /* again */
		}
	}

	if (sb->debug) /* sanity */
		sanity_check_refcnt(sb);
}

/*
 * Merge the given sorted list of blames into a preexisting origin.
 * If there were no previous blames to that commit, it is entered into
 * the commit priority queue of the score board.
 */

static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porigin,
			 struct blame_entry *sorted)
{
	if (porigin->suspects)
		porigin->suspects = blame_merge(porigin->suspects, sorted);
	else {
		struct blame_origin *o;
		for (o = get_blame_suspects(porigin->commit); o; o = o->next) {
			if (o->suspects) {
				porigin->suspects = sorted;
				return;
			}
		}
		porigin->suspects = sorted;
		prio_queue_put(&sb->commits, porigin->commit);
	}
}

/*
 * Fill the blob_sha1 field of an origin if it hasn't, so that later
 * call to fill_origin_blob() can use it to locate the data.  blob_sha1
 * for an origin is also used to pass the blame for the entire file to
 * the parent to detect the case where a child's blob is identical to
 * that of its parent's.
 *
 * This also fills origin->mode for corresponding tree path.
 */
static int fill_blob_sha1_and_mode(struct repository *r,
				   struct blame_origin *origin)
{
	if (!is_null_oid(&origin->blob_oid))
		return 0;
	if (get_tree_entry(r, &origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
		goto error_out;
	if (oid_object_info(r, &origin->blob_oid, NULL) != OBJ_BLOB)
		goto error_out;
	return 0;
 error_out:
	oidclr(&origin->blob_oid);
	origin->mode = S_IFINVALID;
	return -1;
}

struct blame_bloom_data {
	/*
	 * Changed-path Bloom filter keys. These can help prevent
	 * computing diffs against first parents, but we need to
	 * expand the list as code is moved or files are renamed.
	 */
	struct bloom_filter_settings *settings;
	struct bloom_key **keys;
	int nr;
	int alloc;
};

static int bloom_count_queries = 0;
static int bloom_count_no = 0;
static int maybe_changed_path(struct repository *r,
			      struct blame_origin *origin,
			      struct blame_bloom_data *bd)
{
	int i;
	struct bloom_filter *filter;

	if (!bd)
		return 1;

	if (commit_graph_generation(origin->commit) == GENERATION_NUMBER_INFINITY)
		return 1;

	filter = get_bloom_filter(r, origin->commit);

	if (!filter)
		return 1;

	bloom_count_queries++;
	for (i = 0; i < bd->nr; i++) {
		if (bloom_filter_contains(filter,
					  bd->keys[i],
					  bd->settings))
			return 1;
	}

	bloom_count_no++;
	return 0;
}

static void add_bloom_key(struct blame_bloom_data *bd,
			  const char *path)
{
	if (!bd)
		return;

	if (bd->nr >= bd->alloc) {
		bd->alloc *= 2;
		REALLOC_ARRAY(bd->keys, bd->alloc);
	}

	bd->keys[bd->nr] = xmalloc(sizeof(struct bloom_key));
	fill_bloom_key(path, strlen(path), bd->keys[bd->nr], bd->settings);
	bd->nr++;
}

/*
 * We have an origin -- check if the same path exists in the
 * parent and return an origin structure to represent it.
 */
static struct blame_origin *find_origin(struct repository *r,
					struct commit *parent,
					struct blame_origin *origin,
					struct blame_bloom_data *bd)
{
	struct blame_origin *porigin;
	struct diff_options diff_opts;
	const char *paths[2];

	/* First check any existing origins */
	for (porigin = get_blame_suspects(parent); porigin; porigin = porigin->next)
		if (!strcmp(porigin->path, origin->path)) {
			/*
			 * The same path between origin and its parent
			 * without renaming -- the most common case.
			 */
			return blame_origin_incref (porigin);
		}

	/* See if the origin->path is different between parent
	 * and origin first.  Most of the time they are the
	 * same and diff-tree is fairly efficient about this.
	 */
	repo_diff_setup(r, &diff_opts);
	diff_opts.flags.recursive = 1;
	diff_opts.detect_rename = 0;
	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
	paths[0] = origin->path;
	paths[1] = NULL;

	parse_pathspec(&diff_opts.pathspec,
		       PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
		       PATHSPEC_LITERAL_PATH, "", paths);
	diff_setup_done(&diff_opts);

	if (is_null_oid(&origin->commit->object.oid))
		do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
	else {
		int compute_diff = 1;
		if (origin->commit->parents &&
		    oideq(&parent->object.oid,
			  &origin->commit->parents->item->object.oid))
			compute_diff = maybe_changed_path(r, origin, bd);

		if (compute_diff)
			diff_tree_oid(get_commit_tree_oid(parent),
				      get_commit_tree_oid(origin->commit),
				      "", &diff_opts);
	}
	diffcore_std(&diff_opts);

	if (!diff_queued_diff.nr) {
		/* The path is the same as parent */
		porigin = get_origin(parent, origin->path);
		oidcpy(&porigin->blob_oid, &origin->blob_oid);
		porigin->mode = origin->mode;
	} else {
		/*
		 * Since origin->path is a pathspec, if the parent
		 * commit had it as a directory, we will see a whole
		 * bunch of deletion of files in the directory that we
		 * do not care about.
		 */
		int i;
		struct diff_filepair *p = NULL;
		for (i = 0; i < diff_queued_diff.nr; i++) {
			const char *name;
			p = diff_queued_diff.queue[i];
			name = p->one->path ? p->one->path : p->two->path;
			if (!strcmp(name, origin->path))
				break;
		}
		if (!p)
			die("internal error in blame::find_origin");
		switch (p->status) {
		default:
			die("internal error in blame::find_origin (%c)",
			    p->status);
		case 'M':
			porigin = get_origin(parent, origin->path);
			oidcpy(&porigin->blob_oid, &p->one->oid);
			porigin->mode = p->one->mode;
			break;
		case 'A':
		case 'T':
			/* Did not exist in parent, or type changed */
			break;
		}
	}
	diff_flush(&diff_opts);
	return porigin;
}

/*
 * We have an origin -- find the path that corresponds to it in its
 * parent and return an origin structure to represent it.
 */
static struct blame_origin *find_rename(struct repository *r,
					struct commit *parent,
					struct blame_origin *origin,
					struct blame_bloom_data *bd)
{
	struct blame_origin *porigin = NULL;
	struct diff_options diff_opts;
	int i;

	repo_diff_setup(r, &diff_opts);
	diff_opts.flags.recursive = 1;
	diff_opts.detect_rename = DIFF_DETECT_RENAME;
	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
	diff_opts.single_follow = origin->path;
	diff_setup_done(&diff_opts);

	if (is_null_oid(&origin->commit->object.oid))
		do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
	else
		diff_tree_oid(get_commit_tree_oid(parent),
			      get_commit_tree_oid(origin->commit),
			      "", &diff_opts);
	diffcore_std(&diff_opts);

	for (i = 0; i < diff_queued_diff.nr; i++) {
		struct diff_filepair *p = diff_queued_diff.queue[i];
		if ((p->status == 'R' || p->status == 'C') &&
		    !strcmp(p->two->path, origin->path)) {
			add_bloom_key(bd, p->one->path);
			porigin = get_origin(parent, p->one->path);
			oidcpy(&porigin->blob_oid, &p->one->oid);
			porigin->mode = p->one->mode;
			break;
		}
	}
	diff_flush(&diff_opts);
	return porigin;
}

/*
 * Append a new blame entry to a given output queue.
 */
static void add_blame_entry(struct blame_entry ***queue,
			    const struct blame_entry *src)
{
	struct blame_entry *e = xmalloc(sizeof(*e));
	memcpy(e, src, sizeof(*e));
	blame_origin_incref(e->suspect);

	e->next = **queue;
	**queue = e;
	*queue = &e->next;
}

/*
 * src typically is on-stack; we want to copy the information in it to
 * a malloced blame_entry that gets added to the given queue.  The
 * origin of dst loses a refcnt.
 */
static void dup_entry(struct blame_entry ***queue,
		      struct blame_entry *dst, struct blame_entry *src)
{
	blame_origin_incref(src->suspect);
	blame_origin_decref(dst->suspect);
	memcpy(dst, src, sizeof(*src));
	dst->next = **queue;
	**queue = dst;
	*queue = &dst->next;
}

const char *blame_nth_line(struct blame_scoreboard *sb, long lno)
{
	return sb->final_buf + sb->lineno[lno];
}

/*
 * It is known that lines between tlno to same came from parent, and e
 * has an overlap with that range.  it also is known that parent's
 * line plno corresponds to e's line tlno.
 *
 *                <---- e ----->
 *                   <------>
 *                   <------------>
 *             <------------>
 *             <------------------>
 *
 * Split e into potentially three parts; before this chunk, the chunk
 * to be blamed for the parent, and after that portion.
 */
static void split_overlap(struct blame_entry *split,
			  struct blame_entry *e,
			  int tlno, int plno, int same,
			  struct blame_origin *parent)
{
	int chunk_end_lno;
	int i;
	memset(split, 0, sizeof(struct blame_entry [3]));

	for (i = 0; i < 3; i++) {
		split[i].ignored = e->ignored;
		split[i].unblamable = e->unblamable;
	}

	if (e->s_lno < tlno) {
		/* there is a pre-chunk part not blamed on parent */
		split[0].suspect = blame_origin_incref(e->suspect);
		split[0].lno = e->lno;
		split[0].s_lno = e->s_lno;
		split[0].num_lines = tlno - e->s_lno;
		split[1].lno = e->lno + tlno - e->s_lno;
		split[1].s_lno = plno;
	}
	else {
		split[1].lno = e->lno;
		split[1].s_lno = plno + (e->s_lno - tlno);
	}

	if (same < e->s_lno + e->num_lines) {
		/* there is a post-chunk part not blamed on parent */
		split[2].suspect = blame_origin_incref(e->suspect);
		split[2].lno = e->lno + (same - e->s_lno);
		split[2].s_lno = e->s_lno + (same - e->s_lno);
		split[2].num_lines = e->s_lno + e->num_lines - same;
		chunk_end_lno = split[2].lno;
	}
	else
		chunk_end_lno = e->lno + e->num_lines;
	split[1].num_lines = chunk_end_lno - split[1].lno;

	/*
	 * if it turns out there is nothing to blame the parent for,
	 * forget about the splitting.  !split[1].suspect signals this.
	 */
	if (split[1].num_lines < 1)
		return;
	split[1].suspect = blame_origin_incref(parent);
}

/*
 * split_overlap() divided an existing blame e into up to three parts
 * in split.  Any assigned blame is moved to queue to
 * reflect the split.
 */
static void split_blame(struct blame_entry ***blamed,
			struct blame_entry ***unblamed,
			struct blame_entry *split,
			struct blame_entry *e)
{
	if (split[0].suspect && split[2].suspect) {
		/* The first part (reuse storage for the existing entry e) */
		dup_entry(unblamed, e, &split[0]);

		/* The last part -- me */
		add_blame_entry(unblamed, &split[2]);

		/* ... and the middle part -- parent */
		add_blame_entry(blamed, &split[1]);
	}
	else if (!split[0].suspect && !split[2].suspect)
		/*
		 * The parent covers the entire area; reuse storage for
		 * e and replace it with the parent.
		 */
		dup_entry(blamed, e, &split[1]);
	else if (split[0].suspect) {
		/* me and then parent */
		dup_entry(unblamed, e, &split[0]);
		add_blame_entry(blamed, &split[1]);
	}
	else {
		/* parent and then me */
		dup_entry(blamed, e, &split[1]);
		add_blame_entry(unblamed, &split[2]);
	}
}

/*
 * After splitting the blame, the origins used by the
 * on-stack blame_entry should lose one refcnt each.
 */
static void decref_split(struct blame_entry *split)
{
	int i;

	for (i = 0; i < 3; i++)
		blame_origin_decref(split[i].suspect);
}

/*
 * reverse_blame reverses the list given in head, appending tail.
 * That allows us to build lists in reverse order, then reverse them
 * afterwards.  This can be faster than building the list in proper
 * order right away.  The reason is that building in proper order
 * requires writing a link in the _previous_ element, while building
 * in reverse order just requires placing the list head into the
 * _current_ element.
 */

static struct blame_entry *reverse_blame(struct blame_entry *head,
					 struct blame_entry *tail)
{
	while (head) {
		struct blame_entry *next = head->next;
		head->next = tail;
		tail = head;
		head = next;
	}
	return tail;
}

/*
 * Splits a blame entry into two entries at 'len' lines.  The original 'e'
 * consists of len lines, i.e. [e->lno, e->lno + len), and the second part,
 * which is returned, consists of the remainder: [e->lno + len, e->lno +
 * e->num_lines).  The caller needs to sort out the reference counting for the
 * new entry's suspect.
 */
static struct blame_entry *split_blame_at(struct blame_entry *e, int len,
					  struct blame_origin *new_suspect)
{
	struct blame_entry *n = xcalloc(1, sizeof(struct blame_entry));

	n->suspect = new_suspect;
	n->ignored = e->ignored;
	n->unblamable = e->unblamable;
	n->lno = e->lno + len;
	n->s_lno = e->s_lno + len;
	n->num_lines = e->num_lines - len;
	e->num_lines = len;
	e->score = 0;
	return n;
}

struct blame_line_tracker {
	int is_parent;
	int s_lno;
};

static int are_lines_adjacent(struct blame_line_tracker *first,
			      struct blame_line_tracker *second)
{
	return first->is_parent == second->is_parent &&
	       first->s_lno + 1 == second->s_lno;
}

static int scan_parent_range(struct fingerprint *p_fps,
			     struct fingerprint *t_fps, int t_idx,
			     int from, int nr_lines)
{
	int sim, p_idx;
	#define FINGERPRINT_FILE_THRESHOLD	10
	int best_sim_val = FINGERPRINT_FILE_THRESHOLD;
	int best_sim_idx = -1;

	for (p_idx = from; p_idx < from + nr_lines; p_idx++) {
		sim = fingerprint_similarity(&t_fps[t_idx], &p_fps[p_idx]);
		if (sim < best_sim_val)
			continue;
		/* Break ties with the closest-to-target line number */
		if (sim == best_sim_val && best_sim_idx != -1 &&
		    abs(best_sim_idx - t_idx) < abs(p_idx - t_idx))
			continue;
		best_sim_val = sim;
		best_sim_idx = p_idx;
	}
	return best_sim_idx;
}

/*
 * The first pass checks the blame entry (from the target) against the parent's
 * diff chunk.  If that fails for a line, the second pass tries to match that
 * line to any part of parent file.  That catches cases where a change was
 * broken into two chunks by 'context.'
 */
static void guess_line_blames(struct blame_origin *parent,
			      struct blame_origin *target,
			      int tlno, int offset, int same, int parent_len,
			      struct blame_line_tracker *line_blames)
{
	int i, best_idx, target_idx;
	int parent_slno = tlno + offset;
	int *fuzzy_matches;

	fuzzy_matches = fuzzy_find_matching_lines(parent, target,
						  tlno, parent_slno, same,
						  parent_len);
	for (i = 0; i < same - tlno; i++) {
		target_idx = tlno + i;
		if (fuzzy_matches && fuzzy_matches[i] >= 0) {
			best_idx = fuzzy_matches[i];
		} else {
			best_idx = scan_parent_range(parent->fingerprints,
						     target->fingerprints,
						     target_idx, 0,
						     parent->num_lines);
		}
		if (best_idx >= 0) {
			line_blames[i].is_parent = 1;
			line_blames[i].s_lno = best_idx;
		} else {
			line_blames[i].is_parent = 0;
			line_blames[i].s_lno = target_idx;
		}
	}
	free(fuzzy_matches);
}

/*
 * This decides which parts of a blame entry go to the parent (added to the
 * ignoredp list) and which stay with the target (added to the diffp list).  The
 * actual decision was made in a separate heuristic function, and those answers
 * for the lines in 'e' are in line_blames.  This consumes e, essentially
 * putting it on a list.
 *
 * Note that the blame entries on the ignoredp list are not necessarily sorted
 * with respect to the parent's line numbers yet.
 */
static void ignore_blame_entry(struct blame_entry *e,
			       struct blame_origin *parent,
			       struct blame_entry **diffp,
			       struct blame_entry **ignoredp,
			       struct blame_line_tracker *line_blames)
{
	int entry_len, nr_lines, i;

	/*
	 * We carve new entries off the front of e.  Each entry comes from a
	 * contiguous chunk of lines: adjacent lines from the same origin
	 * (either the parent or the target).
	 */
	entry_len = 1;
	nr_lines = e->num_lines;	/* e changes in the loop */
	for (i = 0; i < nr_lines; i++) {
		struct blame_entry *next = NULL;

		/*
		 * We are often adjacent to the next line - only split the blame
		 * entry when we have to.
		 */
		if (i + 1 < nr_lines) {
			if (are_lines_adjacent(&line_blames[i],
					       &line_blames[i + 1])) {
				entry_len++;
				continue;
			}
			next = split_blame_at(e, entry_len,
					      blame_origin_incref(e->suspect));
		}
		if (line_blames[i].is_parent) {
			e->ignored = 1;
			blame_origin_decref(e->suspect);
			e->suspect = blame_origin_incref(parent);
			e->s_lno = line_blames[i - entry_len + 1].s_lno;
			e->next = *ignoredp;
			*ignoredp = e;
		} else {
			e->unblamable = 1;
			/* e->s_lno is already in the target's address space. */
			e->next = *diffp;
			*diffp = e;
		}
		assert(e->num_lines == entry_len);
		e = next;
		entry_len = 1;
	}
	assert(!e);
}

/*
 * Process one hunk from the patch between the current suspect for
 * blame_entry e and its parent.  This first blames any unfinished
 * entries before the chunk (which is where target and parent start
 * differing) on the parent, and then splits blame entries at the
 * start and at the end of the difference region.  Since use of -M and
 * -C options may lead to overlapping/duplicate source line number
 * ranges, all we can rely on from sorting/merging is the order of the
 * first suspect line number.
 *
 * tlno: line number in the target where this chunk begins
 * same: line number in the target where this chunk ends
 * offset: add to tlno to get the chunk starting point in the parent
 * parent_len: number of lines in the parent chunk
 */
static void blame_chunk(struct blame_entry ***dstq, struct blame_entry ***srcq,
			int tlno, int offset, int same, int parent_len,
			struct blame_origin *parent,
			struct blame_origin *target, int ignore_diffs)
{
	struct blame_entry *e = **srcq;
	struct blame_entry *samep = NULL, *diffp = NULL, *ignoredp = NULL;
	struct blame_line_tracker *line_blames = NULL;

	while (e && e->s_lno < tlno) {
		struct blame_entry *next = e->next;
		/*
		 * current record starts before differing portion.  If
		 * it reaches into it, we need to split it up and
		 * examine the second part separately.
		 */
		if (e->s_lno + e->num_lines > tlno) {
			/* Move second half to a new record */
			struct blame_entry *n;

			n = split_blame_at(e, tlno - e->s_lno, e->suspect);
			/* Push new record to diffp */
			n->next = diffp;
			diffp = n;
		} else
			blame_origin_decref(e->suspect);
		/* Pass blame for everything before the differing
		 * chunk to the parent */
		e->suspect = blame_origin_incref(parent);
		e->s_lno += offset;
		e->next = samep;
		samep = e;
		e = next;
	}
	/*
	 * As we don't know how much of a common stretch after this
	 * diff will occur, the currently blamed parts are all that we
	 * can assign to the parent for now.
	 */

	if (samep) {
		**dstq = reverse_blame(samep, **dstq);
		*dstq = &samep->next;
	}
	/*
	 * Prepend the split off portions: everything after e starts
	 * after the blameable portion.
	 */
	e = reverse_blame(diffp, e);

	/*
	 * Now retain records on the target while parts are different
	 * from the parent.
	 */
	samep = NULL;
	diffp = NULL;

	if (ignore_diffs && same - tlno > 0) {
		CALLOC_ARRAY(line_blames, same - tlno);
		guess_line_blames(parent, target, tlno, offset, same,
				  parent_len, line_blames);
	}

	while (e && e->s_lno < same) {
		struct blame_entry *next = e->next;

		/*
		 * If current record extends into sameness, need to split.
		 */
		if (e->s_lno + e->num_lines > same) {
			/*
			 * Move second half to a new record to be
			 * processed by later chunks
			 */
			struct blame_entry *n;

			n = split_blame_at(e, same - e->s_lno,
					   blame_origin_incref(e->suspect));
			/* Push new record to samep */
			n->next = samep;
			samep = n;
		}
		if (ignore_diffs) {
			ignore_blame_entry(e, parent, &diffp, &ignoredp,
					   line_blames + e->s_lno - tlno);
		} else {
			e->next = diffp;
			diffp = e;
		}
		e = next;
	}
	free(line_blames);
	if (ignoredp) {
		/*
		 * Note ignoredp is not sorted yet, and thus neither is dstq.
		 * That list must be sorted before we queue_blames().  We defer
		 * sorting until after all diff hunks are processed, so that
		 * guess_line_blames() can pick *any* line in the parent.  The
		 * slight drawback is that we end up sorting all blame entries
		 * passed to the parent, including those that are unrelated to
		 * changes made by the ignored commit.
		 */
		**dstq = reverse_blame(ignoredp, **dstq);
		*dstq = &ignoredp->next;
	}
	**srcq = reverse_blame(diffp, reverse_blame(samep, e));
	/* Move across elements that are in the unblamable portion */
	if (diffp)
		*srcq = &diffp->next;
}

struct blame_chunk_cb_data {
	struct blame_origin *parent;
	struct blame_origin *target;
	long offset;
	int ignore_diffs;
	struct blame_entry **dstq;
	struct blame_entry **srcq;
};

/* diff chunks are from parent to target */
static int blame_chunk_cb(long start_a, long count_a,
			  long start_b, long count_b, void *data)
{
	struct blame_chunk_cb_data *d = data;
	if (start_a - start_b != d->offset)
		die("internal error in blame::blame_chunk_cb");
	blame_chunk(&d->dstq, &d->srcq, start_b, start_a - start_b,
		    start_b + count_b, count_a, d->parent, d->target,
		    d->ignore_diffs);
	d->offset = start_a + count_a - (start_b + count_b);
	return 0;
}

/*
 * We are looking at the origin 'target' and aiming to pass blame
 * for the lines it is suspected to its parent.  Run diff to find
 * which lines came from parent and pass blame for them.
 */
static void pass_blame_to_parent(struct blame_scoreboard *sb,
				 struct blame_origin *target,
				 struct blame_origin *parent, int ignore_diffs)
{
	mmfile_t file_p, file_o;
	struct blame_chunk_cb_data d;
	struct blame_entry *newdest = NULL;

	if (!target->suspects)
		return; /* nothing remains for this target */

	d.parent = parent;
	d.target = target;
	d.offset = 0;
	d.ignore_diffs = ignore_diffs;
	d.dstq = &newdest; d.srcq = &target->suspects;

	fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
			 &sb->num_read_blob, ignore_diffs);
	fill_origin_blob(&sb->revs->diffopt, target, &file_o,
			 &sb->num_read_blob, ignore_diffs);
	sb->num_get_patch++;

	if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
		die("unable to generate diff (%s -> %s)",
		    oid_to_hex(&parent->commit->object.oid),
		    oid_to_hex(&target->commit->object.oid));
	/* The rest are the same as the parent */
	blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, 0,
		    parent, target, 0);
	*d.dstq = NULL;
	if (ignore_diffs)
		sort_blame_entries(&newdest, compare_blame_suspect);
	queue_blames(sb, parent, newdest);

	return;
}

/*
 * The lines in blame_entry after splitting blames many times can become
 * very small and trivial, and at some point it becomes pointless to
 * blame the parents.  E.g. "\t\t}\n\t}\n\n" appears everywhere in any
 * ordinary C program, and it is not worth to say it was copied from
 * totally unrelated file in the parent.
 *
 * Compute how trivial the lines in the blame_entry are.
 */
unsigned blame_entry_score(struct blame_scoreboard *sb, struct blame_entry *e)
{
	unsigned score;
	const char *cp, *ep;

	if (e->score)
		return e->score;

	score = 1;
	cp = blame_nth_line(sb, e->lno);
	ep = blame_nth_line(sb, e->lno + e->num_lines);
	while (cp < ep) {
		unsigned ch = *((unsigned char *)cp);
		if (isalnum(ch))
			score++;
		cp++;
	}
	e->score = score;
	return score;
}

/*
 * best_so_far[] and potential[] are both a split of an existing blame_entry
 * that passes blame to the parent.  Maintain best_so_far the best split so
 * far, by comparing potential and best_so_far and copying potential into
 * bst_so_far as needed.
 */
static void copy_split_if_better(struct blame_scoreboard *sb,
				 struct blame_entry *best_so_far,
				 struct blame_entry *potential)
{
	int i;

	if (!potential[1].suspect)
		return;
	if (best_so_far[1].suspect) {
		if (blame_entry_score(sb, &potential[1]) <
		    blame_entry_score(sb, &best_so_far[1]))
			return;
	}

	for (i = 0; i < 3; i++)
		blame_origin_incref(potential[i].suspect);
	decref_split(best_so_far);
	memcpy(best_so_far, potential, sizeof(struct blame_entry[3]));
}

/*
 * We are looking at a part of the final image represented by
 * ent (tlno and same are offset by ent->s_lno).
 * tlno is where we are looking at in the final image.
 * up to (but not including) same match preimage.
 * plno is where we are looking at in the preimage.
 *
 * <-------------- final image ---------------------->
 *       <------ent------>
 *         ^tlno ^same
 *    <---------preimage----->
 *         ^plno
 *
 * All line numbers are 0-based.
 */
static void handle_split(struct blame_scoreboard *sb,
			 struct blame_entry *ent,
			 int tlno, int plno, int same,
			 struct blame_origin *parent,
			 struct blame_entry *split)
{
	if (ent->num_lines <= tlno)
		return;
	if (tlno < same) {
		struct blame_entry potential[3];
		tlno += ent->s_lno;
		same += ent->s_lno;
		split_overlap(potential, ent, tlno, plno, same, parent);
		copy_split_if_better(sb, split, potential);
		decref_split(potential);
	}
}

struct handle_split_cb_data {
	struct blame_scoreboard *sb;
	struct blame_entry *ent;
	struct blame_origin *parent;
	struct blame_entry *split;
	long plno;
	long tlno;
};

static int handle_split_cb(long start_a, long count_a,
			   long start_b, long count_b, void *data)
{
	struct handle_split_cb_data *d = data;
	handle_split(d->sb, d->ent, d->tlno, d->plno, start_b, d->parent,
		     d->split);
	d->plno = start_a + count_a;
	d->tlno = start_b + count_b;
	return 0;
}

/*
 * Find the lines from parent that are the same as ent so that
 * we can pass blames to it.  file_p has the blob contents for
 * the parent.
 */
static void find_copy_in_blob(struct blame_scoreboard *sb,
			      struct blame_entry *ent,
			      struct blame_origin *parent,
			      struct blame_entry *split,
			      mmfile_t *file_p)
{
	const char *cp;
	mmfile_t file_o;
	struct handle_split_cb_data d;

	memset(&d, 0, sizeof(d));
	d.sb = sb; d.ent = ent; d.parent = parent; d.split = split;
	/*
	 * Prepare mmfile that contains only the lines in ent.
	 */
	cp = blame_nth_line(sb, ent->lno);
	file_o.ptr = (char *) cp;
	file_o.size = blame_nth_line(sb, ent->lno + ent->num_lines) - cp;

	/*
	 * file_o is a part of final image we are annotating.
	 * file_p partially may match that image.
	 */
	memset(split, 0, sizeof(struct blame_entry [3]));
	if (diff_hunks(file_p, &file_o, handle_split_cb, &d, sb->xdl_opts))
		die("unable to generate diff (%s)",
		    oid_to_hex(&parent->commit->object.oid));
	/* remainder, if any, all match the preimage */
	handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
}

/* Move all blame entries from list *source that have a score smaller
 * than score_min to the front of list *small.
 * Returns a pointer to the link pointing to the old head of the small list.
 */

static struct blame_entry **filter_small(struct blame_scoreboard *sb,
					 struct blame_entry **small,
					 struct blame_entry **source,
					 unsigned score_min)
{
	struct blame_entry *p = *source;
	struct blame_entry *oldsmall = *small;
	while (p) {
		if (blame_entry_score(sb, p) <= score_min) {
			*small = p;
			small = &p->next;
			p = *small;
		} else {
			*source = p;
			source = &p->next;
			p = *source;
		}
	}
	*small = oldsmall;
	*source = NULL;
	return small;
}

/*
 * See if lines currently target is suspected for can be attributed to
 * parent.
 */
static void find_move_in_parent(struct blame_scoreboard *sb,
				struct blame_entry ***blamed,
				struct blame_entry **toosmall,
				struct blame_origin *target,
				struct blame_origin *parent)
{
	struct blame_entry *e, split[3];
	struct blame_entry *unblamed = target->suspects;
	struct blame_entry *leftover = NULL;
	mmfile_t file_p;

	if (!unblamed)
		return; /* nothing remains for this target */

	fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
			 &sb->num_read_blob, 0);
	if (!file_p.ptr)
		return;

	/* At each iteration, unblamed has a NULL-terminated list of
	 * entries that have not yet been tested for blame.  leftover
	 * contains the reversed list of entries that have been tested
	 * without being assignable to the parent.
	 */
	do {
		struct blame_entry **unblamedtail = &unblamed;
		struct blame_entry *next;
		for (e = unblamed; e; e = next) {
			next = e->next;
			find_copy_in_blob(sb, e, parent, split, &file_p);
			if (split[1].suspect &&
			    sb->move_score < blame_entry_score(sb, &split[1])) {
				split_blame(blamed, &unblamedtail, split, e);
			} else {
				e->next = leftover;
				leftover = e;
			}
			decref_split(split);
		}
		*unblamedtail = NULL;
		toosmall = filter_small(sb, toosmall, &unblamed, sb->move_score);
	} while (unblamed);
	target->suspects = reverse_blame(leftover, NULL);
}

struct blame_list {
	struct blame_entry *ent;
	struct blame_entry split[3];
};

/*
 * Count the number of entries the target is suspected for,
 * and prepare a list of entry and the best split.
 */
static struct blame_list *setup_blame_list(struct blame_entry *unblamed,
					   int *num_ents_p)
{
	struct blame_entry *e;
	int num_ents, i;
	struct blame_list *blame_list = NULL;

	for (e = unblamed, num_ents = 0; e; e = e->next)
		num_ents++;
	if (num_ents) {
		CALLOC_ARRAY(blame_list, num_ents);
		for (e = unblamed, i = 0; e; e = e->next)
			blame_list[i++].ent = e;
	}
	*num_ents_p = num_ents;
	return blame_list;
}

/*
 * For lines target is suspected for, see if we can find code movement
 * across file boundary from the parent commit.  porigin is the path
 * in the parent we already tried.
 */
static void find_copy_in_parent(struct blame_scoreboard *sb,
				struct blame_entry ***blamed,
				struct blame_entry **toosmall,
				struct blame_origin *target,
				struct commit *parent,
				struct blame_origin *porigin,
				int opt)
{
	struct diff_options diff_opts;
	int i, j;
	struct blame_list *blame_list;
	int num_ents;
	struct blame_entry *unblamed = target->suspects;
	struct blame_entry *leftover = NULL;

	if (!unblamed)
		return; /* nothing remains for this target */

	repo_diff_setup(sb->repo, &diff_opts);
	diff_opts.flags.recursive = 1;
	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;

	diff_setup_done(&diff_opts);

	/* Try "find copies harder" on new path if requested;
	 * we do not want to use diffcore_rename() actually to
	 * match things up; find_copies_harder is set only to
	 * force diff_tree_oid() to feed all filepairs to diff_queue,
	 * and this code needs to be after diff_setup_done(), which
	 * usually makes find-copies-harder imply copy detection.
	 */
	if ((opt & PICKAXE_BLAME_COPY_HARDEST)
	    || ((opt & PICKAXE_BLAME_COPY_HARDER)
		&& (!porigin || strcmp(target->path, porigin->path))))
		diff_opts.flags.find_copies_harder = 1;

	if (is_null_oid(&target->commit->object.oid))
		do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
	else
		diff_tree_oid(get_commit_tree_oid(parent),
			      get_commit_tree_oid(target->commit),
			      "", &diff_opts);

	if (!diff_opts.flags.find_copies_harder)
		diffcore_std(&diff_opts);

	do {
		struct blame_entry **unblamedtail = &unblamed;
		blame_list = setup_blame_list(unblamed, &num_ents);

		for (i = 0; i < diff_queued_diff.nr; i++) {
			struct diff_filepair *p = diff_queued_diff.queue[i];
			struct blame_origin *norigin;
			mmfile_t file_p;
			struct blame_entry potential[3];

			if (!DIFF_FILE_VALID(p->one))
				continue; /* does not exist in parent */
			if (S_ISGITLINK(p->one->mode))
				continue; /* ignore git links */
			if (porigin && !strcmp(p->one->path, porigin->path))
				/* find_move already dealt with this path */
				continue;

			norigin = get_origin(parent, p->one->path);
			oidcpy(&norigin->blob_oid, &p->one->oid);
			norigin->mode = p->one->mode;
			fill_origin_blob(&sb->revs->diffopt, norigin, &file_p,
					 &sb->num_read_blob, 0);
			if (!file_p.ptr)
				continue;

			for (j = 0; j < num_ents; j++) {
				find_copy_in_blob(sb, blame_list[j].ent,
						  norigin, potential, &file_p);
				copy_split_if_better(sb, blame_list[j].split,
						     potential);
				decref_split(potential);
			}
			blame_origin_decref(norigin);
		}

		for (j = 0; j < num_ents; j++) {
			struct blame_entry *split = blame_list[j].split;
			if (split[1].suspect &&
			    sb->copy_score < blame_entry_score(sb, &split[1])) {
				split_blame(blamed, &unblamedtail, split,
					    blame_list[j].ent);
			} else {
				blame_list[j].ent->next = leftover;
				leftover = blame_list[j].ent;
			}
			decref_split(split);
		}
		free(blame_list);
		*unblamedtail = NULL;
		toosmall = filter_small(sb, toosmall, &unblamed, sb->copy_score);
	} while (unblamed);
	target->suspects = reverse_blame(leftover, NULL);
	diff_flush(&diff_opts);
}

/*
 * The blobs of origin and porigin exactly match, so everything
 * origin is suspected for can be blamed on the parent.
 */
static void pass_whole_blame(struct blame_scoreboard *sb,
			     struct blame_origin *origin, struct blame_origin *porigin)
{
	struct blame_entry *e, *suspects;

	if (!porigin->file.ptr && origin->file.ptr) {
		/* Steal its file */
		porigin->file = origin->file;
		origin->file.ptr = NULL;
	}
	suspects = origin->suspects;
	origin->suspects = NULL;
	for (e = suspects; e; e = e->next) {
		blame_origin_incref(porigin);
		blame_origin_decref(e->suspect);
		e->suspect = porigin;
	}
	queue_blames(sb, porigin, suspects);
}

/*
 * We pass blame from the current commit to its parents.  We keep saying
 * "parent" (and "porigin"), but what we mean is to find scapegoat to
 * exonerate ourselves.
 */
static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit,
					int reverse)
{
	if (!reverse) {
		if (revs->first_parent_only &&
		    commit->parents &&
		    commit->parents->next) {
			free_commit_list(commit->parents->next);
			commit->parents->next = NULL;
		}
		return commit->parents;
	}
	return lookup_decoration(&revs->children, &commit->object);
}

static int num_scapegoats(struct rev_info *revs, struct commit *commit, int reverse)
{
	struct commit_list *l = first_scapegoat(revs, commit, reverse);
	return commit_list_count(l);
}

/* Distribute collected unsorted blames to the respected sorted lists
 * in the various origins.
 */
static void distribute_blame(struct blame_scoreboard *sb, struct blame_entry *blamed)
{
	sort_blame_entries(&blamed, compare_blame_suspect);
	while (blamed)
	{
		struct blame_origin *porigin = blamed->suspect;
		struct blame_entry *suspects = NULL;
		do {
			struct blame_entry *next = blamed->next;
			blamed->next = suspects;
			suspects = blamed;
			blamed = next;
		} while (blamed && blamed->suspect == porigin);
		suspects = reverse_blame(suspects, NULL);
		queue_blames(sb, porigin, suspects);
	}
}

#define MAXSG 16

typedef struct blame_origin *(*blame_find_alg)(struct repository *,
					       struct commit *,
					       struct blame_origin *,
					       struct blame_bloom_data *);

static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin, int opt)
{
	struct rev_info *revs = sb->revs;
	int i, pass, num_sg;
	struct commit *commit = origin->commit;
	struct commit_list *sg;
	struct blame_origin *sg_buf[MAXSG];
	struct blame_origin *porigin, **sg_origin = sg_buf;
	struct blame_entry *toosmall = NULL;
	struct blame_entry *blames, **blametail = &blames;

	num_sg = num_scapegoats(revs, commit, sb->reverse);
	if (!num_sg)
		goto finish;
	else if (num_sg < ARRAY_SIZE(sg_buf))
		memset(sg_buf, 0, sizeof(sg_buf));
	else
		CALLOC_ARRAY(sg_origin, num_sg);

	/*
	 * The first pass looks for unrenamed path to optimize for
	 * common cases, then we look for renames in the second pass.
	 */
	for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) {
		blame_find_alg find = pass ? find_rename : find_origin;

		for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
		     i < num_sg && sg;
		     sg = sg->next, i++) {
			struct commit *p = sg->item;
			int j, same;

			if (sg_origin[i])
				continue;
			if (repo_parse_commit(the_repository, p))
				continue;
			porigin = find(sb->repo, p, origin, sb->bloom_data);
			if (!porigin)
				continue;
			if (oideq(&porigin->blob_oid, &origin->blob_oid)) {
				pass_whole_blame(sb, origin, porigin);
				blame_origin_decref(porigin);
				goto finish;
			}
			for (j = same = 0; j < i; j++)
				if (sg_origin[j] &&
				    oideq(&sg_origin[j]->blob_oid, &porigin->blob_oid)) {
					same = 1;
					break;
				}
			if (!same)
				sg_origin[i] = porigin;
			else
				blame_origin_decref(porigin);
		}
	}

	sb->num_commits++;
	for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
	     i < num_sg && sg;
	     sg = sg->next, i++) {
		struct blame_origin *porigin = sg_origin[i];
		if (!porigin)
			continue;
		if (!origin->previous) {
			blame_origin_incref(porigin);
			origin->previous = porigin;
		}
		pass_blame_to_parent(sb, origin, porigin, 0);
		if (!origin->suspects)
			goto finish;
	}

	/*
	 * Pass remaining suspects for ignored commits to their parents.
	 */
	if (oidset_contains(&sb->ignore_list, &commit->object.oid)) {
		for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
		     i < num_sg && sg;
		     sg = sg->next, i++) {
			struct blame_origin *porigin = sg_origin[i];

			if (!porigin)
				continue;
			pass_blame_to_parent(sb, origin, porigin, 1);
			/*
			 * Preemptively drop porigin so we can refresh the
			 * fingerprints if we use the parent again, which can
			 * occur if you ignore back-to-back commits.
			 */
			drop_origin_blob(porigin);
			if (!origin->suspects)
				goto finish;
		}
	}

	/*
	 * Optionally find moves in parents' files.
	 */
	if (opt & PICKAXE_BLAME_MOVE) {
		filter_small(sb, &toosmall, &origin->suspects, sb->move_score);
		if (origin->suspects) {
			for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
			     i < num_sg && sg;
			     sg = sg->next, i++) {
				struct blame_origin *porigin = sg_origin[i];
				if (!porigin)
					continue;
				find_move_in_parent(sb, &blametail, &toosmall, origin, porigin);
				if (!origin->suspects)
					break;
			}
		}
	}

	/*
	 * Optionally find copies from parents' files.
	 */
	if (opt & PICKAXE_BLAME_COPY) {
		if (sb->copy_score > sb->move_score)
			filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
		else if (sb->copy_score < sb->move_score) {
			origin->suspects = blame_merge(origin->suspects, toosmall);
			toosmall = NULL;
			filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
		}
		if (!origin->suspects)
			goto finish;

		for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
		     i < num_sg && sg;
		     sg = sg->next, i++) {
			struct blame_origin *porigin = sg_origin[i];
			find_copy_in_parent(sb, &blametail, &toosmall,
					    origin, sg->item, porigin, opt);
			if (!origin->suspects)
				goto finish;
		}
	}

finish:
	*blametail = NULL;
	distribute_blame(sb, blames);
	/*
	 * prepend toosmall to origin->suspects
	 *
	 * There is no point in sorting: this ends up on a big
	 * unsorted list in the caller anyway.
	 */
	if (toosmall) {
		struct blame_entry **tail = &toosmall;
		while (*tail)
			tail = &(*tail)->next;
		*tail = origin->suspects;
		origin->suspects = toosmall;
	}
	for (i = 0; i < num_sg; i++) {
		if (sg_origin[i]) {
			if (!sg_origin[i]->suspects)
				drop_origin_blob(sg_origin[i]);
			blame_origin_decref(sg_origin[i]);
		}
	}
	drop_origin_blob(origin);
	if (sg_buf != sg_origin)
		free(sg_origin);
}

/*
 * The main loop -- while we have blobs with lines whose true origin
 * is still unknown, pick one blob, and allow its lines to pass blames
 * to its parents. */
void assign_blame(struct blame_scoreboard *sb, int opt)
{
	struct rev_info *revs = sb->revs;
	struct commit *commit = prio_queue_get(&sb->commits);

	while (commit) {
		struct blame_entry *ent;
		struct blame_origin *suspect = get_blame_suspects(commit);

		/* find one suspect to break down */
		while (suspect && !suspect->suspects)
			suspect = suspect->next;

		if (!suspect) {
			commit = prio_queue_get(&sb->commits);
			continue;
		}

		assert(commit == suspect->commit);

		/*
		 * We will use this suspect later in the loop,
		 * so hold onto it in the meantime.
		 */
		blame_origin_incref(suspect);
		repo_parse_commit(the_repository, commit);
		if (sb->reverse ||
		    (!(commit->object.flags & UNINTERESTING) &&
		     !(revs->max_age != -1 && commit->date < revs->max_age)))
			pass_blame(sb, suspect, opt);
		else {
			commit->object.flags |= UNINTERESTING;
			if (commit->object.parsed)
				mark_parents_uninteresting(sb->revs, commit);
		}
		/* treat root commit as boundary */
		if (!commit->parents && !sb->show_root)
			commit->object.flags |= UNINTERESTING;

		/* Take responsibility for the remaining entries */
		ent = suspect->suspects;
		if (ent) {
			suspect->guilty = 1;
			for (;;) {
				struct blame_entry *next = ent->next;
				if (sb->found_guilty_entry)
					sb->found_guilty_entry(ent, sb->found_guilty_entry_data);
				if (next) {
					ent = next;
					continue;
				}
				ent->next = sb->ent;
				sb->ent = suspect->suspects;
				suspect->suspects = NULL;
				break;
			}
		}
		blame_origin_decref(suspect);

		if (sb->debug) /* sanity */
			sanity_check_refcnt(sb);
	}
}

/*
 * To allow quick access to the contents of nth line in the
 * final image, prepare an index in the scoreboard.
 */
static int prepare_lines(struct blame_scoreboard *sb)
{
	sb->num_lines = find_line_starts(&sb->lineno, sb->final_buf,
					 sb->final_buf_size);
	return sb->num_lines;
}

static struct commit *find_single_final(struct rev_info *revs,
					const char **name_p)
{
	int i;
	struct commit *found = NULL;
	const char *name = NULL;

	for (i = 0; i < revs->pending.nr; i++) {
		struct object *obj = revs->pending.objects[i].item;
		if (obj->flags & UNINTERESTING)
			continue;
		obj = deref_tag(revs->repo, obj, NULL, 0);
		if (!obj || obj->type != OBJ_COMMIT)
			die("Non commit %s?", revs->pending.objects[i].name);
		if (found)
			die("More than one commit to dig from %s and %s?",
			    revs->pending.objects[i].name, name);
		found = (struct commit *)obj;
		name = revs->pending.objects[i].name;
	}
	if (name_p)
		*name_p = xstrdup_or_null(name);
	return found;
}

static struct commit *dwim_reverse_initial(struct rev_info *revs,
					   const char **name_p)
{
	/*
	 * DWIM "git blame --reverse ONE -- PATH" as
	 * "git blame --reverse ONE..HEAD -- PATH" but only do so
	 * when it makes sense.
	 */
	struct object *obj;
	struct commit *head_commit;
	struct object_id head_oid;

	if (revs->pending.nr != 1)
		return NULL;

	/* Is that sole rev a committish? */
	obj = revs->pending.objects[0].item;
	obj = deref_tag(revs->repo, obj, NULL, 0);
	if (!obj || obj->type != OBJ_COMMIT)
		return NULL;

	/* Do we have HEAD? */
	if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
		return NULL;
	head_commit = lookup_commit_reference_gently(revs->repo,
						     &head_oid, 1);
	if (!head_commit)
		return NULL;

	/* Turn "ONE" into "ONE..HEAD" then */
	obj->flags |= UNINTERESTING;
	add_pending_object(revs, &head_commit->object, "HEAD");

	if (name_p)
		*name_p = revs->pending.objects[0].name;
	return (struct commit *)obj;
}

static struct commit *find_single_initial(struct rev_info *revs,
					  const char **name_p)
{
	int i;
	struct commit *found = NULL;
	const char *name = NULL;

	/*
	 * There must be one and only one negative commit, and it must be
	 * the boundary.
	 */
	for (i = 0; i < revs->pending.nr; i++) {
		struct object *obj = revs->pending.objects[i].item;
		if (!(obj->flags & UNINTERESTING))
			continue;
		obj = deref_tag(revs->repo, obj, NULL, 0);
		if (!obj || obj->type != OBJ_COMMIT)
			die("Non commit %s?", revs->pending.objects[i].name);
		if (found)
			die("More than one commit to dig up from, %s and %s?",
			    revs->pending.objects[i].name, name);
		found = (struct commit *) obj;
		name = revs->pending.objects[i].name;
	}

	if (!name)
		found = dwim_reverse_initial(revs, &name);
	if (!name)
		die("No commit to dig up from?");

	if (name_p)
		*name_p = xstrdup(name);
	return found;
}

void init_scoreboard(struct blame_scoreboard *sb)
{
	memset(sb, 0, sizeof(struct blame_scoreboard));
	sb->move_score = BLAME_DEFAULT_MOVE_SCORE;
	sb->copy_score = BLAME_DEFAULT_COPY_SCORE;
}

void setup_scoreboard(struct blame_scoreboard *sb,
		      struct blame_origin **orig)
{
	const char *final_commit_name = NULL;
	struct blame_origin *o;
	struct commit *final_commit = NULL;
	enum object_type type;

	init_blame_suspects(&blame_suspects);

	if (sb->reverse && sb->contents_from)
		die(_("--contents and --reverse do not blend well."));

	if (!sb->repo)
		BUG("repo is NULL");

	if (!sb->reverse) {
		sb->final = find_single_final(sb->revs, &final_commit_name);
		sb->commits.compare = compare_commits_by_commit_date;
	} else {
		sb->final = find_single_initial(sb->revs, &final_commit_name);
		sb->commits.compare = compare_commits_by_reverse_commit_date;
	}

	if (sb->reverse && sb->revs->first_parent_only)
		sb->revs->children.name = NULL;

	if (sb->contents_from || !sb->final) {
		struct object_id head_oid, *parent_oid;

		/*
		 * Build a fake commit at the top of the history, when
		 * (1) "git blame [^A] --path", i.e. with no positive end
		 *     of the history range, in which case we build such
		 *     a fake commit on top of the HEAD to blame in-tree
		 *     modifications.
		 * (2) "git blame --contents=file [A] -- path", with or
		 *     without positive end of the history range but with
		 *     --contents, in which case we pretend that there is
		 *     a fake commit on top of the positive end (defaulting to
		 *     HEAD) that has the given contents in the path.
		 */
		if (sb->final) {
			parent_oid = &sb->final->object.oid;
		} else {
			if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
				die("no such ref: HEAD");
			parent_oid = &head_oid;
		}

		if (!sb->contents_from)
			setup_work_tree();

		sb->final = fake_working_tree_commit(sb->repo,
						     &sb->revs->diffopt,
						     sb->path, sb->contents_from,
						     parent_oid);
		add_pending_object(sb->revs, &(sb->final->object), ":");
	}

	if (sb->reverse && sb->revs->first_parent_only) {
		final_commit = find_single_final(sb->revs, NULL);
		if (!final_commit)
			die(_("--reverse and --first-parent together require specified latest commit"));
	}

	/*
	 * If we have bottom, this will mark the ancestors of the
	 * bottom commits we would reach while traversing as
	 * uninteresting.
	 */
	if (prepare_revision_walk(sb->revs))
		die(_("revision walk setup failed"));

	if (sb->reverse && sb->revs->first_parent_only) {
		struct commit *c = final_commit;

		sb->revs->children.name = "children";
		while (c->parents &&
		       !oideq(&c->object.oid, &sb->final->object.oid)) {
			struct commit_list *l = xcalloc(1, sizeof(*l));

			l->item = c;
			if (add_decoration(&sb->revs->children,
					   &c->parents->item->object, l))
				BUG("not unique item in first-parent chain");
			c = c->parents->item;
		}

		if (!oideq(&c->object.oid, &sb->final->object.oid))
			die(_("--reverse --first-parent together require range along first-parent chain"));
	}

	if (is_null_oid(&sb->final->object.oid)) {
		o = get_blame_suspects(sb->final);
		sb->final_buf = xmemdupz(o->file.ptr, o->file.size);
		sb->final_buf_size = o->file.size;
	}
	else {
		o = get_origin(sb->final, sb->path);
		if (fill_blob_sha1_and_mode(sb->repo, o))
			die(_("no such path %s in %s"), sb->path, final_commit_name);

		if (sb->revs->diffopt.flags.allow_textconv &&
		    textconv_object(sb->repo, sb->path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
				    &sb->final_buf_size))
			;
		else
			sb->final_buf = repo_read_object_file(the_repository,
							      &o->blob_oid,
							      &type,
							      &sb->final_buf_size);

		if (!sb->final_buf)
			die(_("cannot read blob %s for path %s"),
			    oid_to_hex(&o->blob_oid),
			    sb->path);
	}
	sb->num_read_blob++;
	prepare_lines(sb);

	if (orig)
		*orig = o;

	free((char *)final_commit_name);
}



struct blame_entry *blame_entry_prepend(struct blame_entry *head,
					long start, long end,
					struct blame_origin *o)
{
	struct blame_entry *new_head = xcalloc(1, sizeof(struct blame_entry));
	new_head->lno = start;
	new_head->num_lines = end - start;
	new_head->suspect = o;
	new_head->s_lno = start;
	new_head->next = head;
	blame_origin_incref(o);
	return new_head;
}

void setup_blame_bloom_data(struct blame_scoreboard *sb)
{
	struct blame_bloom_data *bd;
	struct bloom_filter_settings *bs;

	if (!sb->repo->objects->commit_graph)
		return;

	bs = get_bloom_filter_settings(sb->repo);
	if (!bs)
		return;

	bd = xmalloc(sizeof(struct blame_bloom_data));

	bd->settings = bs;

	bd->alloc = 4;
	bd->nr = 0;
	ALLOC_ARRAY(bd->keys, bd->alloc);

	add_bloom_key(bd, sb->path);

	sb->bloom_data = bd;
}

void cleanup_scoreboard(struct blame_scoreboard *sb)
{
	if (sb->bloom_data) {
		int i;
		for (i = 0; i < sb->bloom_data->nr; i++) {
			free(sb->bloom_data->keys[i]->hashes);
			free(sb->bloom_data->keys[i]);
		}
		free(sb->bloom_data->keys);
		FREE_AND_NULL(sb->bloom_data);

		trace2_data_intmax("blame", sb->repo,
				   "bloom/queries", bloom_count_queries);
		trace2_data_intmax("blame", sb->repo,
				   "bloom/response-no", bloom_count_no);
	}
}
