/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 */

#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "config.h"
#include "date.h"
#include "diff.h"
#include "diffcore.h"
#include "hex.h"
#include "tempfile.h"
#include "lockfile.h"
#include "cache-tree.h"
#include "refs.h"
#include "dir.h"
#include "object-file.h"
#include "odb.h"
#include "odb/transaction.h"
#include "oid-array.h"
#include "tree.h"
#include "commit.h"
#include "environment.h"
#include "gettext.h"
#include "mem-pool.h"
#include "name-hash.h"
#include "object-name.h"
#include "path.h"
#include "preload-index.h"
#include "read-cache.h"
#include "repository.h"
#include "resolve-undo.h"
#include "revision.h"
#include "strbuf.h"
#include "trace2.h"
#include "varint.h"
#include "split-index.h"
#include "symlinks.h"
#include "utf8.h"
#include "fsmonitor.h"
#include "thread-utils.h"
#include "progress.h"
#include "sparse-index.h"
#include "csum-file.h"
#include "promisor-remote.h"
#include "hook.h"
#include "submodule.h"
#include "submodule-config.h"
#include "advice.h"

/* Mask for the name length in ce_flags in the on-disk index */

#define CE_NAMEMASK  (0x0fff)

/* Index extensions.
 *
 * The first letter should be 'A'..'Z' for extensions that are not
 * necessary for a correct operation (i.e. optimization data).
 * When new extensions are added that _needs_ to be understood in
 * order to correctly interpret the index file, pick character that
 * is outside the range, to cause the reader to abort.
 */

#define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
#define CACHE_EXT_TREE 0x54524545	/* "TREE" */
#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */
#define CACHE_EXT_LINK 0x6c696e6b	  /* "link" */
#define CACHE_EXT_UNTRACKED 0x554E5452	  /* "UNTR" */
#define CACHE_EXT_FSMONITOR 0x46534D4E	  /* "FSMN" */
#define CACHE_EXT_ENDOFINDEXENTRIES 0x454F4945	/* "EOIE" */
#define CACHE_EXT_INDEXENTRYOFFSETTABLE 0x49454F54 /* "IEOT" */
#define CACHE_EXT_SPARSE_DIRECTORIES 0x73646972 /* "sdir" */

/* changes that can be kept in $GIT_DIR/index (basically all extensions) */
#define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \
		 CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED | \
		 SPLIT_INDEX_ORDERED | UNTRACKED_CHANGED | FSMONITOR_CHANGED)


/*
 * This is an estimate of the pathname length in the index.  We use
 * this for V4 index files to guess the un-deltafied size of the index
 * in memory because of pathname deltafication.  This is not required
 * for V2/V3 index formats because their pathnames are not compressed.
 * If the initial amount of memory set aside is not sufficient, the
 * mem pool will allocate extra memory.
 */
#define CACHE_ENTRY_PATH_LENGTH 80

enum index_search_mode {
	NO_EXPAND_SPARSE = 0,
	EXPAND_SPARSE = 1
};

static inline struct cache_entry *mem_pool__ce_alloc(struct mem_pool *mem_pool, size_t len)
{
	struct cache_entry *ce;
	ce = mem_pool_alloc(mem_pool, cache_entry_size(len));
	ce->mem_pool_allocated = 1;
	return ce;
}

static inline struct cache_entry *mem_pool__ce_calloc(struct mem_pool *mem_pool, size_t len)
{
	struct cache_entry * ce;
	ce = mem_pool_calloc(mem_pool, 1, cache_entry_size(len));
	ce->mem_pool_allocated = 1;
	return ce;
}

static struct mem_pool *find_mem_pool(struct index_state *istate)
{
	struct mem_pool **pool_ptr;

	if (istate->split_index && istate->split_index->base)
		pool_ptr = &istate->split_index->base->ce_mem_pool;
	else
		pool_ptr = &istate->ce_mem_pool;

	if (!*pool_ptr) {
		*pool_ptr = xmalloc(sizeof(**pool_ptr));
		mem_pool_init(*pool_ptr, 0);
	}

	return *pool_ptr;
}

static const char *alternate_index_output;

static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
{
	if (S_ISSPARSEDIR(ce->ce_mode))
		istate->sparse_index = INDEX_COLLAPSED;

	istate->cache[nr] = ce;
	add_name_hash(istate, ce);
}

static void replace_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
{
	struct cache_entry *old = istate->cache[nr];

	replace_index_entry_in_base(istate, old, ce);
	remove_name_hash(istate, old);
	discard_cache_entry(old);
	ce->ce_flags &= ~CE_HASHED;
	set_index_entry(istate, nr, ce);
	ce->ce_flags |= CE_UPDATE_IN_BASE;
	mark_fsmonitor_invalid(istate, ce);
	istate->cache_changed |= CE_ENTRY_CHANGED;
}

void rename_index_entry_at(struct index_state *istate, int nr, const char *new_name)
{
	struct cache_entry *old_entry = istate->cache[nr], *new_entry, *refreshed;
	int namelen = strlen(new_name);

	new_entry = make_empty_cache_entry(istate, namelen);
	copy_cache_entry(new_entry, old_entry);
	new_entry->ce_flags &= ~CE_HASHED;
	new_entry->ce_namelen = namelen;
	new_entry->index = 0;
	memcpy(new_entry->name, new_name, namelen + 1);

	cache_tree_invalidate_path(istate, old_entry->name);
	untracked_cache_remove_from_index(istate, old_entry->name);
	remove_index_entry_at(istate, nr);

	/*
	 * Refresh the new index entry. Using 'refresh_cache_entry' ensures
	 * we only update stat info if the entry is otherwise up-to-date (i.e.,
	 * the contents/mode haven't changed). This ensures that we reflect the
	 * 'ctime' of the rename in the index without (incorrectly) updating
	 * the cached stat info to reflect unstaged changes on disk.
	 */
	refreshed = refresh_cache_entry(istate, new_entry, CE_MATCH_REFRESH);
	if (refreshed && refreshed != new_entry) {
		add_index_entry(istate, refreshed, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
		discard_cache_entry(new_entry);
	} else
		add_index_entry(istate, new_entry, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
}

/*
 * This only updates the "non-critical" parts of the directory
 * cache, ie the parts that aren't tracked by GIT, and only used
 * to validate the cache.
 */
void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st)
{
	fill_stat_data(&ce->ce_stat_data, st);

	if (assume_unchanged)
		ce->ce_flags |= CE_VALID;

	if (S_ISREG(st->st_mode)) {
		ce_mark_uptodate(ce);
		mark_fsmonitor_valid(istate, ce);
	}
}

static unsigned int st_mode_from_ce(const struct cache_entry *ce)
{
	extern int trust_executable_bit, has_symlinks;

	switch (ce->ce_mode & S_IFMT) {
	case S_IFLNK:
		return has_symlinks ? S_IFLNK : (S_IFREG | 0644);
	case S_IFREG:
		return (ce->ce_mode & (trust_executable_bit ? 0755 : 0644)) | S_IFREG;
	case S_IFGITLINK:
		return S_IFDIR | 0755;
	case S_IFDIR:
		return ce->ce_mode;
	default:
		BUG("unsupported ce_mode: %o", ce->ce_mode);
	}
}

int fake_lstat(const struct cache_entry *ce, struct stat *st)
{
	fake_lstat_data(&ce->ce_stat_data, st);
	st->st_mode = st_mode_from_ce(ce);

	/* always succeed as lstat() replacement */
	return 0;
}

static int ce_compare_data(struct index_state *istate,
			   const struct cache_entry *ce,
			   struct stat *st)
{
	int match = -1;
	int fd = git_open_cloexec(ce->name, O_RDONLY);

	if (fd >= 0) {
		struct object_id oid;
		if (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0))
			match = !oideq(&oid, &ce->oid);
		/* index_fd() closed the file descriptor already */
	}
	return match;
}

static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
{
	int match = -1;
	void *buffer;
	size_t size;
	enum object_type type;
	struct strbuf sb = STRBUF_INIT;

	if (strbuf_readlink(&sb, ce->name, expected_size))
		return -1;

	buffer = odb_read_object(the_repository->objects, &ce->oid, &type, &size);
	if (buffer) {
		if (size == sb.len)
			match = memcmp(buffer, sb.buf, size);
		free(buffer);
	}
	strbuf_release(&sb);
	return match;
}

static int ce_compare_gitlink(const struct cache_entry *ce)
{
	struct object_id oid;

	/*
	 * We don't actually require that the .git directory
	 * under GITLINK directory be a valid git directory. It
	 * might even be missing (in case nobody populated that
	 * sub-project).
	 *
	 * If so, we consider it always to match.
	 */
	if (repo_resolve_gitlink_ref(the_repository, ce->name,
				     "HEAD", &oid) < 0)
		return 0;
	return !oideq(&oid, &ce->oid);
}

static int ce_modified_check_fs(struct index_state *istate,
				const struct cache_entry *ce,
				struct stat *st)
{
	switch (st->st_mode & S_IFMT) {
	case S_IFREG:
		if (ce_compare_data(istate, ce, st))
			return DATA_CHANGED;
		break;
	case S_IFLNK:
		if (ce_compare_link(ce, xsize_t(st->st_size)))
			return DATA_CHANGED;
		break;
	case S_IFDIR:
		if (S_ISGITLINK(ce->ce_mode))
			return ce_compare_gitlink(ce) ? DATA_CHANGED : 0;
		/* else fallthrough */
	default:
		return TYPE_CHANGED;
	}
	return 0;
}

static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
{
	unsigned int changed = 0;

	if (ce->ce_flags & CE_REMOVE)
		return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED;

	switch (ce->ce_mode & S_IFMT) {
	case S_IFREG:
		changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0;
		/* We consider only the owner x bit to be relevant for
		 * "mode changes"
		 */
		if (trust_executable_bit &&
		    (0100 & (ce->ce_mode ^ st->st_mode)))
			changed |= MODE_CHANGED;
		break;
	case S_IFLNK:
		if (!S_ISLNK(st->st_mode) &&
		    (has_symlinks || !S_ISREG(st->st_mode)))
			changed |= TYPE_CHANGED;
		break;
	case S_IFGITLINK:
		/* We ignore most of the st_xxx fields for gitlinks */
		if (!S_ISDIR(st->st_mode))
			changed |= TYPE_CHANGED;
		else if (ce_compare_gitlink(ce))
			changed |= DATA_CHANGED;
		return changed;
	default:
		BUG("unsupported ce_mode: %o", ce->ce_mode);
	}

	changed |= match_stat_data(&ce->ce_stat_data, st);

	/* Racily smudged entry? */
	if (!ce->ce_stat_data.sd_size) {
		if (!is_empty_blob_oid(&ce->oid, the_repository->hash_algo))
			changed |= DATA_CHANGED;
	}

	return changed;
}

static int is_racy_stat(const struct index_state *istate,
			const struct stat_data *sd)
{
	return (istate->timestamp.sec &&
#ifdef USE_NSEC
		 /* nanosecond timestamped files can also be racy! */
		(istate->timestamp.sec < sd->sd_mtime.sec ||
		 (istate->timestamp.sec == sd->sd_mtime.sec &&
		  istate->timestamp.nsec <= sd->sd_mtime.nsec))
#else
		istate->timestamp.sec <= sd->sd_mtime.sec
#endif
		);
}

int is_racy_timestamp(const struct index_state *istate,
			     const struct cache_entry *ce)
{
	return (!S_ISGITLINK(ce->ce_mode) &&
		is_racy_stat(istate, &ce->ce_stat_data));
}

int match_stat_data_racy(const struct index_state *istate,
			 const struct stat_data *sd, struct stat *st)
{
	if (is_racy_stat(istate, sd))
		return MTIME_CHANGED;
	return match_stat_data(sd, st);
}

int ie_match_stat(struct index_state *istate,
		  const struct cache_entry *ce, struct stat *st,
		  unsigned int options)
{
	unsigned int changed;
	int ignore_valid = options & CE_MATCH_IGNORE_VALID;
	int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
	int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY;
	int ignore_fsmonitor = options & CE_MATCH_IGNORE_FSMONITOR;

	if (!ignore_fsmonitor)
		refresh_fsmonitor(istate);
	/*
	 * If it's marked as always valid in the index, it's
	 * valid whatever the checked-out copy says.
	 *
	 * skip-worktree has the same effect with higher precedence
	 */
	if (!ignore_skip_worktree && ce_skip_worktree(ce))
		return 0;
	if (!ignore_valid && (ce->ce_flags & CE_VALID))
		return 0;
	if (!ignore_fsmonitor && (ce->ce_flags & CE_FSMONITOR_VALID))
		return 0;

	/*
	 * Intent-to-add entries have not been added, so the index entry
	 * by definition never matches what is in the work tree until it
	 * actually gets added.
	 */
	if (ce_intent_to_add(ce))
		return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED;

	changed = ce_match_stat_basic(ce, st);

	/*
	 * Within 1 second of this sequence:
	 * 	echo xyzzy >file && git-update-index --add file
	 * running this command:
	 * 	echo frotz >file
	 * would give a falsely clean cache entry.  The mtime and
	 * length match the cache, and other stat fields do not change.
	 *
	 * We could detect this at update-index time (the cache entry
	 * being registered/updated records the same time as "now")
	 * and delay the return from git-update-index, but that would
	 * effectively mean we can make at most one commit per second,
	 * which is not acceptable.  Instead, we check cache entries
	 * whose mtime are the same as the index file timestamp more
	 * carefully than others.
	 */
	if (!changed && is_racy_timestamp(istate, ce)) {
		if (assume_racy_is_modified)
			changed |= DATA_CHANGED;
		else
			changed |= ce_modified_check_fs(istate, ce, st);
	}

	return changed;
}

int ie_modified(struct index_state *istate,
		const struct cache_entry *ce,
		struct stat *st, unsigned int options)
{
	int changed, changed_fs;

	changed = ie_match_stat(istate, ce, st, options);
	if (!changed)
		return 0;
	/*
	 * If the mode or type has changed, there's no point in trying
	 * to refresh the entry - it's not going to match
	 */
	if (changed & (MODE_CHANGED | TYPE_CHANGED))
		return changed;

	/*
	 * Immediately after read-tree or update-index --cacheinfo,
	 * the length field is zero, as we have never even read the
	 * lstat(2) information once, and we cannot trust DATA_CHANGED
	 * returned by ie_match_stat() which in turn was returned by
	 * ce_match_stat_basic() to signal that the filesize of the
	 * blob changed.  We have to actually go to the filesystem to
	 * see if the contents match, and if so, should answer "unchanged".
	 *
	 * The logic does not apply to gitlinks, as ce_match_stat_basic()
	 * already has checked the actual HEAD from the filesystem in the
	 * subproject.  If ie_match_stat() already said it is different,
	 * then we know it is.
	 */
	if ((changed & DATA_CHANGED) &&
#ifdef GIT_WINDOWS_NATIVE
	    /*
	     * Work around Git for Windows v2.27.0 fixing a bug where symlinks'
	     * target path lengths were not read at all, and instead recorded
	     * as 4096: now, all symlinks would appear as modified.
	     *
	     * So let's just special-case symlinks with a target path length
	     * (i.e. `sd_size`) of 4096 and force them to be re-checked.
	     */
	    (!S_ISLNK(st->st_mode) || ce->ce_stat_data.sd_size != MAX_PATH) &&
#endif
	    (S_ISGITLINK(ce->ce_mode) || ce->ce_stat_data.sd_size != 0))
		return changed;

	changed_fs = ce_modified_check_fs(istate, ce, st);
	if (changed_fs)
		return changed | changed_fs;
	return 0;
}

static int cache_name_stage_compare(const char *name1, int len1, int stage1,
				    const char *name2, int len2, int stage2)
{
	int cmp;

	cmp = name_compare(name1, len1, name2, len2);
	if (cmp)
		return cmp;

	if (stage1 < stage2)
		return -1;
	if (stage1 > stage2)
		return 1;
	return 0;
}

int cmp_cache_name_compare(const void *a_, const void *b_)
{
	const struct cache_entry *ce1, *ce2;

	ce1 = *((const struct cache_entry **)a_);
	ce2 = *((const struct cache_entry **)b_);
	return cache_name_stage_compare(ce1->name, ce1->ce_namelen, ce_stage(ce1),
				  ce2->name, ce2->ce_namelen, ce_stage(ce2));
}

static int index_name_stage_pos(struct index_state *istate,
				const char *name, int namelen,
				int stage,
				enum index_search_mode search_mode)
{
	int first, last;

	first = 0;
	last = istate->cache_nr;
	while (last > first) {
		int next = first + ((last - first) >> 1);
		struct cache_entry *ce = istate->cache[next];
		int cmp = cache_name_stage_compare(name, namelen, stage, ce->name, ce_namelen(ce), ce_stage(ce));
		if (!cmp)
			return next;
		if (cmp < 0) {
			last = next;
			continue;
		}
		first = next+1;
	}

	if (search_mode == EXPAND_SPARSE && istate->sparse_index &&
	    first > 0) {
		/* Note: first <= istate->cache_nr */
		struct cache_entry *ce = istate->cache[first - 1];

		/*
		 * If we are in a sparse-index _and_ the entry before the
		 * insertion position is a sparse-directory entry that is
		 * an ancestor of 'name', then we need to expand the index
		 * and search again. This will only trigger once, because
		 * thereafter the index is fully expanded.
		 */
		if (S_ISSPARSEDIR(ce->ce_mode) &&
		    ce_namelen(ce) < namelen &&
		    !strncmp(name, ce->name, ce_namelen(ce))) {
			ensure_full_index(istate);
			return index_name_stage_pos(istate, name, namelen, stage, search_mode);
		}
	}

	return -first-1;
}

int index_name_pos(struct index_state *istate, const char *name, int namelen)
{
	return index_name_stage_pos(istate, name, namelen, 0, EXPAND_SPARSE);
}

int index_name_pos_sparse(struct index_state *istate, const char *name, int namelen)
{
	return index_name_stage_pos(istate, name, namelen, 0, NO_EXPAND_SPARSE);
}

int index_entry_exists(struct index_state *istate, const char *name, int namelen)
{
	return index_name_stage_pos(istate, name, namelen, 0, NO_EXPAND_SPARSE) >= 0;
}

int remove_index_entry_at(struct index_state *istate, int pos)
{
	struct cache_entry *ce = istate->cache[pos];

	record_resolve_undo(istate, ce);
	remove_name_hash(istate, ce);
	save_or_free_index_entry(istate, ce);
	istate->cache_changed |= CE_ENTRY_REMOVED;
	istate->cache_nr--;
	if (pos >= istate->cache_nr)
		return 0;
	MOVE_ARRAY(istate->cache + pos, istate->cache + pos + 1,
		   istate->cache_nr - pos);
	return 1;
}

/*
 * Remove all cache entries marked for removal, that is where
 * CE_REMOVE is set in ce_flags.  This is much more effective than
 * calling remove_index_entry_at() for each entry to be removed.
 */
void remove_marked_cache_entries(struct index_state *istate, int invalidate)
{
	struct cache_entry **ce_array = istate->cache;
	unsigned int i, j;

	for (i = j = 0; i < istate->cache_nr; i++) {
		if (ce_array[i]->ce_flags & CE_REMOVE) {
			if (invalidate) {
				cache_tree_invalidate_path(istate,
							   ce_array[i]->name);
				untracked_cache_remove_from_index(istate,
								  ce_array[i]->name);
			}
			remove_name_hash(istate, ce_array[i]);
			save_or_free_index_entry(istate, ce_array[i]);
		}
		else
			ce_array[j++] = ce_array[i];
	}
	if (j == istate->cache_nr)
		return;
	istate->cache_changed |= CE_ENTRY_REMOVED;
	istate->cache_nr = j;
}

int remove_file_from_index(struct index_state *istate, const char *path)
{
	int pos = index_name_pos(istate, path, strlen(path));
	if (pos < 0)
		pos = -pos-1;
	cache_tree_invalidate_path(istate, path);
	untracked_cache_remove_from_index(istate, path);
	while (pos < istate->cache_nr && !strcmp(istate->cache[pos]->name, path))
		remove_index_entry_at(istate, pos);
	return 0;
}

static int compare_name(struct cache_entry *ce, const char *path, int namelen)
{
	return namelen != ce_namelen(ce) || memcmp(path, ce->name, namelen);
}

static int index_name_pos_also_unmerged(struct index_state *istate,
	const char *path, int namelen)
{
	int pos = index_name_pos(istate, path, namelen);
	struct cache_entry *ce;

	if (pos >= 0)
		return pos;

	/* maybe unmerged? */
	pos = -1 - pos;
	if (pos >= istate->cache_nr ||
			compare_name((ce = istate->cache[pos]), path, namelen))
		return -1;

	/* order of preference: stage 2, 1, 3 */
	if (ce_stage(ce) == 1 && pos + 1 < istate->cache_nr &&
			ce_stage((ce = istate->cache[pos + 1])) == 2 &&
			!compare_name(ce, path, namelen))
		pos++;
	return pos;
}

static int different_name(struct cache_entry *ce, struct cache_entry *alias)
{
	int len = ce_namelen(ce);
	return ce_namelen(alias) != len || memcmp(ce->name, alias->name, len);
}

/*
 * If we add a filename that aliases in the cache, we will use the
 * name that we already have - but we don't want to update the same
 * alias twice, because that implies that there were actually two
 * different files with aliasing names!
 *
 * So we use the CE_ADDED flag to verify that the alias was an old
 * one before we accept it as
 */
static struct cache_entry *create_alias_ce(struct index_state *istate,
					   struct cache_entry *ce,
					   struct cache_entry *alias)
{
	int len;
	struct cache_entry *new_entry;

	if (alias->ce_flags & CE_ADDED)
		die(_("will not add file alias '%s' ('%s' already exists in index)"),
		    ce->name, alias->name);

	/* Ok, create the new entry using the name of the existing alias */
	len = ce_namelen(alias);
	new_entry = make_empty_cache_entry(istate, len);
	memcpy(new_entry->name, alias->name, len);
	copy_cache_entry(new_entry, ce);
	save_or_free_index_entry(istate, ce);
	return new_entry;
}

void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
{
	struct object_id oid;
	if (odb_write_object(the_repository->objects, "", 0, OBJ_BLOB, &oid))
		die(_("cannot create an empty blob in the object database"));
	oidcpy(&ce->oid, &oid);
}

int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
{
	int namelen, was_same;
	mode_t st_mode = st->st_mode;
	struct cache_entry *ce, *alias = NULL;
	unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE|CE_MATCH_RACY_IS_DIRTY;
	int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND);
	int pretend = flags & ADD_CACHE_PRETEND;
	int intent_only = flags & ADD_CACHE_INTENT;
	int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|
			  (intent_only ? ADD_CACHE_NEW_ONLY : 0));
	unsigned hash_flags = pretend ? 0 : INDEX_WRITE_OBJECT;

	if (flags & ADD_CACHE_RENORMALIZE)
		hash_flags |= INDEX_RENORMALIZE;

	if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
		return error(_("%s: can only add regular files, symbolic links or git-directories"), path);

	namelen = strlen(path);
	if (S_ISDIR(st_mode)) {
		while (namelen && path[namelen-1] == '/')
			namelen--;
	}
	ce = make_empty_cache_entry(istate, namelen);
	memcpy(ce->name, path, namelen);
	ce->ce_namelen = namelen;
	if (!intent_only)
		fill_stat_cache_info(istate, ce, st);
	else
		ce->ce_flags |= CE_INTENT_TO_ADD;


	if (trust_executable_bit && has_symlinks) {
		ce->ce_mode = create_ce_mode(st_mode);
	} else {
		/* If there is an existing entry, pick the mode bits and type
		 * from it, otherwise assume unexecutable regular file.
		 */
		struct cache_entry *ent;
		int pos = index_name_pos_also_unmerged(istate, path, namelen);

		ent = (0 <= pos) ? istate->cache[pos] : NULL;
		ce->ce_mode = ce_mode_from_stat(ent, st_mode);
	}

	/* When core.ignorecase=true, determine if a directory of the same name but differing
	 * case already exists within the Git repository.  If it does, ensure the directory
	 * case of the file being added to the repository matches (is folded into) the existing
	 * entry's directory case.
	 */
	if (repo_ignore_case(the_repository)) {
		adjust_dirname_case(istate, ce->name);
	}
	if (!(flags & ADD_CACHE_RENORMALIZE)) {
		alias = index_file_exists(istate, ce->name,
					  ce_namelen(ce), repo_ignore_case(the_repository));
		if (alias &&
		    !ce_stage(alias) &&
		    !ie_match_stat(istate, alias, st, ce_option)) {
			/* Nothing changed, really */
			if (!S_ISGITLINK(alias->ce_mode))
				ce_mark_uptodate(alias);
			alias->ce_flags |= CE_ADDED;

			discard_cache_entry(ce);
			return 0;
		}
	}
	if (!intent_only) {
		if (index_path(istate, &ce->oid, path, st, hash_flags)) {
			discard_cache_entry(ce);
			return error(_("unable to index file '%s'"), path);
		}
	} else
		set_object_name_for_intent_to_add_entry(ce);

	if (repo_ignore_case(the_repository) && alias && different_name(ce, alias))
		ce = create_alias_ce(istate, ce, alias);
	ce->ce_flags |= CE_ADDED;

	/* It was suspected to be racily clean, but it turns out to be Ok */
	was_same = (alias &&
		    !ce_stage(alias) &&
		    oideq(&alias->oid, &ce->oid) &&
		    ce->ce_mode == alias->ce_mode);

	if (pretend)
		discard_cache_entry(ce);
	else if (add_index_entry(istate, ce, add_option)) {
		discard_cache_entry(ce);
		return error(_("unable to add '%s' to index"), path);
	}
	if (verbose && !was_same)
		printf("add '%s'\n", path);
	return 0;
}

int add_file_to_index(struct index_state *istate, const char *path, int flags)
{
	struct stat st;
	if (lstat(path, &st))
		die_errno(_("unable to stat '%s'"), path);
	return add_to_index(istate, path, &st, flags);
}

struct cache_entry *make_empty_cache_entry(struct index_state *istate, size_t len)
{
	return mem_pool__ce_calloc(find_mem_pool(istate), len);
}

struct cache_entry *make_empty_transient_cache_entry(size_t len,
						     struct mem_pool *ce_mem_pool)
{
	if (ce_mem_pool)
		return mem_pool__ce_calloc(ce_mem_pool, len);
	return xcalloc(1, cache_entry_size(len));
}

enum verify_path_result {
	PATH_OK,
	PATH_INVALID,
	PATH_DIR_WITH_SEP,
};

static enum verify_path_result verify_path_internal(const char *, unsigned);

int verify_path(const char *path, unsigned mode)
{
	return verify_path_internal(path, mode) == PATH_OK;
}

struct cache_entry *make_cache_entry(struct index_state *istate,
				     unsigned int mode,
				     const struct object_id *oid,
				     const char *path,
				     int stage,
				     unsigned int refresh_options)
{
	struct cache_entry *ce, *ret;
	int len;

	if (verify_path_internal(path, mode) == PATH_INVALID) {
		error(_("invalid path '%s'"), path);
		return NULL;
	}

	len = strlen(path);
	ce = make_empty_cache_entry(istate, len);

	oidcpy(&ce->oid, oid);
	memcpy(ce->name, path, len);
	ce->ce_flags = create_ce_flags(stage);
	ce->ce_namelen = len;
	ce->ce_mode = create_ce_mode(mode);

	ret = refresh_cache_entry(istate, ce, refresh_options);
	if (ret != ce)
		discard_cache_entry(ce);
	return ret;
}

struct cache_entry *make_transient_cache_entry(unsigned int mode,
					       const struct object_id *oid,
					       const char *path,
					       int stage,
					       struct mem_pool *ce_mem_pool)
{
	struct cache_entry *ce;
	int len;

	if (!verify_path(path, mode)) {
		error(_("invalid path '%s'"), path);
		return NULL;
	}

	len = strlen(path);
	ce = make_empty_transient_cache_entry(len, ce_mem_pool);

	oidcpy(&ce->oid, oid);
	memcpy(ce->name, path, len);
	ce->ce_flags = create_ce_flags(stage);
	ce->ce_namelen = len;
	ce->ce_mode = create_ce_mode(mode);

	return ce;
}

/*
 * Chmod an index entry with either +x or -x.
 *
 * Returns -1 if the chmod for the particular cache entry failed (if it's
 * not a regular file), -2 if an invalid flip argument is passed in, 0
 * otherwise.
 */
int chmod_index_entry(struct index_state *istate, struct cache_entry *ce,
		      char flip)
{
	if (!S_ISREG(ce->ce_mode))
		return -1;
	switch (flip) {
	case '+':
		ce->ce_mode |= 0111;
		break;
	case '-':
		ce->ce_mode &= ~0111;
		break;
	default:
		return -2;
	}
	cache_tree_invalidate_path(istate, ce->name);
	ce->ce_flags |= CE_UPDATE_IN_BASE;
	mark_fsmonitor_invalid(istate, ce);
	istate->cache_changed |= CE_ENTRY_CHANGED;

	return 0;
}

int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
{
	int len = ce_namelen(a);
	return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}

/*
 * We fundamentally don't like some paths: we don't want
 * dot or dot-dot anywhere, and for obvious reasons don't
 * want to recurse into ".git" either.
 *
 * Also, we don't want double slashes or slashes at the
 * end that can make pathnames ambiguous.
 */
static int verify_dotfile(const char *rest, unsigned mode)
{
	/*
	 * The first character was '.', but that
	 * has already been discarded, we now test
	 * the rest.
	 */

	/* "." is not allowed */
	if (*rest == '\0' || is_dir_sep(*rest))
		return 0;

	switch (*rest) {
	/*
	 * ".git" followed by NUL or slash is bad. Note that we match
	 * case-insensitively here, even if ignore_case is not set.
	 * This outlaws ".GIT" everywhere out of an abundance of caution,
	 * since there's really no good reason to allow it.
	 *
	 * Once we've seen ".git", we can also find ".gitmodules", etc (also
	 * case-insensitively).
	 */
	case 'g':
	case 'G':
		if (rest[1] != 'i' && rest[1] != 'I')
			break;
		if (rest[2] != 't' && rest[2] != 'T')
			break;
		if (rest[3] == '\0' || is_dir_sep(rest[3]))
			return 0;
		if (S_ISLNK(mode)) {
			rest += 3;
			if (skip_iprefix(rest, "modules", &rest) &&
			    (*rest == '\0' || is_dir_sep(*rest)))
				return 0;
		}
		break;
	case '.':
		if (rest[1] == '\0' || is_dir_sep(rest[1]))
			return 0;
	}
	return 1;
}

static enum verify_path_result verify_path_internal(const char *path,
						    unsigned mode)
{
	char c = 0;

	if (has_dos_drive_prefix(path))
		return PATH_INVALID;

	if (!is_valid_path(path))
		return PATH_INVALID;

	goto inside;
	for (;;) {
		if (!c)
			return PATH_OK;
		if (is_dir_sep(c)) {
inside:
			if (repo_protect_hfs(the_repository)) {

				if (is_hfs_dotgit(path))
					return PATH_INVALID;
				if (S_ISLNK(mode)) {
					if (is_hfs_dotgitmodules(path))
						return PATH_INVALID;
				}
			}
			if (repo_protect_ntfs(the_repository)) {
#if defined GIT_WINDOWS_NATIVE || defined __CYGWIN__
				if (c == '\\')
					return PATH_INVALID;
#endif
				if (is_ntfs_dotgit(path))
					return PATH_INVALID;
				if (S_ISLNK(mode)) {
					if (is_ntfs_dotgitmodules(path))
						return PATH_INVALID;
				}
			}

			c = *path++;
			if ((c == '.' && !verify_dotfile(path, mode)) ||
			    is_dir_sep(c))
				return PATH_INVALID;
			/*
			 * allow terminating directory separators for
			 * sparse directory entries.
			 */
			if (c == '\0')
				return S_ISDIR(mode) ? PATH_DIR_WITH_SEP :
						       PATH_INVALID;
		} else if (c == '\\' &&
			   repo_protect_ntfs(the_repository)) {
			if (is_ntfs_dotgit(path))
				return PATH_INVALID;
			if (S_ISLNK(mode)) {
				if (is_ntfs_dotgitmodules(path))
					return PATH_INVALID;
			}
		}

		c = *path++;
	}
}

/*
 * Do we have another file that has the beginning components being a
 * proper superset of the name we're trying to add?
 */
static int has_file_name(struct index_state *istate,
			 const struct cache_entry *ce, int pos, int ok_to_replace)
{
	int retval = 0;
	int len = ce_namelen(ce);
	int stage = ce_stage(ce);
	const char *name = ce->name;

	while (pos < istate->cache_nr) {
		struct cache_entry *p = istate->cache[pos++];

		if (len >= ce_namelen(p))
			break;
		if (memcmp(name, p->name, len))
			break;
		if (ce_stage(p) != stage)
			continue;
		if (p->name[len] != '/')
			continue;
		if (p->ce_flags & CE_REMOVE)
			continue;
		retval = -1;
		if (!ok_to_replace)
			break;
		remove_index_entry_at(istate, --pos);
	}
	return retval;
}


/*
 * Like strcmp(), but also return the offset of the first change.
 * If strings are equal, return the length.
 */
int strcmp_offset(const char *s1, const char *s2, size_t *first_change)
{
	size_t k;

	if (!first_change)
		return strcmp(s1, s2);

	for (k = 0; s1[k] == s2[k]; k++)
		if (s1[k] == '\0')
			break;

	*first_change = k;
	return (unsigned char)s1[k] - (unsigned char)s2[k];
}

/*
 * Do we have another file with a pathname that is a proper
 * subset of the name we're trying to add?
 *
 * That is, is there another file in the index with a path
 * that matches a sub-directory in the given entry?
 */
static int has_dir_name(struct index_state *istate,
			const struct cache_entry *ce, int pos, int ok_to_replace)
{
	int retval = 0;
	int stage = ce_stage(ce);
	const char *name = ce->name;
	const char *slash = name + ce_namelen(ce);
	size_t len_eq_last;
	int cmp_last = 0;

	/*
	 * We are frequently called during an iteration on a sorted
	 * list of pathnames and while building a new index.  Therefore,
	 * there is a high probability that this entry will eventually
	 * be appended to the index, rather than inserted in the middle.
	 * If we can confirm that, we can avoid binary searches on the
	 * components of the pathname.
	 *
	 * Compare the entry's full path with the last path in the index.
	 */
	if (!istate->cache_nr)
		return 0;

	cmp_last = strcmp_offset(name,
				 istate->cache[istate->cache_nr - 1]->name,
				 &len_eq_last);
	if (cmp_last > 0 && name[len_eq_last] != '/')
		/*
		 * The entry sorts AFTER the last one in the
		 * index and their paths have no common prefix,
		 * so there cannot be a F/D conflict.
		 */
		return 0;

	for (;;) {
		size_t len;

		for (;;) {
			if (*--slash == '/')
				break;
			if (slash <= ce->name)
				return retval;
		}
		len = slash - name;

		pos = index_name_stage_pos(istate, name, len, stage, EXPAND_SPARSE);
		if (pos >= 0) {
			/*
			 * Found one, but not so fast.  This could
			 * be a marker that says "I was here, but
			 * I am being removed".  Such an entry is
			 * not a part of the resulting tree, and
			 * it is Ok to have a directory at the same
			 * path.
			 */
			if (!(istate->cache[pos]->ce_flags & CE_REMOVE)) {
				retval = -1;
				if (!ok_to_replace)
					break;
				remove_index_entry_at(istate, pos);
				continue;
			}
		}
		else
			pos = -pos-1;

		/*
		 * Trivial optimization: if we find an entry that
		 * already matches the sub-directory, then we know
		 * we're ok, and we can exit.
		 */
		while (pos < istate->cache_nr) {
			struct cache_entry *p = istate->cache[pos];
			if ((ce_namelen(p) <= len) ||
			    (p->name[len] != '/') ||
			    memcmp(p->name, name, len))
				break; /* not our subdirectory */
			if (ce_stage(p) == stage && !(p->ce_flags & CE_REMOVE))
				/*
				 * p is at the same stage as our entry, and
				 * is a subdirectory of what we are looking
				 * at, so we cannot have conflicts at our
				 * level or anything shorter.
				 */
				return retval;
			pos++;
		}
	}
	return retval;
}

/* We may be in a situation where we already have path/file and path
 * is being added, or we already have path and path/file is being
 * added.  Either one would result in a nonsense tree that has path
 * twice when git-write-tree tries to write it out.  Prevent it.
 *
 * If ok-to-replace is specified, we remove the conflicting entries
 * from the cache so the caller should recompute the insert position.
 * When this happens, we return non-zero.
 */
static int check_file_directory_conflict(struct index_state *istate,
					 const struct cache_entry *ce,
					 int pos, int ok_to_replace)
{
	int retval;

	/*
	 * When ce is an "I am going away" entry, we allow it to be added
	 */
	if (ce->ce_flags & CE_REMOVE)
		return 0;

	/*
	 * We check if the path is a sub-path of a subsequent pathname
	 * first, since removing those will not change the position
	 * in the array.
	 */
	retval = has_file_name(istate, ce, pos, ok_to_replace);

	/*
	 * Then check if the path might have a clashing sub-directory
	 * before it.
	 */
	return retval + has_dir_name(istate, ce, pos, ok_to_replace);
}

static int add_index_entry_with_check(struct index_state *istate, struct cache_entry *ce, int option)
{
	int pos;
	int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
	int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
	int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
	int new_only = option & ADD_CACHE_NEW_ONLY;

	/*
	 * If this entry's path sorts after the last entry in the index,
	 * we can avoid searching for it.
	 */
	if (istate->cache_nr > 0 &&
		strcmp(ce->name, istate->cache[istate->cache_nr - 1]->name) > 0)
		pos = index_pos_to_insert_pos(istate->cache_nr);
	else
		pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce), EXPAND_SPARSE);

	/*
	 * Cache tree path should be invalidated only after index_name_stage_pos,
	 * in case it expands a sparse index.
	 */
	if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
		cache_tree_invalidate_path(istate, ce->name);

	/* existing match? Just replace it. */
	if (pos >= 0) {
		if (!new_only)
			replace_index_entry(istate, pos, ce);
		return 0;
	}
	pos = -pos-1;

	if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
		untracked_cache_add_to_index(istate, ce->name);

	/*
	 * Inserting a merged entry ("stage 0") into the index
	 * will always replace all non-merged entries..
	 */
	if (pos < istate->cache_nr && ce_stage(ce) == 0) {
		while (ce_same_name(istate->cache[pos], ce)) {
			ok_to_add = 1;
			if (!remove_index_entry_at(istate, pos))
				break;
		}
	}

	if (!ok_to_add)
		return -1;
	if (verify_path_internal(ce->name, ce->ce_mode) == PATH_INVALID)
		return error(_("invalid path '%s'"), ce->name);

	if (!skip_df_check &&
	    check_file_directory_conflict(istate, ce, pos, ok_to_replace)) {
		if (!ok_to_replace)
			return error(_("'%s' appears as both a file and as a directory"),
				     ce->name);
		pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce), EXPAND_SPARSE);
		pos = -pos-1;
	}
	return pos + 1;
}

int add_index_entry(struct index_state *istate, struct cache_entry *ce, int option)
{
	int pos;

	if (option & ADD_CACHE_JUST_APPEND)
		pos = istate->cache_nr;
	else {
		int ret;
		ret = add_index_entry_with_check(istate, ce, option);
		if (ret <= 0)
			return ret;
		pos = ret - 1;
	}

	/* Make sure the array is big enough .. */
	ALLOC_GROW(istate->cache, istate->cache_nr + 1, istate->cache_alloc);

	/* Add it in.. */
	istate->cache_nr++;
	if (istate->cache_nr > pos + 1)
		MOVE_ARRAY(istate->cache + pos + 1, istate->cache + pos,
			   istate->cache_nr - pos - 1);
	set_index_entry(istate, pos, ce);
	istate->cache_changed |= CE_ENTRY_ADDED;
	return 0;
}

/*
 * "refresh" does not calculate a new sha1 file or bring the
 * cache up-to-date for mode/content changes. But what it
 * _does_ do is to "re-match" the stat information of a file
 * with the cache, so that you can refresh the cache for a
 * file that hasn't been changed but where the stat entry is
 * out of date.
 *
 * For example, you'd want to do this after doing a "git-read-tree",
 * to link up the stat cache details with the proper files.
 */
static struct cache_entry *refresh_cache_ent(struct index_state *istate,
					     struct cache_entry *ce,
					     unsigned int options, int *err,
					     int *changed_ret,
					     int *t2_did_lstat,
					     int *t2_did_scan)
{
	struct stat st;
	struct cache_entry *updated;
	int changed;
	int refresh = options & CE_MATCH_REFRESH;
	int ignore_valid = options & CE_MATCH_IGNORE_VALID;
	int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
	int ignore_missing = options & CE_MATCH_IGNORE_MISSING;
	int ignore_fsmonitor = options & CE_MATCH_IGNORE_FSMONITOR;

	if (!refresh || ce_uptodate(ce))
		return ce;

	if (!ignore_fsmonitor)
		refresh_fsmonitor(istate);
	/*
	 * CE_VALID or CE_SKIP_WORKTREE means the user promised us
	 * that the change to the work tree does not matter and told
	 * us not to worry.
	 */
	if (!ignore_skip_worktree && ce_skip_worktree(ce)) {
		ce_mark_uptodate(ce);
		return ce;
	}
	if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
		ce_mark_uptodate(ce);
		return ce;
	}
	if (!ignore_fsmonitor && (ce->ce_flags & CE_FSMONITOR_VALID)) {
		ce_mark_uptodate(ce);
		return ce;
	}

	if (has_symlink_leading_path(ce->name, ce_namelen(ce))) {
		if (ignore_missing)
			return ce;
		if (err)
			*err = ENOENT;
		return NULL;
	}

	if (t2_did_lstat)
		*t2_did_lstat = 1;
	if (lstat(ce->name, &st) < 0) {
		if (ignore_missing && errno == ENOENT)
			return ce;
		if (err)
			*err = errno;
		return NULL;
	}

	changed = ie_match_stat(istate, ce, &st, options);
	if (changed_ret)
		*changed_ret = changed;
	if (!changed) {
		/*
		 * The path is unchanged.  If we were told to ignore
		 * valid bit, then we did the actual stat check and
		 * found that the entry is unmodified.  If the entry
		 * is not marked VALID, this is the place to mark it
		 * valid again, under "assume unchanged" mode.
		 */
		if (ignore_valid && assume_unchanged &&
		    !(ce->ce_flags & CE_VALID))
			; /* mark this one VALID again */
		else {
			/*
			 * We do not mark the index itself "modified"
			 * because CE_UPTODATE flag is in-core only;
			 * we are not going to write this change out.
			 */
			if (!S_ISGITLINK(ce->ce_mode)) {
				ce_mark_uptodate(ce);
				mark_fsmonitor_valid(istate, ce);
			}
			return ce;
		}
	}

	if (t2_did_scan)
		*t2_did_scan = 1;
	if (ie_modified(istate, ce, &st, options)) {
		if (err)
			*err = EINVAL;
		return NULL;
	}

	updated = make_empty_cache_entry(istate, ce_namelen(ce));
	copy_cache_entry(updated, ce);
	memcpy(updated->name, ce->name, ce->ce_namelen + 1);
	fill_stat_cache_info(istate, updated, &st);
	/*
	 * If ignore_valid is not set, we should leave CE_VALID bit
	 * alone.  Otherwise, paths marked with --no-assume-unchanged
	 * (i.e. things to be edited) will reacquire CE_VALID bit
	 * automatically, which is not really what we want.
	 */
	if (!ignore_valid && assume_unchanged &&
	    !(ce->ce_flags & CE_VALID))
		updated->ce_flags &= ~CE_VALID;

	/* istate->cache_changed is updated in the caller */
	return updated;
}

static void show_file(const char * fmt, const char * name, int in_porcelain,
		      int * first, const char *header_msg)
{
	if (in_porcelain && *first && header_msg) {
		printf("%s\n", header_msg);
		*first = 0;
	}
	printf(fmt, name);
}

int repo_refresh_and_write_index(struct repository *repo,
				 unsigned int refresh_flags,
				 unsigned int write_flags,
				 int gentle,
				 const struct pathspec *pathspec,
				 char *seen, const char *header_msg)
{
	struct lock_file lock_file = LOCK_INIT;
	int fd, ret = 0;

	fd = repo_hold_locked_index(repo, &lock_file,
				    gentle ? 0 : LOCK_REPORT_ON_ERROR);
	if (!gentle && fd < 0)
		return -1;
	if (refresh_index(repo->index, refresh_flags, pathspec, seen, header_msg))
		ret = 1;
	if (0 <= fd && write_locked_index(repo->index, &lock_file, COMMIT_LOCK | write_flags))
		ret = -1;
	return ret;
}


int refresh_index(struct index_state *istate, unsigned int flags,
		  const struct pathspec *pathspec,
		  char *seen, const char *header_msg)
{
	int i;
	int has_errors = 0;
	int really = (flags & REFRESH_REALLY) != 0;
	int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
	int quiet = (flags & REFRESH_QUIET) != 0;
	int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
	int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
	int ignore_skip_worktree = (flags & REFRESH_IGNORE_SKIP_WORKTREE) != 0;
	int first = 1;
	int in_porcelain = (flags & REFRESH_IN_PORCELAIN);
	unsigned int options = (CE_MATCH_REFRESH |
				(really ? CE_MATCH_IGNORE_VALID : 0) |
				(not_new ? CE_MATCH_IGNORE_MISSING : 0));
	const char *modified_fmt;
	const char *deleted_fmt;
	const char *typechange_fmt;
	const char *added_fmt;
	const char *unmerged_fmt;
	struct progress *progress = NULL;
	int t2_sum_lstat = 0;
	int t2_sum_scan = 0;

	if (flags & REFRESH_PROGRESS && isatty(2))
		progress = start_delayed_progress(the_repository,
						  _("Refresh index"),
						  istate->cache_nr);

	trace_performance_enter();
	modified_fmt   = in_porcelain ? "M\t%s\n" : "%s: needs update\n";
	deleted_fmt    = in_porcelain ? "D\t%s\n" : "%s: needs update\n";
	typechange_fmt = in_porcelain ? "T\t%s\n" : "%s: needs update\n";
	added_fmt      = in_porcelain ? "A\t%s\n" : "%s: needs update\n";
	unmerged_fmt   = in_porcelain ? "U\t%s\n" : "%s: needs merge\n";
	/*
	 * Use the multi-threaded preload_index() to refresh most of the
	 * cache entries quickly then in the single threaded loop below,
	 * we only have to do the special cases that are left.
	 */
	preload_index(istate, pathspec, 0);
	trace2_region_enter("index", "refresh", NULL);

	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce, *new_entry;
		int cache_errno = 0;
		int changed = 0;
		int filtered = 0;
		int t2_did_lstat = 0;
		int t2_did_scan = 0;

		ce = istate->cache[i];
		if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
			continue;
		if (ignore_skip_worktree && ce_skip_worktree(ce))
			continue;

		/*
		 * If this entry is a sparse directory, then there isn't
		 * any stat() information to update. Ignore the entry.
		 */
		if (S_ISSPARSEDIR(ce->ce_mode))
			continue;

		if (pathspec && !ce_path_match(istate, ce, pathspec, seen))
			filtered = 1;

		if (ce_stage(ce)) {
			while ((i < istate->cache_nr) &&
			       ! strcmp(istate->cache[i]->name, ce->name))
				i++;
			i--;
			if (allow_unmerged)
				continue;
			if (!filtered)
				show_file(unmerged_fmt, ce->name, in_porcelain,
					  &first, header_msg);
			has_errors = 1;
			continue;
		}

		if (filtered)
			continue;

		new_entry = refresh_cache_ent(istate, ce, options,
					      &cache_errno, &changed,
					      &t2_did_lstat, &t2_did_scan);
		t2_sum_lstat += t2_did_lstat;
		t2_sum_scan += t2_did_scan;
		if (new_entry == ce)
			continue;
		display_progress(progress, i);
		if (!new_entry) {
			const char *fmt;

			if (really && cache_errno == EINVAL) {
				/* If we are doing --really-refresh that
				 * means the index is not valid anymore.
				 */
				ce->ce_flags &= ~CE_VALID;
				ce->ce_flags |= CE_UPDATE_IN_BASE;
				mark_fsmonitor_invalid(istate, ce);
				istate->cache_changed |= CE_ENTRY_CHANGED;
			}
			if (quiet)
				continue;

			if (cache_errno == ENOENT)
				fmt = deleted_fmt;
			else if (ce_intent_to_add(ce))
				fmt = added_fmt; /* must be before other checks */
			else if (changed & TYPE_CHANGED)
				fmt = typechange_fmt;
			else
				fmt = modified_fmt;
			show_file(fmt,
				  ce->name, in_porcelain, &first, header_msg);
			has_errors = 1;
			continue;
		}

		replace_index_entry(istate, i, new_entry);
	}
	trace2_data_intmax("index", NULL, "refresh/sum_lstat", t2_sum_lstat);
	trace2_data_intmax("index", NULL, "refresh/sum_scan", t2_sum_scan);
	trace2_region_leave("index", "refresh", NULL);
	display_progress(progress, istate->cache_nr);
	stop_progress(&progress);
	trace_performance_leave("refresh index");
	return has_errors;
}

struct cache_entry *refresh_cache_entry(struct index_state *istate,
					struct cache_entry *ce,
					unsigned int options)
{
	return refresh_cache_ent(istate, ce, options, NULL, NULL, NULL, NULL);
}


/*****************************************************************
 * Index File I/O
 *****************************************************************/

#define INDEX_FORMAT_DEFAULT 3

static unsigned int get_index_format_default(struct repository *r)
{
	char *envversion = getenv("GIT_INDEX_VERSION");
	char *endp;
	unsigned int version = INDEX_FORMAT_DEFAULT;

	if (!envversion) {
		prepare_repo_settings(r);

		if (r->settings.index_version >= 0)
			version = r->settings.index_version;
		if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
			warning(_("index.version set, but the value is invalid.\n"
				  "Using version %i"), INDEX_FORMAT_DEFAULT);
			return INDEX_FORMAT_DEFAULT;
		}
		return version;
	}

	version = strtoul(envversion, &endp, 10);
	if (*endp ||
	    version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
		warning(_("GIT_INDEX_VERSION set, but the value is invalid.\n"
			  "Using version %i"), INDEX_FORMAT_DEFAULT);
		version = INDEX_FORMAT_DEFAULT;
	}
	return version;
}

/*
 * dev/ino/uid/gid/size are also just tracked to the low 32 bits
 * Again - this is just a (very strong in practice) heuristic that
 * the inode hasn't changed.
 *
 * We save the fields in big-endian order to allow using the
 * index file over NFS transparently.
 */
struct ondisk_cache_entry {
	struct cache_time ctime;
	struct cache_time mtime;
	uint32_t dev;
	uint32_t ino;
	uint32_t mode;
	uint32_t uid;
	uint32_t gid;
	uint32_t size;
	/*
	 * unsigned char hash[hashsz];
	 * uint16_t flags;
	 * if (flags & CE_EXTENDED)
	 *	uint16_t flags2;
	 */
	unsigned char data[GIT_MAX_RAWSZ + 2 * sizeof(uint16_t)];
	char name[FLEX_ARRAY];
};

/* These are only used for v3 or lower */
#define align_padding_size(size, len) ((size + (len) + 8) & ~7) - (size + len)
#define align_flex_name(STRUCT,len) ((offsetof(struct STRUCT,data) + (len) + 8) & ~7)
#define ondisk_cache_entry_size(len) align_flex_name(ondisk_cache_entry,len)
#define ondisk_data_size(flags, len) (the_hash_algo->rawsz + \
				     ((flags & CE_EXTENDED) ? 2 : 1) * sizeof(uint16_t) + len)
#define ondisk_data_size_max(len) (ondisk_data_size(CE_EXTENDED, len))
#define ondisk_ce_size(ce) (ondisk_cache_entry_size(ondisk_data_size((ce)->ce_flags, ce_namelen(ce))))

/* Allow fsck to force verification of the index checksum. */
int verify_index_checksum;

/* Allow fsck to force verification of the cache entry order. */
int verify_ce_order;

static int verify_hdr(const struct cache_header *hdr, unsigned long size)
{
	struct git_hash_ctx c;
	unsigned char hash[GIT_MAX_RAWSZ];
	int hdr_version;
	unsigned char *start, *end;
	struct object_id oid;

	if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
		return error(_("bad signature 0x%08x"), hdr->hdr_signature);
	hdr_version = ntohl(hdr->hdr_version);
	if (hdr_version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < hdr_version)
		return error(_("bad index version %d"), hdr_version);

	if (!verify_index_checksum)
		return 0;

	end = (unsigned char *)hdr + size;
	start = end - the_hash_algo->rawsz;
	oidread(&oid, start, the_repository->hash_algo);
	if (oideq(&oid, null_oid(the_hash_algo)))
		return 0;

	git_hash_init(&c, the_hash_algo);
	git_hash_update(&c, hdr, size - the_hash_algo->rawsz);
	git_hash_final(hash, &c);
	if (!hasheq(hash, start, the_repository->hash_algo))
		return error(_("bad index file sha1 signature"));
	return 0;
}

static int read_index_extension(struct index_state *istate,
				const char *ext, const char *data, unsigned long sz)
{
	switch (CACHE_EXT(ext)) {
	case CACHE_EXT_TREE:
		istate->cache_tree = cache_tree_read(data, sz);
		break;
	case CACHE_EXT_RESOLVE_UNDO:
		istate->resolve_undo = resolve_undo_read(data, sz, the_hash_algo);
		break;
	case CACHE_EXT_LINK:
		if (read_link_extension(istate, data, sz))
			return -1;
		break;
	case CACHE_EXT_UNTRACKED:
		istate->untracked = read_untracked_extension(data, sz);
		break;
	case CACHE_EXT_FSMONITOR:
		read_fsmonitor_extension(istate, data, sz);
		break;
	case CACHE_EXT_ENDOFINDEXENTRIES:
	case CACHE_EXT_INDEXENTRYOFFSETTABLE:
		/* already handled in do_read_index() */
		break;
	case CACHE_EXT_SPARSE_DIRECTORIES:
		/* no content, only an indicator */
		istate->sparse_index = INDEX_COLLAPSED;
		break;
	default:
		if (*ext < 'A' || 'Z' < *ext)
			return error(_("index uses %.4s extension, which we do not understand"),
				     ext);
		fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
		break;
	}
	return 0;
}

/*
 * Parses the contents of the cache entry contained within the 'ondisk' buffer
 * into a new incore 'cache_entry'.
 *
 * Note that 'char *ondisk' may not be aligned to a 4-byte address interval in
 * index v4, so we cannot cast it to 'struct ondisk_cache_entry *' and access
 * its members. Instead, we use the byte offsets of members within the struct to
 * identify where 'get_be16()', 'get_be32()', and 'oidread()' (which can all
 * read from an unaligned memory buffer) should read from the 'ondisk' buffer
 * into the corresponding incore 'cache_entry' members.
 */
static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
					    unsigned int version,
					    const char *ondisk,
					    unsigned long *ent_size,
					    const struct cache_entry *previous_ce)
{
	struct cache_entry *ce;
	size_t len;
	const char *name;
	const unsigned hashsz = the_hash_algo->rawsz;
	const char *flagsp = ondisk + offsetof(struct ondisk_cache_entry, data) + hashsz;
	unsigned int flags;
	size_t copy_len = 0;
	/*
	 * Adjacent cache entries tend to share the leading paths, so it makes
	 * sense to only store the differences in later entries.  In the v4
	 * on-disk format of the index, each on-disk cache entry stores the
	 * number of bytes to be stripped from the end of the previous name,
	 * and the bytes to append to the result, to come up with its name.
	 */
	int expand_name_field = version == 4;

	/* On-disk flags are just 16 bits */
	flags = get_be16(flagsp);
	len = flags & CE_NAMEMASK;

	if (flags & CE_EXTENDED) {
		int extended_flags;
		extended_flags = get_be16(flagsp + sizeof(uint16_t)) << 16;
		/* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
		if (extended_flags & ~CE_EXTENDED_FLAGS)
			die(_("unknown index entry format 0x%08x"), extended_flags);
		flags |= extended_flags;
		name = (const char *)(flagsp + 2 * sizeof(uint16_t));
	}
	else
		name = (const char *)(flagsp + sizeof(uint16_t));

	if (expand_name_field) {
		const unsigned char *cp = (const unsigned char *)name;
		uint64_t strip_len, previous_len;

		/* If we're at the beginning of a block, ignore the previous name */
		strip_len = decode_varint(&cp);
		if (previous_ce) {
			previous_len = previous_ce->ce_namelen;
			if (previous_len < strip_len)
				die(_("malformed name field in the index, near path '%s'"),
					previous_ce->name);
			copy_len = previous_len - strip_len;
		}
		name = (const char *)cp;
	}

	if (len == CE_NAMEMASK) {
		len = strlen(name);
		if (expand_name_field)
			len += copy_len;
	}

	ce = mem_pool__ce_alloc(ce_mem_pool, len);

	/*
	 * NEEDSWORK: using 'offsetof()' is cumbersome and should be replaced
	 * with something more akin to 'load_bitmap_entries_v1()'s use of
	 * 'read_be16'/'read_be32'. For consistency with the corresponding
	 * ondisk entry write function ('copy_cache_entry_to_ondisk()'), this
	 * should be done at the same time as removing references to
	 * 'ondisk_cache_entry' there.
	 */
	ce->ce_stat_data.sd_ctime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
							+ offsetof(struct cache_time, sec));
	ce->ce_stat_data.sd_mtime.sec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
							+ offsetof(struct cache_time, sec));
	ce->ce_stat_data.sd_ctime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ctime)
							 + offsetof(struct cache_time, nsec));
	ce->ce_stat_data.sd_mtime.nsec = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mtime)
							 + offsetof(struct cache_time, nsec));
	ce->ce_stat_data.sd_dev   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, dev));
	ce->ce_stat_data.sd_ino   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, ino));
	ce->ce_mode  = get_be32(ondisk + offsetof(struct ondisk_cache_entry, mode));
	ce->ce_stat_data.sd_uid   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, uid));
	ce->ce_stat_data.sd_gid   = get_be32(ondisk + offsetof(struct ondisk_cache_entry, gid));
	ce->ce_stat_data.sd_size  = get_be32(ondisk + offsetof(struct ondisk_cache_entry, size));
	ce->ce_flags = flags & ~CE_NAMEMASK;
	ce->ce_namelen = len;
	ce->index = 0;
	oidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data),
		the_repository->hash_algo);

	if (expand_name_field) {
		if (copy_len)
			memcpy(ce->name, previous_ce->name, copy_len);
		memcpy(ce->name + copy_len, name, len + 1 - copy_len);
		*ent_size = (name - ((char *)ondisk)) + len + 1 - copy_len;
	} else {
		memcpy(ce->name, name, len + 1);
		*ent_size = ondisk_ce_size(ce);
	}
	return ce;
}

static void check_ce_order(struct index_state *istate)
{
	unsigned int i;

	if (!verify_ce_order)
		return;

	for (i = 1; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i - 1];
		struct cache_entry *next_ce = istate->cache[i];
		int name_compare = strcmp(ce->name, next_ce->name);

		if (0 < name_compare)
			die(_("unordered stage entries in index"));
		if (!name_compare) {
			if (!ce_stage(ce))
				die(_("multiple stage entries for merged file '%s'"),
				    ce->name);
			if (ce_stage(ce) > ce_stage(next_ce))
				die(_("unordered stage entries for '%s'"),
				    ce->name);
		}
	}
}

static void tweak_untracked_cache(struct index_state *istate)
{
	struct repository *r = the_repository;

	prepare_repo_settings(r);

	switch (r->settings.core_untracked_cache) {
	case UNTRACKED_CACHE_REMOVE:
		remove_untracked_cache(istate);
		break;
	case UNTRACKED_CACHE_WRITE:
		add_untracked_cache(istate);
		break;
	case UNTRACKED_CACHE_KEEP:
		/*
		 * Either an explicit "core.untrackedCache=keep", the
		 * default if "core.untrackedCache" isn't configured,
		 * or a fallback on an unknown "core.untrackedCache"
		 * value.
		 */
		break;
	}
}

static void tweak_split_index(struct index_state *istate)
{
	switch (repo_config_get_split_index(the_repository)) {
	case -1: /* unset: do nothing */
		break;
	case 0: /* false */
		remove_split_index(istate);
		break;
	case 1: /* true */
		add_split_index(istate);
		break;
	default: /* unknown value: do nothing */
		break;
	}
}

static void post_read_index_from(struct index_state *istate)
{
	check_ce_order(istate);
	tweak_untracked_cache(istate);
	tweak_split_index(istate);
	tweak_fsmonitor(istate);
}

static size_t estimate_cache_size_from_compressed(unsigned int entries)
{
	return entries * (sizeof(struct cache_entry) + CACHE_ENTRY_PATH_LENGTH);
}

static size_t estimate_cache_size(size_t ondisk_size, unsigned int entries)
{
	long per_entry = sizeof(struct cache_entry) - sizeof(struct ondisk_cache_entry);

	/*
	 * Account for potential alignment differences.
	 */
	per_entry += align_padding_size(per_entry, 0);
	return ondisk_size + entries * per_entry;
}

struct index_entry_offset
{
	/* starting byte offset into index file, count of index entries in this block */
	int offset, nr;
};

struct index_entry_offset_table
{
	int nr;
	struct index_entry_offset entries[FLEX_ARRAY];
};

static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset);
static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot);

static size_t read_eoie_extension(const char *mmap, size_t mmap_size);
static void write_eoie_extension(struct strbuf *sb, struct git_hash_ctx *eoie_context, size_t offset);

struct load_index_extensions
{
	pthread_t pthread;
	struct index_state *istate;
	const char *mmap;
	size_t mmap_size;
	unsigned long src_offset;
};

static void *load_index_extensions(void *_data)
{
	struct load_index_extensions *p = _data;
	unsigned long src_offset = p->src_offset;

	while (src_offset <= p->mmap_size - the_hash_algo->rawsz - 8) {
		/* After an array of active_nr index entries,
		 * there can be arbitrary number of extended
		 * sections, each of which is prefixed with
		 * extension name (4-byte) and section length
		 * in 4-byte network byte order.
		 */
		uint32_t extsize = get_be32(p->mmap + src_offset + 4);
		if (read_index_extension(p->istate,
					 p->mmap + src_offset,
					 p->mmap + src_offset + 8,
					 extsize) < 0) {
			munmap((void *)p->mmap, p->mmap_size);
			die(_("index file corrupt"));
		}
		src_offset += 8;
		src_offset += extsize;
	}

	return NULL;
}

/*
 * A helper function that will load the specified range of cache entries
 * from the memory mapped file and add them to the given index.
 */
static unsigned long load_cache_entry_block(struct index_state *istate,
			struct mem_pool *ce_mem_pool, int offset, int nr, const char *mmap,
			unsigned long start_offset, const struct cache_entry *previous_ce)
{
	int i;
	unsigned long src_offset = start_offset;

	for (i = offset; i < offset + nr; i++) {
		struct cache_entry *ce;
		unsigned long consumed;

		ce = create_from_disk(ce_mem_pool, istate->version,
				      mmap + src_offset,
				      &consumed, previous_ce);
		set_index_entry(istate, i, ce);

		src_offset += consumed;
		previous_ce = ce;
	}
	return src_offset - start_offset;
}

static unsigned long load_all_cache_entries(struct index_state *istate,
			const char *mmap, size_t mmap_size, unsigned long src_offset)
{
	unsigned long consumed;

	istate->ce_mem_pool = xmalloc(sizeof(*istate->ce_mem_pool));
	if (istate->version == 4) {
		mem_pool_init(istate->ce_mem_pool,
				estimate_cache_size_from_compressed(istate->cache_nr));
	} else {
		mem_pool_init(istate->ce_mem_pool,
				estimate_cache_size(mmap_size, istate->cache_nr));
	}

	consumed = load_cache_entry_block(istate, istate->ce_mem_pool,
					0, istate->cache_nr, mmap, src_offset, NULL);
	return consumed;
}

/*
 * Mostly randomly chosen maximum thread counts: we
 * cap the parallelism to online_cpus() threads, and we want
 * to have at least 10000 cache entries per thread for it to
 * be worth starting a thread.
 */

#define THREAD_COST		(10000)

struct load_cache_entries_thread_data
{
	pthread_t pthread;
	struct index_state *istate;
	struct mem_pool *ce_mem_pool;
	int offset;
	const char *mmap;
	struct index_entry_offset_table *ieot;
	int ieot_start;		/* starting index into the ieot array */
	int ieot_blocks;	/* count of ieot entries to process */
	unsigned long consumed;	/* return # of bytes in index file processed */
};

/*
 * A thread proc to run the load_cache_entries() computation
 * across multiple background threads.
 */
static void *load_cache_entries_thread(void *_data)
{
	struct load_cache_entries_thread_data *p = _data;
	int i;

	/* iterate across all ieot blocks assigned to this thread */
	for (i = p->ieot_start; i < p->ieot_start + p->ieot_blocks; i++) {
		p->consumed += load_cache_entry_block(p->istate, p->ce_mem_pool,
			p->offset, p->ieot->entries[i].nr, p->mmap, p->ieot->entries[i].offset, NULL);
		p->offset += p->ieot->entries[i].nr;
	}
	return NULL;
}

static unsigned long load_cache_entries_threaded(struct index_state *istate, const char *mmap, size_t mmap_size,
						 int nr_threads, struct index_entry_offset_table *ieot)
{
	int i, offset, ieot_blocks, ieot_start, err;
	struct load_cache_entries_thread_data *data;
	unsigned long consumed = 0;

	/* a little sanity checking */
	if (istate->name_hash_initialized)
		BUG("the name hash isn't thread safe");

	istate->ce_mem_pool = xmalloc(sizeof(*istate->ce_mem_pool));
	mem_pool_init(istate->ce_mem_pool, 0);

	/* ensure we have no more threads than we have blocks to process */
	if (nr_threads > ieot->nr)
		nr_threads = ieot->nr;
	CALLOC_ARRAY(data, nr_threads);

	offset = ieot_start = 0;
	ieot_blocks = DIV_ROUND_UP(ieot->nr, nr_threads);
	for (i = 0; i < nr_threads; i++) {
		struct load_cache_entries_thread_data *p = &data[i];
		int nr, j;

		if (ieot_start + ieot_blocks > ieot->nr)
			ieot_blocks = ieot->nr - ieot_start;

		p->istate = istate;
		p->offset = offset;
		p->mmap = mmap;
		p->ieot = ieot;
		p->ieot_start = ieot_start;
		p->ieot_blocks = ieot_blocks;

		/* create a mem_pool for each thread */
		nr = 0;
		for (j = p->ieot_start; j < p->ieot_start + p->ieot_blocks; j++)
			nr += p->ieot->entries[j].nr;
		p->ce_mem_pool = xmalloc(sizeof(*istate->ce_mem_pool));
		if (istate->version == 4) {
			mem_pool_init(p->ce_mem_pool,
				estimate_cache_size_from_compressed(nr));
		} else {
			mem_pool_init(p->ce_mem_pool,
				estimate_cache_size(mmap_size, nr));
		}

		err = pthread_create(&p->pthread, NULL, load_cache_entries_thread, p);
		if (err)
			die(_("unable to create load_cache_entries thread: %s"), strerror(err));

		/* increment by the number of cache entries in the ieot block being processed */
		for (j = 0; j < ieot_blocks; j++)
			offset += ieot->entries[ieot_start + j].nr;
		ieot_start += ieot_blocks;
	}

	for (i = 0; i < nr_threads; i++) {
		struct load_cache_entries_thread_data *p = &data[i];

		err = pthread_join(p->pthread, NULL);
		if (err)
			die(_("unable to join load_cache_entries thread: %s"), strerror(err));
		mem_pool_combine(istate->ce_mem_pool, p->ce_mem_pool);
		free(p->ce_mem_pool);
		consumed += p->consumed;
	}

	free(data);

	return consumed;
}

static void set_new_index_sparsity(struct index_state *istate)
{
	/*
	 * If the index's repo exists, mark it sparse according to
	 * repo settings.
	 */
	prepare_repo_settings(istate->repo);
	if (!istate->repo->settings.command_requires_full_index &&
	    is_sparse_index_allowed(istate, 0))
		istate->sparse_index = 1;
}

/* remember to discard_cache() before reading a different cache! */
int do_read_index(struct index_state *istate, const char *path, int must_exist)
{
	int fd;
	struct stat st;
	unsigned long src_offset;
	const struct cache_header *hdr;
	const char *mmap;
	size_t mmap_size;
	struct load_index_extensions p;
	size_t extension_offset = 0;
	int nr_threads, cpus;
	struct index_entry_offset_table *ieot = NULL;

	if (istate->initialized)
		return istate->cache_nr;

	istate->timestamp.sec = 0;
	istate->timestamp.nsec = 0;
	fd = open(path, O_RDONLY);
	if (fd < 0) {
		if (!must_exist && errno == ENOENT) {
			set_new_index_sparsity(istate);
			istate->initialized = 1;
			return 0;
		}
		die_errno(_("%s: index file open failed"), path);
	}

	if (fstat(fd, &st))
		die_errno(_("%s: cannot stat the open index"), path);

	mmap_size = xsize_t(st.st_size);
	if (mmap_size < sizeof(struct cache_header) + the_hash_algo->rawsz)
		die(_("%s: index file smaller than expected"), path);

	mmap = xmmap_gently(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (mmap == MAP_FAILED)
		die_errno(_("%s: unable to map index file%s"), path,
			mmap_os_err());
	close(fd);

	hdr = (const struct cache_header *)mmap;
	if (verify_hdr(hdr, mmap_size) < 0)
		goto unmap;

	oidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz,
		the_repository->hash_algo);
	istate->version = ntohl(hdr->hdr_version);
	istate->cache_nr = ntohl(hdr->hdr_entries);
	istate->cache_alloc = alloc_nr(istate->cache_nr);
	CALLOC_ARRAY(istate->cache, istate->cache_alloc);
	istate->initialized = 1;

	p.istate = istate;
	p.mmap = mmap;
	p.mmap_size = mmap_size;

	src_offset = sizeof(*hdr);

	if (repo_config_get_index_threads(the_repository, &nr_threads))
		nr_threads = 1;

	/* TODO: does creating more threads than cores help? */
	if (!nr_threads) {
		nr_threads = istate->cache_nr / THREAD_COST;
		cpus = online_cpus();
		if (nr_threads > cpus)
			nr_threads = cpus;
	}

	if (!HAVE_THREADS)
		nr_threads = 1;

	if (nr_threads > 1) {
		extension_offset = read_eoie_extension(mmap, mmap_size);
		if (extension_offset) {
			int err;

			p.src_offset = extension_offset;
			err = pthread_create(&p.pthread, NULL, load_index_extensions, &p);
			if (err)
				die(_("unable to create load_index_extensions thread: %s"), strerror(err));

			nr_threads--;
		}
	}

	/*
	 * Locate and read the index entry offset table so that we can use it
	 * to multi-thread the reading of the cache entries.
	 */
	if (extension_offset && nr_threads > 1)
		ieot = read_ieot_extension(mmap, mmap_size, extension_offset);

	if (ieot) {
		src_offset += load_cache_entries_threaded(istate, mmap, mmap_size, nr_threads, ieot);
		free(ieot);
	} else {
		src_offset += load_all_cache_entries(istate, mmap, mmap_size, src_offset);
	}

	istate->timestamp.sec = st.st_mtime;
	istate->timestamp.nsec = ST_MTIME_NSEC(st);

	/* if we created a thread, join it otherwise load the extensions on the primary thread */
	if (extension_offset) {
		int ret = pthread_join(p.pthread, NULL);
		if (ret)
			die(_("unable to join load_index_extensions thread: %s"), strerror(ret));
	} else {
		p.src_offset = src_offset;
		load_index_extensions(&p);
	}
	munmap((void *)mmap, mmap_size);

	trace2_data_intmax("index", istate->repo, "read/version",
			   istate->version);
	trace2_data_intmax("index", istate->repo, "read/cache_nr",
			   istate->cache_nr);

	/*
	 * If the command explicitly requires a full index, force it
	 * to be full. Otherwise, correct the sparsity based on repository
	 * settings and other properties of the index (if necessary).
	 */
	prepare_repo_settings(istate->repo);
	if (istate->repo->settings.command_requires_full_index)
		ensure_full_index(istate);
	else
		ensure_correct_sparsity(istate);

	return istate->cache_nr;

unmap:
	munmap((void *)mmap, mmap_size);
	die(_("index file corrupt"));
}

/*
 * Signal that the shared index is used by updating its mtime.
 *
 * This way, shared index can be removed if they have not been used
 * for some time.
 */
static void freshen_shared_index(const char *shared_index, int warn)
{
	if (!check_and_freshen_file(shared_index, 1) && warn)
		warning(_("could not freshen shared index '%s'"), shared_index);
}

int read_index_from(struct index_state *istate, const char *path,
		    const char *gitdir)
{
	struct split_index *split_index;
	int ret;
	char *base_oid_hex;
	char *base_path;

	/* istate->initialized covers both .git/index and .git/sharedindex.xxx */
	if (istate->initialized)
		return istate->cache_nr;

	trace2_region_enter_printf("index", "do_read_index", istate->repo,
				   "%s", path);
	trace_performance_enter();
	ret = do_read_index(istate, path, 0);
	trace_performance_leave("read cache %s", path);
	trace2_region_leave_printf("index", "do_read_index", istate->repo,
				   "%s", path);

	split_index = istate->split_index;
	if (!split_index || is_null_oid(&split_index->base_oid)) {
		post_read_index_from(istate);
		return ret;
	}

	trace_performance_enter();
	if (split_index->base)
		release_index(split_index->base);
	else
		ALLOC_ARRAY(split_index->base, 1);
	index_state_init(split_index->base, istate->repo);

	base_oid_hex = oid_to_hex(&split_index->base_oid);
	base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex);
	if (file_exists(base_path)) {
		trace2_region_enter_printf("index", "shared/do_read_index",
					the_repository, "%s", base_path);

		ret = do_read_index(split_index->base, base_path, 0);
		trace2_region_leave_printf("index", "shared/do_read_index",
					the_repository, "%s", base_path);
	} else {
		char *path_copy = xstrdup(path);
		char *base_path2 = xstrfmt("%s/sharedindex.%s",
					   dirname(path_copy), base_oid_hex);
		free(path_copy);
		trace2_region_enter_printf("index", "shared/do_read_index",
					   the_repository, "%s", base_path2);
		ret = do_read_index(split_index->base, base_path2, 1);
		trace2_region_leave_printf("index", "shared/do_read_index",
					   the_repository, "%s", base_path2);
		free(base_path2);
	}
	if (!oideq(&split_index->base_oid, &split_index->base->oid))
		die(_("broken index, expect %s in %s, got %s"),
		    base_oid_hex, base_path,
		    oid_to_hex(&split_index->base->oid));

	freshen_shared_index(base_path, 0);
	merge_base_index(istate);
	post_read_index_from(istate);
	trace_performance_leave("read cache %s", base_path);
	free(base_path);
	return ret;
}

int is_index_unborn(struct index_state *istate)
{
	return (!istate->cache_nr && !istate->timestamp.sec);
}

void index_state_init(struct index_state *istate, struct repository *r)
{
	struct index_state blank = INDEX_STATE_INIT(r);
	memcpy(istate, &blank, sizeof(*istate));
}

void release_index(struct index_state *istate)
{
	/*
	 * Cache entries in istate->cache[] should have been allocated
	 * from the memory pool associated with this index, or from an
	 * associated split_index. There is no need to free individual
	 * cache entries. validate_cache_entries can detect when this
	 * assertion does not hold.
	 */
	validate_cache_entries(istate);

	resolve_undo_clear_index(istate);
	free_name_hash(istate);
	cache_tree_free(&(istate->cache_tree));
	free(istate->fsmonitor_last_update);
	free(istate->cache);
	discard_split_index(istate);
	free_untracked_cache(istate->untracked);

	if (istate->sparse_checkout_patterns) {
		clear_pattern_list(istate->sparse_checkout_patterns);
		FREE_AND_NULL(istate->sparse_checkout_patterns);
	}

	if (istate->ce_mem_pool) {
		mem_pool_discard(istate->ce_mem_pool, should_validate_cache_entries());
		FREE_AND_NULL(istate->ce_mem_pool);
	}
}

void discard_index(struct index_state *istate)
{
	release_index(istate);
	index_state_init(istate, istate->repo);
}

/*
 * Validate the cache entries of this index.
 * All cache entries associated with this index
 * should have been allocated by the memory pool
 * associated with this index, or by a referenced
 * split index.
 */
void validate_cache_entries(const struct index_state *istate)
{
	int i;

	if (!should_validate_cache_entries() ||!istate || !istate->initialized)
		return;

	for (i = 0; i < istate->cache_nr; i++) {
		if (!istate) {
			BUG("cache entry is not allocated from expected memory pool");
		} else if (!istate->ce_mem_pool ||
			!mem_pool_contains(istate->ce_mem_pool, istate->cache[i])) {
			if (!istate->split_index ||
				!istate->split_index->base ||
				!istate->split_index->base->ce_mem_pool ||
				!mem_pool_contains(istate->split_index->base->ce_mem_pool, istate->cache[i])) {
				BUG("cache entry is not allocated from expected memory pool");
			}
		}
	}

	if (istate->split_index)
		validate_cache_entries(istate->split_index->base);
}

int unmerged_index(const struct index_state *istate)
{
	int i;
	for (i = 0; i < istate->cache_nr; i++) {
		if (ce_stage(istate->cache[i]))
			return 1;
	}
	return 0;
}

int repo_index_has_changes(struct repository *repo,
			   struct tree *tree,
			   struct strbuf *sb)
{
	struct index_state *istate = repo->index;
	struct object_id cmp;
	int i;

	if (tree)
		cmp = tree->object.oid;
	if (tree || !repo_get_oid_tree(repo, "HEAD", &cmp)) {
		struct diff_options opt;

		repo_diff_setup(repo, &opt);
		opt.flags.exit_with_status = 1;
		if (!sb)
			opt.flags.quick = 1;
		diff_setup_done(&opt);
		do_diff_cache(&cmp, &opt);
		diffcore_std(&opt);
		for (i = 0; sb && i < diff_queued_diff.nr; i++) {
			if (i)
				strbuf_addch(sb, ' ');
			strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);
		}
		diff_flush(&opt);
		return opt.flags.has_changes != 0;
	} else {
		/* TODO: audit for interaction with sparse-index. */
		ensure_full_index(istate);
		for (i = 0; sb && i < istate->cache_nr; i++) {
			if (i)
				strbuf_addch(sb, ' ');
			strbuf_addstr(sb, istate->cache[i]->name);
		}
		return !!istate->cache_nr;
	}
}

static int write_index_ext_header(struct hashfile *f,
				  struct git_hash_ctx *eoie_f,
				  unsigned int ext,
				  unsigned int sz)
{
	hashwrite_be32(f, ext);
	hashwrite_be32(f, sz);

	if (eoie_f) {
		ext = htonl(ext);
		sz = htonl(sz);
		git_hash_update(eoie_f, &ext, sizeof(ext));
		git_hash_update(eoie_f, &sz, sizeof(sz));
	}
	return 0;
}

static void ce_smudge_racily_clean_entry(struct index_state *istate,
					 struct cache_entry *ce)
{
	/*
	 * The only thing we care about in this function is to smudge the
	 * falsely clean entry due to touch-update-touch race, so we leave
	 * everything else as they are.  We are called for entries whose
	 * ce_stat_data.sd_mtime match the index file mtime.
	 *
	 * Note that this actually does not do much for gitlinks, for
	 * which ce_match_stat_basic() always goes to the actual
	 * contents.  The caller checks with is_racy_timestamp() which
	 * always says "no" for gitlinks, so we are not called for them ;-)
	 */
	struct stat st;

	if (lstat(ce->name, &st) < 0)
		return;
	if (ce_match_stat_basic(ce, &st))
		return;
	if (ce_modified_check_fs(istate, ce, &st)) {
		/* This is "racily clean"; smudge it.  Note that this
		 * is a tricky code.  At first glance, it may appear
		 * that it can break with this sequence:
		 *
		 * $ echo xyzzy >frotz
		 * $ git-update-index --add frotz
		 * $ : >frotz
		 * $ sleep 3
		 * $ echo filfre >nitfol
		 * $ git-update-index --add nitfol
		 *
		 * but it does not.  When the second update-index runs,
		 * it notices that the entry "frotz" has the same timestamp
		 * as index, and if we were to smudge it by resetting its
		 * size to zero here, then the object name recorded
		 * in index is the 6-byte file but the cached stat information
		 * becomes zero --- which would then match what we would
		 * obtain from the filesystem next time we stat("frotz").
		 *
		 * However, the second update-index, before calling
		 * this function, notices that the cached size is 6
		 * bytes and what is on the filesystem is an empty
		 * file, and never calls us, so the cached size information
		 * for "frotz" stays 6 which does not match the filesystem.
		 */
		ce->ce_stat_data.sd_size = 0;
	}
}

/* Copy miscellaneous fields but not the name */
static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
				       struct cache_entry *ce)
{
	short flags;
	const unsigned hashsz = the_hash_algo->rawsz;
	uint16_t *flagsp = (uint16_t *)(ondisk->data + hashsz);

	ondisk->ctime.sec = htonl(ce->ce_stat_data.sd_ctime.sec);
	ondisk->mtime.sec = htonl(ce->ce_stat_data.sd_mtime.sec);
	ondisk->ctime.nsec = htonl(ce->ce_stat_data.sd_ctime.nsec);
	ondisk->mtime.nsec = htonl(ce->ce_stat_data.sd_mtime.nsec);
	ondisk->dev  = htonl(ce->ce_stat_data.sd_dev);
	ondisk->ino  = htonl(ce->ce_stat_data.sd_ino);
	ondisk->mode = htonl(ce->ce_mode);
	ondisk->uid  = htonl(ce->ce_stat_data.sd_uid);
	ondisk->gid  = htonl(ce->ce_stat_data.sd_gid);
	ondisk->size = htonl(ce->ce_stat_data.sd_size);
	hashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);

	flags = ce->ce_flags & ~CE_NAMEMASK;
	flags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));
	flagsp[0] = htons(flags);
	if (ce->ce_flags & CE_EXTENDED) {
		flagsp[1] = htons((ce->ce_flags & CE_EXTENDED_FLAGS) >> 16);
	}
}

static int ce_write_entry(struct hashfile *f, struct cache_entry *ce,
			  struct strbuf *previous_name, struct ondisk_cache_entry *ondisk)
{
	int size;
	unsigned int saved_namelen;
	int stripped_name = 0;
	static unsigned char padding[8] = { 0x00 };

	if (ce->ce_flags & CE_STRIP_NAME) {
		saved_namelen = ce_namelen(ce);
		ce->ce_namelen = 0;
		stripped_name = 1;
	}

	size = offsetof(struct ondisk_cache_entry,data) + ondisk_data_size(ce->ce_flags, 0);

	if (!previous_name) {
		int len = ce_namelen(ce);
		copy_cache_entry_to_ondisk(ondisk, ce);
		hashwrite(f, ondisk, size);
		hashwrite(f, ce->name, len);
		hashwrite(f, padding, align_padding_size(size, len));
	} else {
		int common, to_remove;
		uint8_t prefix_size;
		unsigned char to_remove_vi[16];

		for (common = 0;
		     (common < previous_name->len &&
		      ce->name[common] &&
		      ce->name[common] == previous_name->buf[common]);
		     common++)
			; /* still matching */
		to_remove = previous_name->len - common;
		prefix_size = encode_varint(to_remove, to_remove_vi);

		copy_cache_entry_to_ondisk(ondisk, ce);
		hashwrite(f, ondisk, size);
		hashwrite(f, to_remove_vi, prefix_size);
		hashwrite(f, ce->name + common, ce_namelen(ce) - common);
		hashwrite(f, padding, 1);

		strbuf_splice(previous_name, common, to_remove,
			      ce->name + common, ce_namelen(ce) - common);
	}
	if (stripped_name) {
		ce->ce_namelen = saved_namelen;
		ce->ce_flags &= ~CE_STRIP_NAME;
	}

	return 0;
}

/*
 * This function verifies if index_state has the correct sha1 of the
 * index file.  Don't die if we have any other failure, just return 0.
 */
static int verify_index_from(const struct index_state *istate, const char *path)
{
	int fd;
	ssize_t n;
	struct stat st;
	unsigned char hash[GIT_MAX_RAWSZ];

	if (!istate->initialized)
		return 0;

	fd = open(path, O_RDONLY);
	if (fd < 0)
		return 0;

	if (fstat(fd, &st))
		goto out;

	if (st.st_size < sizeof(struct cache_header) + the_hash_algo->rawsz)
		goto out;

	n = pread_in_full(fd, hash, the_hash_algo->rawsz, st.st_size - the_hash_algo->rawsz);
	if (n != the_hash_algo->rawsz)
		goto out;

	if (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))
		goto out;

	close(fd);
	return 1;

out:
	close(fd);
	return 0;
}

static int repo_verify_index(struct repository *repo)
{
	return verify_index_from(repo->index, repo->index_file);
}

int has_racy_timestamp(struct index_state *istate)
{
	int entries = istate->cache_nr;
	int i;

	for (i = 0; i < entries; i++) {
		struct cache_entry *ce = istate->cache[i];
		if (is_racy_timestamp(istate, ce))
			return 1;
	}
	return 0;
}

void repo_update_index_if_able(struct repository *repo,
			       struct lock_file *lockfile)
{
	if ((repo->index->cache_changed ||
	     has_racy_timestamp(repo->index)) &&
	    repo_verify_index(repo))
		write_locked_index(repo->index, lockfile, COMMIT_LOCK);
	else
		rollback_lock_file(lockfile);
}

static int record_eoie(void)
{
	int val;

	if (!repo_config_get_bool(the_repository, "index.recordendofindexentries", &val))
		return val;

	/*
	 * As a convenience, the end of index entries extension
	 * used for threading is written by default if the user
	 * explicitly requested threaded index reads.
	 */
	return !repo_config_get_index_threads(the_repository, &val) && val != 1;
}

static int record_ieot(void)
{
	int val;

	if (!repo_config_get_bool(the_repository, "index.recordoffsettable", &val))
		return val;

	/*
	 * As a convenience, the offset table used for threading is
	 * written by default if the user explicitly requested
	 * threaded index reads.
	 */
	return !repo_config_get_index_threads(the_repository, &val) && val != 1;
}

enum write_extensions {
	WRITE_NO_EXTENSION =              0,
	WRITE_SPLIT_INDEX_EXTENSION =     1<<0,
	WRITE_CACHE_TREE_EXTENSION =      1<<1,
	WRITE_RESOLVE_UNDO_EXTENSION =    1<<2,
	WRITE_UNTRACKED_CACHE_EXTENSION = 1<<3,
	WRITE_FSMONITOR_EXTENSION =       1<<4,
};
#define WRITE_ALL_EXTENSIONS ((enum write_extensions)-1)

/*
 * On success, `tempfile` is closed. If it is the temporary file
 * of a `struct lock_file`, we will therefore effectively perform
 * a 'close_lock_file_gently()`. Since that is an implementation
 * detail of lockfiles, callers of `do_write_index()` should not
 * rely on it.
 */
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
			  enum write_extensions write_extensions, unsigned flags)
{
	uint64_t start = getnanotime();
	struct hashfile *f;
	struct git_hash_ctx *eoie_c = NULL;
	struct cache_header hdr;
	int i, err = 0, removed, extended, hdr_version;
	struct cache_entry **cache = istate->cache;
	int entries = istate->cache_nr;
	struct stat st;
	struct ondisk_cache_entry ondisk;
	struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
	int drop_cache_tree = istate->drop_cache_tree;
	off_t offset;
	int csum_fsync_flag;
	int ieot_entries = 1;
	struct index_entry_offset_table *ieot = NULL;
	struct repository *r = istate->repo;
	struct strbuf sb = STRBUF_INIT;
	int nr, nr_threads, ret;

	f = hashfd(the_repository->hash_algo, tempfile->fd, tempfile->filename.buf);

	prepare_repo_settings(r);
	f->skip_hash = r->settings.index_skip_hash;

	for (i = removed = extended = 0; i < entries; i++) {
		if (cache[i]->ce_flags & CE_REMOVE)
			removed++;

		/* reduce extended entries if possible */
		cache[i]->ce_flags &= ~CE_EXTENDED;
		if (cache[i]->ce_flags & CE_EXTENDED_FLAGS) {
			extended++;
			cache[i]->ce_flags |= CE_EXTENDED;
		}
	}

	if (!istate->version)
		istate->version = get_index_format_default(r);

	/* demote version 3 to version 2 when the latter suffices */
	if (istate->version == 3 || istate->version == 2)
		istate->version = extended ? 3 : 2;

	hdr_version = istate->version;

	hdr.hdr_signature = htonl(CACHE_SIGNATURE);
	hdr.hdr_version = htonl(hdr_version);
	hdr.hdr_entries = htonl(entries - removed);

	hashwrite(f, &hdr, sizeof(hdr));

	if (!HAVE_THREADS || repo_config_get_index_threads(the_repository, &nr_threads))
		nr_threads = 1;

	if (nr_threads != 1 && record_ieot()) {
		int ieot_blocks, cpus;

		/*
		 * ensure default number of ieot blocks maps evenly to the
		 * default number of threads that will process them leaving
		 * room for the thread to load the index extensions.
		 */
		if (!nr_threads) {
			ieot_blocks = istate->cache_nr / THREAD_COST;
			cpus = online_cpus();
			if (ieot_blocks > cpus - 1)
				ieot_blocks = cpus - 1;
		} else {
			ieot_blocks = nr_threads;
			if (ieot_blocks > istate->cache_nr)
				ieot_blocks = istate->cache_nr;
		}

		/*
		 * no reason to write out the IEOT extension if we don't
		 * have enough blocks to utilize multi-threading
		 */
		if (ieot_blocks > 1) {
			ieot = xcalloc(1, sizeof(struct index_entry_offset_table)
				+ (ieot_blocks * sizeof(struct index_entry_offset)));
			ieot_entries = DIV_ROUND_UP(entries, ieot_blocks);
		}
	}

	offset = hashfile_total(f);

	nr = 0;
	previous_name = (hdr_version == 4) ? &previous_name_buf : NULL;

	for (i = 0; i < entries; i++) {
		struct cache_entry *ce = cache[i];
		if (ce->ce_flags & CE_REMOVE)
			continue;
		if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
			ce_smudge_racily_clean_entry(istate, ce);
		if (is_null_oid(&ce->oid)) {
			static const char msg[] = "cache entry has null sha1: %s";
			static int allow = -1;

			if (allow < 0)
				allow = git_env_bool("GIT_ALLOW_NULL_SHA1", 0);
			if (allow)
				warning(msg, ce->name);
			else
				err = error(msg, ce->name);

			drop_cache_tree = 1;
		}
		if (ieot && i && (i % ieot_entries == 0)) {
			ieot->entries[ieot->nr].nr = nr;
			ieot->entries[ieot->nr].offset = offset;
			ieot->nr++;
			/*
			 * If we have a V4 index, set the first byte to an invalid
			 * character to ensure there is nothing common with the previous
			 * entry
			 */
			if (previous_name)
				previous_name->buf[0] = 0;
			nr = 0;

			offset = hashfile_total(f);
		}
		if (ce_write_entry(f, ce, previous_name, (struct ondisk_cache_entry *)&ondisk) < 0)
			err = -1;

		if (err)
			break;
		nr++;
	}
	if (ieot && nr) {
		ieot->entries[ieot->nr].nr = nr;
		ieot->entries[ieot->nr].offset = offset;
		ieot->nr++;
	}
	strbuf_release(&previous_name_buf);

	if (err) {
		ret = err;
		goto out;
	}

	offset = hashfile_total(f);

	/*
	 * The extension headers must be hashed on their own for the
	 * EOIE extension. Create a hashfile here to compute that hash.
	 */
	if (offset && record_eoie()) {
		CALLOC_ARRAY(eoie_c, 1);
		git_hash_init(eoie_c, the_hash_algo);
	}

	/*
	 * Lets write out CACHE_EXT_INDEXENTRYOFFSETTABLE first so that we
	 * can minimize the number of extensions we have to scan through to
	 * find it during load.  Write it out regardless of the
	 * strip_extensions parameter as we need it when loading the shared
	 * index.
	 */
	if (ieot) {
		strbuf_reset(&sb);

		write_ieot_extension(&sb, ieot);
		err = write_index_ext_header(f, eoie_c, CACHE_EXT_INDEXENTRYOFFSETTABLE, sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}

	if (write_extensions & WRITE_SPLIT_INDEX_EXTENSION &&
	    istate->split_index) {
		strbuf_reset(&sb);

		if (istate->sparse_index)
			die(_("cannot write split index for a sparse index"));

		err = write_link_extension(&sb, istate) < 0 ||
			write_index_ext_header(f, eoie_c, CACHE_EXT_LINK,
					       sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}
	if (write_extensions & WRITE_CACHE_TREE_EXTENSION &&
	    !drop_cache_tree && istate->cache_tree) {
		strbuf_reset(&sb);

		cache_tree_write(&sb, istate->cache_tree);
		err = write_index_ext_header(f, eoie_c, CACHE_EXT_TREE, sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}
	if (write_extensions & WRITE_RESOLVE_UNDO_EXTENSION &&
	    istate->resolve_undo) {
		strbuf_reset(&sb);

		resolve_undo_write(&sb, istate->resolve_undo, the_hash_algo);
		err = write_index_ext_header(f, eoie_c, CACHE_EXT_RESOLVE_UNDO,
					     sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}
	if (write_extensions & WRITE_UNTRACKED_CACHE_EXTENSION &&
	    istate->untracked) {
		strbuf_reset(&sb);

		write_untracked_extension(&sb, istate->untracked);
		err = write_index_ext_header(f, eoie_c, CACHE_EXT_UNTRACKED,
					     sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}
	if (write_extensions & WRITE_FSMONITOR_EXTENSION &&
	    istate->fsmonitor_last_update) {
		strbuf_reset(&sb);

		write_fsmonitor_extension(&sb, istate);
		err = write_index_ext_header(f, eoie_c, CACHE_EXT_FSMONITOR, sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}
	if (istate->sparse_index) {
		if (write_index_ext_header(f, eoie_c, CACHE_EXT_SPARSE_DIRECTORIES, 0) < 0) {
			ret = -1;
			goto out;
		}
	}

	/*
	 * CACHE_EXT_ENDOFINDEXENTRIES must be written as the last entry before the SHA1
	 * so that it can be found and processed before all the index entries are
	 * read.  Write it out regardless of the strip_extensions parameter as we need it
	 * when loading the shared index.
	 */
	if (eoie_c) {
		strbuf_reset(&sb);

		write_eoie_extension(&sb, eoie_c, offset);
		err = write_index_ext_header(f, NULL, CACHE_EXT_ENDOFINDEXENTRIES, sb.len) < 0;
		hashwrite(f, sb.buf, sb.len);
		if (err) {
			ret = -1;
			goto out;
		}
	}

	csum_fsync_flag = 0;
	if (!alternate_index_output && (flags & COMMIT_LOCK))
		csum_fsync_flag = CSUM_FSYNC;

	finalize_hashfile(f, istate->oid.hash, FSYNC_COMPONENT_INDEX,
			  CSUM_HASH_IN_STREAM | csum_fsync_flag);
	f = NULL;

	if (close_tempfile_gently(tempfile)) {
		ret = error(_("could not close '%s'"), get_tempfile_path(tempfile));
		goto out;
	}
	if (stat(get_tempfile_path(tempfile), &st)) {
		ret = -1;
		goto out;
	}
	istate->timestamp.sec = (unsigned int)st.st_mtime;
	istate->timestamp.nsec = ST_MTIME_NSEC(st);
	trace_performance_since(start, "write index, changed mask = %x", istate->cache_changed);

	trace2_data_intmax("index", istate->repo, "write/version",
			   istate->version);
	trace2_data_intmax("index", istate->repo, "write/cache_nr",
			   istate->cache_nr);

	ret = 0;

out:
	if (f)
		free_hashfile(f);
	strbuf_release(&sb);
	free(eoie_c);
	free(ieot);
	return ret;
}

void set_alternate_index_output(const char *name)
{
	alternate_index_output = name;
}

static int commit_locked_index(struct lock_file *lk)
{
	if (alternate_index_output)
		return commit_lock_file_to(lk, alternate_index_output);
	else
		return commit_lock_file(lk);
}

static int do_write_locked_index(struct index_state *istate,
				 struct lock_file *lock,
				 unsigned flags,
				 enum write_extensions write_extensions)
{
	int ret;
	int was_full = istate->sparse_index == INDEX_EXPANDED;

	ret = convert_to_sparse(istate, 0);

	if (ret) {
		warning(_("failed to convert to a sparse-index"));
		return ret;
	}

	trace2_region_enter_printf("index", "do_write_index", istate->repo,
				   "%s", get_lock_file_path(lock));
	ret = do_write_index(istate, lock->tempfile, write_extensions, flags);
	trace2_region_leave_printf("index", "do_write_index", istate->repo,
				   "%s", get_lock_file_path(lock));

	if (was_full)
		ensure_full_index(istate);

	if (ret)
		return ret;
	if (flags & COMMIT_LOCK)
		ret = commit_locked_index(lock);
	else
		ret = close_lock_file_gently(lock);

	run_hooks_l(the_repository, "post-index-change",
		    istate->updated_workdir ? "1" : "0",
		    istate->updated_skipworktree ? "1" : "0", NULL);
	istate->updated_workdir = 0;
	istate->updated_skipworktree = 0;

	return ret;
}

static int write_split_index(struct index_state *istate,
			     struct lock_file *lock,
			     unsigned flags)
{
	int ret;
	prepare_to_write_split_index(istate);
	ret = do_write_locked_index(istate, lock, flags, WRITE_ALL_EXTENSIONS);
	finish_writing_split_index(istate);
	return ret;
}

static unsigned long get_shared_index_expire_date(void)
{
	static unsigned long shared_index_expire_date;
	static int shared_index_expire_date_prepared;

	if (!shared_index_expire_date_prepared) {
		const char *shared_index_expire = "2.weeks.ago";
		char *value = NULL;

		repo_config_get_expiry(the_repository, "splitindex.sharedindexexpire",
				       &value);
		if (value)
			shared_index_expire = value;

		shared_index_expire_date = approxidate(shared_index_expire);
		shared_index_expire_date_prepared = 1;

		free(value);
	}

	return shared_index_expire_date;
}

static int should_delete_shared_index(const char *shared_index_path)
{
	struct stat st;
	unsigned long expiration;

	/* Check timestamp */
	expiration = get_shared_index_expire_date();
	if (!expiration)
		return 0;
	if (stat(shared_index_path, &st))
		return error_errno(_("could not stat '%s'"), shared_index_path);
	if (st.st_mtime > expiration)
		return 0;

	return 1;
}

static int clean_shared_index_files(const char *current_hex)
{
	struct dirent *de;
	DIR *dir = opendir(repo_get_git_dir(the_repository));

	if (!dir)
		return error_errno(_("unable to open git dir: %s"),
				   repo_get_git_dir(the_repository));

	while ((de = readdir(dir)) != NULL) {
		const char *sha1_hex;
		char *shared_index_path;
		if (!skip_prefix(de->d_name, "sharedindex.", &sha1_hex))
			continue;
		if (!strcmp(sha1_hex, current_hex))
			continue;

		shared_index_path = repo_git_path(the_repository, "%s", de->d_name);
		if (should_delete_shared_index(shared_index_path) > 0 &&
		    unlink(shared_index_path))
			warning_errno(_("unable to unlink: %s"), shared_index_path);

		free(shared_index_path);
	}
	closedir(dir);

	return 0;
}

static int write_shared_index(struct index_state *istate,
			      struct tempfile **temp, unsigned flags)
{
	struct split_index *si = istate->split_index;
	int ret, was_full = !istate->sparse_index;
	char *path;

	move_cache_to_base_index(istate);
	convert_to_sparse(istate, 0);

	trace2_region_enter_printf("index", "shared/do_write_index",
				   the_repository, "%s", get_tempfile_path(*temp));
	ret = do_write_index(si->base, *temp, WRITE_NO_EXTENSION, flags);
	trace2_region_leave_printf("index", "shared/do_write_index",
				   the_repository, "%s", get_tempfile_path(*temp));

	if (was_full)
		ensure_full_index(istate);

	if (ret)
		return ret;
	ret = adjust_shared_perm(the_repository, get_tempfile_path(*temp));
	if (ret) {
		error(_("cannot fix permission bits on '%s'"), get_tempfile_path(*temp));
		return ret;
	}

	path = repo_git_path(the_repository, "sharedindex.%s", oid_to_hex(&si->base->oid));
	ret = rename_tempfile(temp, path);
	if (!ret) {
		oidcpy(&si->base_oid, &si->base->oid);
		clean_shared_index_files(oid_to_hex(&si->base->oid));
	}

	free(path);
	return ret;
}

static const int default_max_percent_split_change = 20;

static int too_many_not_shared_entries(struct index_state *istate)
{
	int i, not_shared = 0;
	int max_split = repo_config_get_max_percent_split_change(the_repository);

	switch (max_split) {
	case -1:
		/* not or badly configured: use the default value */
		max_split = default_max_percent_split_change;
		break;
	case 0:
		return 1; /* 0% means always write a new shared index */
	case 100:
		return 0; /* 100% means never write a new shared index */
	default:
		break; /* just use the configured value */
	}

	/* Count not shared entries */
	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];
		if (!ce->index)
			not_shared++;
	}

	return (int64_t)istate->cache_nr * max_split < (int64_t)not_shared * 100;
}

int write_locked_index(struct index_state *istate, struct lock_file *lock,
		       unsigned flags)
{
	int new_shared_index, ret, test_split_index_env;
	struct split_index *si = istate->split_index;

	if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0) &&
	    cache_tree_verify(the_repository, istate) < 0)
		return -1;

	if ((flags & SKIP_IF_UNCHANGED) && !istate->cache_changed) {
		if (flags & COMMIT_LOCK)
			rollback_lock_file(lock);
		return 0;
	}

	if (istate->fsmonitor_last_update)
		fill_fsmonitor_bitmap(istate);

	test_split_index_env = git_env_bool("GIT_TEST_SPLIT_INDEX", 0);

	if ((!si && !test_split_index_env) ||
	    alternate_index_output ||
	    (istate->cache_changed & ~EXTMASK)) {
		ret = do_write_locked_index(istate, lock, flags,
					    ~WRITE_SPLIT_INDEX_EXTENSION);
		goto out;
	}

	if (test_split_index_env) {
		if (!si) {
			si = init_split_index(istate);
			istate->cache_changed |= SPLIT_INDEX_ORDERED;
		} else {
			int v = si->base_oid.hash[0];
			if ((v & 15) < 6)
				istate->cache_changed |= SPLIT_INDEX_ORDERED;
		}
	}
	if (too_many_not_shared_entries(istate))
		istate->cache_changed |= SPLIT_INDEX_ORDERED;

	new_shared_index = istate->cache_changed & SPLIT_INDEX_ORDERED;

	if (new_shared_index) {
		struct tempfile *temp;
		int saved_errno;
		char *path;

		/* Same initial permissions as the main .git/index file */
		path = repo_git_path(the_repository, "sharedindex_XXXXXX");
		temp = mks_tempfile_sm(path, 0, 0666);
		free(path);
		if (!temp) {
			ret = do_write_locked_index(istate, lock, flags,
						    ~WRITE_SPLIT_INDEX_EXTENSION);
			goto out;
		}
		ret = write_shared_index(istate, &temp, flags);

		saved_errno = errno;
		if (is_tempfile_active(temp))
			delete_tempfile(&temp);
		errno = saved_errno;

		if (ret)
			goto out;
	}

	ret = write_split_index(istate, lock, flags);

	/* Freshen the shared index only if the split-index was written */
	if (!ret && !new_shared_index && !is_null_oid(&si->base_oid)) {
		char *shared_index = repo_git_path(the_repository, "sharedindex.%s",
						   oid_to_hex(&si->base_oid));
		freshen_shared_index(shared_index, 1);
		free(shared_index);
	}

out:
	if (flags & COMMIT_LOCK)
		rollback_lock_file(lock);
	return ret;
}

/*
 * Read the index file that is potentially unmerged into given
 * index_state, dropping any unmerged entries to stage #0 (potentially
 * resulting in a path appearing as both a file and a directory in the
 * index; the caller is responsible to clear out the extra entries
 * before writing the index to a tree).  Returns true if the index is
 * unmerged.  Callers who want to refuse to work from an unmerged
 * state can call this and check its return value, instead of calling
 * read_cache().
 */
int repo_read_index_unmerged(struct repository *repo)
{
	repo_read_index(repo);
	return index_state_unmerged_to_stage0(repo->index);
}

int index_state_unmerged_to_stage0(struct index_state *istate)
{
	int unmerged = 0;

	for (unsigned int i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];
		struct cache_entry *new_ce;
		int len;

		if (!ce_stage(ce))
			continue;
		unmerged = 1;
		len = ce_namelen(ce);
		new_ce = make_empty_cache_entry(istate, len);
		memcpy(new_ce->name, ce->name, len);
		new_ce->ce_flags = create_ce_flags(0) | CE_CONFLICTED;
		new_ce->ce_namelen = len;
		new_ce->ce_mode = ce->ce_mode;
		if (add_index_entry(istate, new_ce, ADD_CACHE_SKIP_DFCHECK))
			return error(_("%s: cannot drop to stage #0"),
				     new_ce->name);
	}
	return unmerged;
}

/*
 * Returns 1 if the path is an "other" path with respect to
 * the index; that is, the path is not mentioned in the index at all,
 * either as a file, a directory with some files in the index,
 * or as an unmerged entry.
 *
 * We helpfully remove a trailing "/" from directories so that
 * the output of read_directory can be used as-is.
 */
int index_name_is_other(struct index_state *istate, const char *name,
			int namelen)
{
	int pos;
	if (namelen && name[namelen - 1] == '/')
		namelen--;
	pos = index_name_pos(istate, name, namelen);
	if (0 <= pos)
		return 0;	/* exact match */
	pos = -pos - 1;
	if (pos < istate->cache_nr) {
		struct cache_entry *ce = istate->cache[pos];
		if (ce_namelen(ce) == namelen &&
		    !memcmp(ce->name, name, namelen))
			return 0; /* Yup, this one exists unmerged */
	}
	return 1;
}

void *read_blob_data_from_index(struct index_state *istate,
				const char *path, unsigned long *size)
{
	int pos, len;
	size_t sz;
	enum object_type type;
	void *data;

	len = strlen(path);
	pos = index_name_pos(istate, path, len);
	if (pos < 0) {
		/*
		 * We might be in the middle of a merge, in which
		 * case we would read stage #2 (ours).
		 */
		int i;
		for (i = -pos - 1;
		     (pos < 0 && i < istate->cache_nr &&
		      !strcmp(istate->cache[i]->name, path));
		     i++)
			if (ce_stage(istate->cache[i]) == 2)
				pos = i;
	}
	if (pos < 0)
		return NULL;
	data = odb_read_object(the_repository->objects, &istate->cache[pos]->oid,
			       &type, &sz);
	if (!data || type != OBJ_BLOB) {
		free(data);
		return NULL;
	}
	if (size)
		*size = cast_size_t_to_ulong(sz);
	return data;
}

void move_index_extensions(struct index_state *dst, struct index_state *src)
{
	dst->untracked = src->untracked;
	src->untracked = NULL;
	dst->cache_tree = src->cache_tree;
	src->cache_tree = NULL;
}

struct cache_entry *dup_cache_entry(const struct cache_entry *ce,
				    struct index_state *istate)
{
	unsigned int size = ce_size(ce);
	int mem_pool_allocated;
	struct cache_entry *new_entry = make_empty_cache_entry(istate, ce_namelen(ce));
	mem_pool_allocated = new_entry->mem_pool_allocated;

	memcpy(new_entry, ce, size);
	new_entry->mem_pool_allocated = mem_pool_allocated;
	return new_entry;
}

void discard_cache_entry(struct cache_entry *ce)
{
	if (ce && should_validate_cache_entries())
		memset(ce, 0xCD, cache_entry_size(ce->ce_namelen));

	if (ce && ce->mem_pool_allocated)
		return;

	free(ce);
}

int should_validate_cache_entries(void)
{
	static int validate_index_cache_entries = -1;

	if (validate_index_cache_entries < 0) {
		if (getenv("GIT_TEST_VALIDATE_INDEX_CACHE_ENTRIES"))
			validate_index_cache_entries = 1;
		else
			validate_index_cache_entries = 0;
	}

	return validate_index_cache_entries;
}

#define EOIE_SIZE (4 + GIT_SHA1_RAWSZ) /* <4-byte offset> + <20-byte hash> */
#define EOIE_SIZE_WITH_HEADER (4 + 4 + EOIE_SIZE) /* <4-byte signature> + <4-byte length> + EOIE_SIZE */

static size_t read_eoie_extension(const char *mmap, size_t mmap_size)
{
	/*
	 * The end of index entries (EOIE) extension is guaranteed to be last
	 * so that it can be found by scanning backwards from the EOF.
	 *
	 * "EOIE"
	 * <4-byte length>
	 * <4-byte offset>
	 * <20-byte hash>
	 */
	const char *index, *eoie;
	uint32_t extsize;
	size_t offset, src_offset;
	unsigned char hash[GIT_MAX_RAWSZ];
	struct git_hash_ctx c;

	/* ensure we have an index big enough to contain an EOIE extension */
	if (mmap_size < sizeof(struct cache_header) + EOIE_SIZE_WITH_HEADER + the_hash_algo->rawsz)
		return 0;

	/* validate the extension signature */
	index = eoie = mmap + mmap_size - EOIE_SIZE_WITH_HEADER - the_hash_algo->rawsz;
	if (CACHE_EXT(index) != CACHE_EXT_ENDOFINDEXENTRIES)
		return 0;
	index += sizeof(uint32_t);

	/* validate the extension size */
	extsize = get_be32(index);
	if (extsize != EOIE_SIZE)
		return 0;
	index += sizeof(uint32_t);

	/*
	 * Validate the offset we're going to look for the first extension
	 * signature is after the index header and before the eoie extension.
	 */
	offset = get_be32(index);
	if (mmap + offset < mmap + sizeof(struct cache_header))
		return 0;
	if (mmap + offset >= eoie)
		return 0;
	index += sizeof(uint32_t);

	/*
	 * The hash is computed over extension types and their sizes (but not
	 * their contents).  E.g. if we have "TREE" extension that is N-bytes
	 * long, "REUC" extension that is M-bytes long, followed by "EOIE",
	 * then the hash would be:
	 *
	 * SHA-1("TREE" + <binary representation of N> +
	 *	 "REUC" + <binary representation of M>)
	 */
	src_offset = offset;
	git_hash_init(&c, the_hash_algo);
	while (src_offset < mmap_size - the_hash_algo->rawsz - EOIE_SIZE_WITH_HEADER) {
		/* After an array of active_nr index entries,
		 * there can be arbitrary number of extended
		 * sections, each of which is prefixed with
		 * extension name (4-byte) and section length
		 * in 4-byte network byte order.
		 */
		uint32_t extsize;
		memcpy(&extsize, mmap + src_offset + 4, 4);
		extsize = ntohl(extsize);

		/* verify the extension size isn't so large it will wrap around */
		if (src_offset + 8 + extsize < src_offset)
			return 0;

		git_hash_update(&c, mmap + src_offset, 8);

		src_offset += 8;
		src_offset += extsize;
	}
	git_hash_final(hash, &c);
	if (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))
		return 0;

	/* Validate that the extension offsets returned us back to the eoie extension. */
	if (src_offset != mmap_size - the_hash_algo->rawsz - EOIE_SIZE_WITH_HEADER)
		return 0;

	return offset;
}

static void write_eoie_extension(struct strbuf *sb, struct git_hash_ctx *eoie_context, size_t offset)
{
	uint32_t buffer;
	unsigned char hash[GIT_MAX_RAWSZ];

	/* offset */
	put_be32(&buffer, offset);
	strbuf_add(sb, &buffer, sizeof(uint32_t));

	/* hash */
	git_hash_final(hash, eoie_context);
	strbuf_add(sb, hash, the_hash_algo->rawsz);
}

#define IEOT_VERSION	(1)

static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset)
{
	const char *index = NULL;
	uint32_t extsize, ext_version;
	struct index_entry_offset_table *ieot;
	int i, nr;

	/* find the IEOT extension */
	if (!offset)
		return NULL;
	while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
		extsize = get_be32(mmap + offset + 4);
		if (CACHE_EXT((mmap + offset)) == CACHE_EXT_INDEXENTRYOFFSETTABLE) {
			index = mmap + offset + 4 + 4;
			break;
		}
		offset += 8;
		offset += extsize;
	}
	if (!index)
		return NULL;

	/* validate the version is IEOT_VERSION */
	ext_version = get_be32(index);
	if (ext_version != IEOT_VERSION) {
		error("invalid IEOT version %d", ext_version);
		return NULL;
	}
	index += sizeof(uint32_t);

	/* extension size - version bytes / bytes per entry */
	nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + sizeof(uint32_t));
	if (!nr) {
		error("invalid number of IEOT entries %d", nr);
		return NULL;
	}
	ieot = xmalloc(sizeof(struct index_entry_offset_table)
		       + (nr * sizeof(struct index_entry_offset)));
	ieot->nr = nr;
	for (i = 0; i < nr; i++) {
		ieot->entries[i].offset = get_be32(index);
		index += sizeof(uint32_t);
		ieot->entries[i].nr = get_be32(index);
		index += sizeof(uint32_t);
	}

	return ieot;
}

static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot)
{
	uint32_t buffer;
	int i;

	/* version */
	put_be32(&buffer, IEOT_VERSION);
	strbuf_add(sb, &buffer, sizeof(uint32_t));

	/* ieot */
	for (i = 0; i < ieot->nr; i++) {

		/* offset */
		put_be32(&buffer, ieot->entries[i].offset);
		strbuf_add(sb, &buffer, sizeof(uint32_t));

		/* count */
		put_be32(&buffer, ieot->entries[i].nr);
		strbuf_add(sb, &buffer, sizeof(uint32_t));
	}
}

void prefetch_cache_entries(const struct index_state *istate,
			    must_prefetch_predicate must_prefetch)
{
	int i;
	struct oid_array to_fetch = OID_ARRAY_INIT;

	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];

		if (S_ISGITLINK(ce->ce_mode) || !must_prefetch(ce))
			continue;
		if (!odb_read_object_info_extended(the_repository->objects,
						   &ce->oid, NULL,
						   OBJECT_INFO_FOR_PREFETCH))
			continue;
		oid_array_append(&to_fetch, &ce->oid);
	}
	promisor_remote_get_direct(the_repository,
				   to_fetch.oid, to_fetch.nr);
	oid_array_clear(&to_fetch);
}

static int read_one_entry_opt(struct index_state *istate,
			      const struct object_id *oid,
			      struct strbuf *base,
			      const char *pathname,
			      unsigned mode, int opt)
{
	int len;
	struct cache_entry *ce;

	if (S_ISDIR(mode))
		return READ_TREE_RECURSIVE;

	len = strlen(pathname);
	ce = make_empty_cache_entry(istate, base->len + len);

	ce->ce_mode = create_ce_mode(mode);
	ce->ce_flags = create_ce_flags(1);
	ce->ce_namelen = base->len + len;
	memcpy(ce->name, base->buf, base->len);
	memcpy(ce->name + base->len, pathname, len+1);
	oidcpy(&ce->oid, oid);
	return add_index_entry(istate, ce, opt);
}

static int read_one_entry(const struct object_id *oid, struct strbuf *base,
			  const char *pathname, unsigned mode,
			  void *context)
{
	struct index_state *istate = context;
	return read_one_entry_opt(istate, oid, base, pathname,
				  mode,
				  ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
}

/*
 * This is used when the caller knows there is no existing entries at
 * the stage that will conflict with the entry being added.
 */
static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base,
				const char *pathname, unsigned mode,
				void *context)
{
	struct index_state *istate = context;
	return read_one_entry_opt(istate, oid, base, pathname,
				  mode, ADD_CACHE_JUST_APPEND);
}

/*
 * Read the tree specified with --with-tree option
 * (typically, HEAD) into stage #1 and then
 * squash them down to stage #0.  This is used for
 * --error-unmatch to list and check the path patterns
 * that were given from the command line.  We are not
 * going to write this index out.
 */
void overlay_tree_on_index(struct index_state *istate,
			   const char *tree_name, const char *prefix)
{
	struct tree *tree;
	struct object_id oid;
	struct pathspec pathspec;
	struct cache_entry *last_stage0 = NULL;
	int i;
	read_tree_fn_t fn = NULL;
	int err;

	if (repo_get_oid(the_repository, tree_name, &oid))
		die("tree-ish %s not found.", tree_name);
	tree = repo_parse_tree_indirect(the_repository, &oid);
	if (!tree)
		die("bad tree-ish %s", tree_name);

	/* Hoist the unmerged entries up to stage #3 to make room */
	/* TODO: audit for interaction with sparse-index. */
	ensure_full_index(istate);
	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];
		if (!ce_stage(ce))
			continue;
		ce->ce_flags |= CE_STAGEMASK;
	}

	if (prefix) {
		static const char *(matchbuf[1]);
		matchbuf[0] = NULL;
		parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC,
			       PATHSPEC_PREFER_CWD, prefix, matchbuf);
	} else
		memset(&pathspec, 0, sizeof(pathspec));

	/*
	 * See if we have cache entry at the stage.  If so,
	 * do it the original slow way, otherwise, append and then
	 * sort at the end.
	 */
	for (i = 0; !fn && i < istate->cache_nr; i++) {
		const struct cache_entry *ce = istate->cache[i];
		if (ce_stage(ce) == 1)
			fn = read_one_entry;
	}

	if (!fn)
		fn = read_one_entry_quick;
	err = read_tree(the_repository, tree, &pathspec, fn, istate);
	clear_pathspec(&pathspec);
	if (err)
		die("unable to read tree entries %s", tree_name);

	/*
	 * Sort the cache entry -- we need to nuke the cache tree, though.
	 */
	if (fn == read_one_entry_quick) {
		cache_tree_free(&istate->cache_tree);
		QSORT(istate->cache, istate->cache_nr, cmp_cache_name_compare);
	}

	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];
		switch (ce_stage(ce)) {
		case 0:
			last_stage0 = ce;
			/* fallthru */
		default:
			continue;
		case 1:
			/*
			 * If there is stage #0 entry for this, we do not
			 * need to show it.  We use CE_UPDATE bit to mark
			 * such an entry.
			 */
			if (last_stage0 &&
			    !strcmp(last_stage0->name, ce->name))
				ce->ce_flags |= CE_UPDATE;
		}
	}
}

struct update_callback_data {
	struct index_state *index;
	struct repository *repo;
	struct pathspec *pathspec;
	int include_sparse;
	int flags;
	int add_errors;
	int ignored_too;
};

static int fix_unmerged_status(struct diff_filepair *p,
			       struct update_callback_data *data)
{
	if (p->status != DIFF_STATUS_UNMERGED)
		return p->status;
	if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
		/*
		 * This is not an explicit add request, and the
		 * path is missing from the working tree (deleted)
		 */
		return DIFF_STATUS_DELETED;
	else
		/*
		 * Either an explicit add request, or path exists
		 * in the working tree.  An attempt to explicitly
		 * add a path that does not exist in the working tree
		 * will be caught as an error by the caller immediately.
		 */
		return DIFF_STATUS_MODIFIED;
}

static int skip_submodule(const char *path,
						struct repository *repo,
						struct pathspec *pathspec,
						int ignored_too)
{
    struct stat st;
    const struct submodule *sub;
    int pathspec_matches = 0;
    int ps_i;
    char *norm_pathspec = NULL;

    /* Only consider if path is a directory */
    if (lstat(path, &st) || !S_ISDIR(st.st_mode))
		return 0;

    /* Check if it's a submodule with ignore=all */
    sub = submodule_from_path(repo, null_oid(the_hash_algo), path);
    if (!sub || !sub->name || !sub->ignore || strcmp(sub->ignore, "all"))
		return 0;

    trace_printf("ignore=all: %s\n", path);
    trace_printf("pathspec %s\n", (pathspec && pathspec->nr)
									? "has pathspec"
									: "no pathspec");

    /* Check if submodule path is explicitly mentioned in pathspec */
    if (pathspec) {
		for (ps_i = 0; ps_i < pathspec->nr; ps_i++) {
			const char *m = pathspec->items[ps_i].match;
			if (!m)
				continue;
			norm_pathspec = xstrdup(m);
			strip_dir_trailing_slashes(norm_pathspec);
			if (!strcmp(path, norm_pathspec)) {
				pathspec_matches = 1;
				FREE_AND_NULL(norm_pathspec);
				break;
			}
			FREE_AND_NULL(norm_pathspec);
		}
    }

    /* If explicitly matched and forced, allow adding */
    if (pathspec_matches) {
		if (ignored_too && ignored_too > 0) {
			trace_printf("Add submodule due to --force: %s\n", path);
			return 0;
		} else {
			advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
				_("Skipping submodule due to ignore=all: %s\n"
					"Use --force if you really want to add the submodule."), path);
			return 1;
		}
    }

    /* No explicit pathspec match -> skip silently */
    trace_printf("Pathspec to submodule does not match explicitly: %s\n", path);
    return 1;
}

static void update_callback(struct diff_queue_struct *q,
							struct diff_options *opt UNUSED, void *cbdata)
{
	int i;
	struct update_callback_data *data = cbdata;

	for (i = 0; i < q->nr; i++) {
		struct diff_filepair *p = q->queue[i];
		const char *path = p->one->path;

		if (!data->include_sparse &&
			!path_in_sparse_checkout(path, data->index))
			continue;

		switch (fix_unmerged_status(p, data)) {
		default:
			die(_("unexpected diff status %c"), p->status);
		case DIFF_STATUS_MODIFIED:
		case DIFF_STATUS_TYPE_CHANGED:
			if (skip_submodule(path, data->repo,
								data->pathspec,
								data->ignored_too))
				continue;

			if (add_file_to_index(data->index, path, data->flags)) {
				if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
					die(_("updating files failed"));
				data->add_errors++;
			}
			break;
		case DIFF_STATUS_DELETED:
			if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
				break;
			if (!(data->flags & ADD_CACHE_PRETEND))
				remove_file_from_index(data->index, path);
			if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
				printf(_("remove '%s'\n"), path);
			break;
		}
	}
}

int add_files_to_cache(struct repository *repo, const char *prefix,
		       const struct pathspec *pathspec, char *ps_matched,
		       int include_sparse, int flags, int ignored_too )
{
	struct odb_transaction *transaction;
	struct update_callback_data data;
	struct rev_info rev;

	memset(&data, 0, sizeof(data));
	data.index = repo->index;
	data.include_sparse = include_sparse;
	data.flags = flags;
	data.repo = repo;
	data.ignored_too = ignored_too;
	data.pathspec = (struct pathspec *)pathspec;

	repo_init_revisions(repo, &rev, prefix);
	setup_revisions(0, NULL, &rev, NULL);
	if (pathspec) {
		copy_pathspec(&rev.prune_data, pathspec);
		rev.ps_matched = ps_matched;
	}
	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
	rev.diffopt.format_callback = update_callback;
	rev.diffopt.format_callback_data = &data;
	rev.diffopt.flags.override_submodule_config = 1;
	rev.diffopt.detect_rename = 0; /* staging worktree changes does not need renames */
	rev.max_count = 0; /* do not compare unmerged paths with stage #2 */

	/*
	 * Use an ODB transaction to optimize adding multiple objects.
	 * This function is invoked from commands other than 'add', which
	 * may not have their own transaction active.
	 */
	transaction = odb_transaction_begin(repo->objects);
	run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
	odb_transaction_commit(transaction);

	release_revisions(&rev);
	return !!data.add_errors;
}
