/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
#include "git2/config.h"
#include "git2/sys/config.h"
#include "git2/types.h"
#include "git2/index.h"
#include "buffer.h"
#include "buf_text.h"
#include "vector.h"
#include "posix.h"
#include "config_file.h"
#include "config.h"
#include "repository.h"
#include "submodule.h"
#include "tree.h"
#include "iterator.h"
#include "path.h"
#include "index.h"

#define GIT_MODULES_FILE ".gitmodules"

static git_cvar_map _sm_update_map[] = {
	{GIT_CVAR_STRING, "checkout", GIT_SUBMODULE_UPDATE_CHECKOUT},
	{GIT_CVAR_STRING, "rebase", GIT_SUBMODULE_UPDATE_REBASE},
	{GIT_CVAR_STRING, "merge", GIT_SUBMODULE_UPDATE_MERGE},
	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_UPDATE_NONE},
	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_UPDATE_NONE},
	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_UPDATE_CHECKOUT},
};

static git_cvar_map _sm_ignore_map[] = {
	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_IGNORE_NONE},
	{GIT_CVAR_STRING, "untracked", GIT_SUBMODULE_IGNORE_UNTRACKED},
	{GIT_CVAR_STRING, "dirty", GIT_SUBMODULE_IGNORE_DIRTY},
	{GIT_CVAR_STRING, "all", GIT_SUBMODULE_IGNORE_ALL},
	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_IGNORE_NONE},
	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_IGNORE_ALL},
};

static git_cvar_map _sm_recurse_map[] = {
	{GIT_CVAR_STRING, "on-demand", GIT_SUBMODULE_RECURSE_ONDEMAND},
	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_RECURSE_NO},
	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_RECURSE_YES},
};

enum {
	CACHE_OK = 0,
	CACHE_REFRESH = 1,
	CACHE_FLUSH = 2
};
enum {
	GITMODULES_EXISTING = 0,
	GITMODULES_CREATE = 1,
};

static kh_inline khint_t str_hash_no_trailing_slash(const char *s)
{
	khint_t h;

	for (h = 0; *s; ++s)
		if (s[1] != '\0' || *s != '/')
			h = (h << 5) - h + *s;

	return h;
}

static kh_inline int str_equal_no_trailing_slash(const char *a, const char *b)
{
	size_t alen = a ? strlen(a) : 0;
	size_t blen = b ? strlen(b) : 0;

	if (alen > 0 && a[alen - 1] == '/')
		alen--;
	if (blen > 0 && b[blen - 1] == '/')
		blen--;

	return (alen == blen && strncmp(a, b, alen) == 0);
}

__KHASH_IMPL(
	str, static kh_inline, const char *, void *, 1,
	str_hash_no_trailing_slash, str_equal_no_trailing_slash)

static int submodule_cache_init(git_repository *repo, int refresh);
static void submodule_cache_free(git_submodule_cache *cache);

static git_config_backend *open_gitmodules(git_submodule_cache *, int gitmod);
static int get_url_base(git_buf *url, git_repository *repo);
static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
static int submodule_get(git_submodule **, git_submodule_cache *, const char *, const char *);
static int submodule_load_from_config(const git_config_entry *, void *);
static int submodule_load_from_wd_lite(git_submodule *);
static void submodule_get_index_status(unsigned int *, git_submodule *);
static void submodule_get_wd_status(unsigned int *, git_submodule *, git_repository *, git_submodule_ignore_t);

static int submodule_cmp(const void *a, const void *b)
{
	return strcmp(((git_submodule *)a)->name, ((git_submodule *)b)->name);
}

static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix)
{
	ssize_t idx = git_buf_rfind(key, '.');
	git_buf_truncate(key, (size_t)(idx + 1));
	return git_buf_puts(key, suffix);
}

/* lookup submodule or return ENOTFOUND if it doesn't exist */
static int submodule_lookup(
	git_submodule **out,
	git_submodule_cache *cache,
	const char *name,
	const char *alternate)
{
	khiter_t pos;

	/* lock cache */

	pos = git_strmap_lookup_index(cache->submodules, name);

	if (!git_strmap_valid_index(cache->submodules, pos) && alternate)
		pos = git_strmap_lookup_index(cache->submodules, alternate);

	if (!git_strmap_valid_index(cache->submodules, pos)) {
		/* unlock cache */
		return GIT_ENOTFOUND; /* don't set error - caller will cope */
	}

	if (out != NULL) {
		git_submodule *sm = git_strmap_value_at(cache->submodules, pos);
		GIT_REFCOUNT_INC(sm);
		*out = sm;
	}

	/* unlock cache */

	return 0;
}

/* clear a set of flags on all submodules */
static void submodule_cache_clear_flags(
	git_submodule_cache *cache, uint32_t mask)
{
	git_submodule *sm;
	uint32_t inverted_mask = ~mask;

	git_strmap_foreach_value(cache->submodules, sm, {
		sm->flags &= inverted_mask;
	});
}

/*
 * PUBLIC APIS
 */

bool git_submodule__is_submodule(git_repository *repo, const char *name)
{
	git_strmap *map;

	if (submodule_cache_init(repo, CACHE_OK) < 0) {
		giterr_clear();
		return false;
	}

	if (!repo->_submodules || !(map = repo->_submodules->submodules))
		return false;

	return git_strmap_valid_index(map, git_strmap_lookup_index(map, name));
}

static void submodule_set_lookup_error(int error, const char *name)
{
	if (!error)
		return;

	giterr_set(GITERR_SUBMODULE, (error == GIT_ENOTFOUND) ?
		"No submodule named '%s'" :
		"Submodule '%s' has not been added yet", name);
}

int git_submodule__lookup(
	git_submodule **out, /* NULL if user only wants to test existence */
	git_repository *repo,
	const char *name)    /* trailing slash is allowed */
{
	int error;

	assert(repo && name);

	if ((error = submodule_cache_init(repo, CACHE_OK)) < 0)
		return error;

	if ((error = submodule_lookup(out, repo->_submodules, name, NULL)) < 0)
		submodule_set_lookup_error(error, name);

	return error;
}

int git_submodule_lookup(
	git_submodule **out, /* NULL if user only wants to test existence */
	git_repository *repo,
	const char *name)    /* trailing slash is allowed */
{
	int error;

	assert(repo && name);

	if ((error = submodule_cache_init(repo, CACHE_REFRESH)) < 0)
		return error;

	if ((error = submodule_lookup(out, repo->_submodules, name, NULL)) < 0) {

		/* check if a plausible submodule exists at path */
		if (git_repository_workdir(repo)) {
			git_buf path = GIT_BUF_INIT;

			if (git_buf_join3(&path,
					'/', git_repository_workdir(repo), name, DOT_GIT) < 0)
				return -1;

			if (git_path_exists(path.ptr))
				error = GIT_EEXISTS;

			git_buf_free(&path);
		}

		submodule_set_lookup_error(error, name);
	}

	return error;
}

static void submodule_free_dup(void *sm)
{
	git_submodule_free(sm);
}

int git_submodule_foreach(
	git_repository *repo,
	int (*callback)(git_submodule *sm, const char *name, void *payload),
	void *payload)
{
	int error;
	size_t i;
	git_submodule *sm;
	git_submodule_cache *cache;
	git_vector snapshot = GIT_VECTOR_INIT;

	assert(repo && callback);

	if ((error = submodule_cache_init(repo, CACHE_REFRESH)) < 0)
		return error;

	cache = repo->_submodules;

	if (git_mutex_lock(&cache->lock) < 0) {
		giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
		return -1;
	}

	if (!(error = git_vector_init(
			&snapshot, kh_size(cache->submodules), submodule_cmp))) {

		git_strmap_foreach_value(cache->submodules, sm, {
			if ((error = git_vector_insert(&snapshot, sm)) < 0)
				break;
			GIT_REFCOUNT_INC(sm);
		});
	}

	git_mutex_unlock(&cache->lock);

	if (error < 0)
		goto done;

	git_vector_uniq(&snapshot, submodule_free_dup);

	git_vector_foreach(&snapshot, i, sm) {
		if ((error = callback(sm, sm->name, payload)) != 0) {
			giterr_set_after_callback(error);
			break;
		}
	}

done:
	git_vector_foreach(&snapshot, i, sm)
		git_submodule_free(sm);
	git_vector_free(&snapshot);

	return error;
}

void git_submodule_cache_free(git_repository *repo)
{
	git_submodule_cache *cache;

	assert(repo);

	if ((cache = git__swap(repo->_submodules, NULL)) != NULL)
		submodule_cache_free(cache);
}

static int submodule_repo_init(
	git_repository **out,
	git_repository *parent_repo,
	const char *path,
	const char *url,
	bool use_gitlink)
{
	int error = 0;
	git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT;
	git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	git_repository *subrepo = NULL;

	error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path);
	if (error < 0)
		goto cleanup;

	initopt.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_NO_REINIT;
	initopt.origin_url = url;

	/* init submodule repository and add origin remote as needed */

	/* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a
	 * gitlink in the sub-repo workdir directory to that repository
	 *
	 * Old style: sub-repo goes directly into repo/<name>/.git/
	 */
	 if (use_gitlink) {
		error = git_buf_join3(
			&repodir, '/', git_repository_path(parent_repo), "modules", path);
		if (error < 0)
			goto cleanup;

		initopt.workdir_path = workdir.ptr;
		initopt.flags |=
			GIT_REPOSITORY_INIT_NO_DOTGIT_DIR |
			GIT_REPOSITORY_INIT_RELATIVE_GITLINK;

		error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);
	} else
		error = git_repository_init_ext(&subrepo, workdir.ptr, &initopt);

cleanup:
	git_buf_free(&workdir);
	git_buf_free(&repodir);

	*out = subrepo;

	return error;
}

int git_submodule_add_setup(
	git_submodule **out,
	git_repository *repo,
	const char *url,
	const char *path,
	int use_gitlink)
{
	int error = 0;
	git_config_backend *mods = NULL;
	git_submodule *sm = NULL;
	git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
	git_repository *subrepo = NULL;

	assert(repo && url && path);

	/* see if there is already an entry for this submodule */

	if (git_submodule_lookup(NULL, repo, path) < 0)
		giterr_clear();
	else {
		giterr_set(GITERR_SUBMODULE,
			"Attempt to add submodule '%s' that already exists", path);
		return GIT_EEXISTS;
	}

	/* validate and normalize path */

	if (git__prefixcmp(path, git_repository_workdir(repo)) == 0)
		path += strlen(git_repository_workdir(repo));

	if (git_path_root(path) >= 0) {
		giterr_set(GITERR_SUBMODULE, "Submodule path must be a relative path");
		error = -1;
		goto cleanup;
	}

	/* update .gitmodules */

	if (!(mods = open_gitmodules(repo->_submodules, GITMODULES_CREATE))) {
		giterr_set(GITERR_SUBMODULE,
			"Adding submodules to a bare repository is not supported");
		return -1;
	}

	if ((error = git_buf_printf(&name, "submodule.%s.path", path)) < 0 ||
		(error = git_config_file_set_string(mods, name.ptr, path)) < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(&name, "url")) < 0 ||
		(error = git_config_file_set_string(mods, name.ptr, url)) < 0)
		goto cleanup;

	git_buf_clear(&name);

	/* init submodule repository and add origin remote as needed */

	error = git_buf_joinpath(&name, git_repository_workdir(repo), path);
	if (error < 0)
		goto cleanup;

	/* if the repo does not already exist, then init a new repo and add it.
	 * Otherwise, just add the existing repo.
	 */
	if (!(git_path_exists(name.ptr) &&
		git_path_contains(&name, DOT_GIT))) {

		/* resolve the actual URL to use */
		if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0)
			goto cleanup;

		 if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
			goto cleanup;
	}

	/* add submodule to hash and "reload" it */

	if (git_mutex_lock(&repo->_submodules->lock) < 0) {
		giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
		error = -1;
		goto cleanup;
	}

	if (!(error = submodule_get(&sm, repo->_submodules, path, NULL)) &&
		!(error = git_submodule_reload(sm, false)))
		error = git_submodule_init(sm, false);

	git_mutex_unlock(&repo->_submodules->lock);

cleanup:
	if (error && sm) {
		git_submodule_free(sm);
		sm = NULL;
	}
	if (out != NULL)
		*out = sm;

	git_config_file_free(mods);
	git_repository_free(subrepo);
	git_buf_free(&real_url);
	git_buf_free(&name);

	return error;
}

int git_submodule_repo_init(
	git_repository **out,
	const git_submodule *sm,
	int use_gitlink)
{
	int error;
	git_repository *sub_repo = NULL;
	const char *configured_url;
	git_config *cfg = NULL;
	git_buf buf = GIT_BUF_INIT;

	assert(out && sm);

	/* get the configured remote url of the submodule */
	if ((error = git_buf_printf(&buf, "submodule.%s.url", sm->name)) < 0 ||
		(error = git_repository_config_snapshot(&cfg, sm->repo)) < 0 ||
		(error = git_config_get_string(&configured_url, cfg, buf.ptr)) < 0 ||
		(error = submodule_repo_init(&sub_repo, sm->repo, sm->path, configured_url, use_gitlink)) < 0)
		goto done;

	*out = sub_repo;

done:
	git_config_free(cfg);
	git_buf_free(&buf);
	return error;
}

int git_submodule_add_finalize(git_submodule *sm)
{
	int error;
	git_index *index;

	assert(sm);

	if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 ||
		(error = git_index_add_bypath(index, GIT_MODULES_FILE)) < 0)
		return error;

	return git_submodule_add_to_index(sm, true);
}

int git_submodule_add_to_index(git_submodule *sm, int write_index)
{
	int error;
	git_repository *sm_repo = NULL;
	git_index *index;
	git_buf path = GIT_BUF_INIT;
	git_commit *head;
	git_index_entry entry;
	struct stat st;

	assert(sm);

	/* force reload of wd OID by git_submodule_open */
	sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID;

	if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 ||
		(error = git_buf_joinpath(
			&path, git_repository_workdir(sm->repo), sm->path)) < 0 ||
		(error = git_submodule_open(&sm_repo, sm)) < 0)
		goto cleanup;

	/* read stat information for submodule working directory */
	if (p_stat(path.ptr, &st) < 0) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot add submodule without working directory");
		error = -1;
		goto cleanup;
	}

	memset(&entry, 0, sizeof(entry));
	entry.path = sm->path;
	git_index_entry__init_from_stat(
		&entry, &st, !(git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE));

	/* calling git_submodule_open will have set sm->wd_oid if possible */
	if ((sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) == 0) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot add submodule without HEAD to index");
		error = -1;
		goto cleanup;
	}
	git_oid_cpy(&entry.id, &sm->wd_oid);

	if ((error = git_commit_lookup(&head, sm_repo, &sm->wd_oid)) < 0)
		goto cleanup;

	entry.ctime.seconds = git_commit_time(head);
	entry.ctime.nanoseconds = 0;
	entry.mtime.seconds = git_commit_time(head);
	entry.mtime.nanoseconds = 0;

	git_commit_free(head);

	/* add it */
	error = git_index_add(index, &entry);

	/* write it, if requested */
	if (!error && write_index) {
		error = git_index_write(index);

		if (!error)
			git_oid_cpy(&sm->index_oid, &sm->wd_oid);
	}

cleanup:
	git_repository_free(sm_repo);
	git_buf_free(&path);
	return error;
}

const char *git_submodule_ignore_to_str(git_submodule_ignore_t ignore)
{
	int i;
	for (i = 0; i < (int)ARRAY_SIZE(_sm_ignore_map); ++i)
		if (_sm_ignore_map[i].map_value == ignore)
			return _sm_ignore_map[i].str_match;
	return NULL;
}

const char *git_submodule_update_to_str(git_submodule_update_t update)
{
	int i;
	for (i = 0; i < (int)ARRAY_SIZE(_sm_update_map); ++i)
		if (_sm_update_map[i].map_value == update)
			return _sm_update_map[i].str_match;
	return NULL;
}

const char *git_submodule_recurse_to_str(git_submodule_recurse_t recurse)
{
	int i;
	for (i = 0; i < (int)ARRAY_SIZE(_sm_recurse_map); ++i)
		if (_sm_recurse_map[i].map_value == recurse)
			return _sm_recurse_map[i].str_match;
	return NULL;
}

int git_submodule_save(git_submodule *submodule)
{
	int error = 0;
	git_config_backend *mods;
	git_buf key = GIT_BUF_INIT;
	const char *val;

	assert(submodule);

	mods = open_gitmodules(submodule->repo->_submodules, GITMODULES_CREATE);
	if (!mods) {
		giterr_set(GITERR_SUBMODULE,
			"Adding submodules to a bare repository is not supported");
		return -1;
	}

	if ((error = git_buf_printf(&key, "submodule.%s.", submodule->name)) < 0)
		goto cleanup;

	/* save values for path, url, update, ignore, fetchRecurseSubmodules */

	if ((error = submodule_config_key_trunc_puts(&key, "path")) < 0 ||
		(error = git_config_file_set_string(mods, key.ptr, submodule->path)) < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(&key, "url")) < 0 ||
		(error = git_config_file_set_string(mods, key.ptr, submodule->url)) < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(&key, "branch")) < 0 ||
		(error = git_config_file_set_string(mods, key.ptr, submodule->branch)) < 0)
		goto cleanup;

	if (!(error = submodule_config_key_trunc_puts(&key, "update")) &&
		(val = git_submodule_update_to_str(submodule->update)) != NULL)
		error = git_config_file_set_string(mods, key.ptr, val);
	if (error < 0)
		goto cleanup;

	if (!(error = submodule_config_key_trunc_puts(&key, "ignore")) &&
		(val = git_submodule_ignore_to_str(submodule->ignore)) != NULL)
		error = git_config_file_set_string(mods, key.ptr, val);
	if (error < 0)
		goto cleanup;

	if (!(error = submodule_config_key_trunc_puts(&key, "fetchRecurseSubmodules")) &&
		(val = git_submodule_recurse_to_str(submodule->fetch_recurse)) != NULL)
		error = git_config_file_set_string(mods, key.ptr, val);
	if (error < 0)
		goto cleanup;

	/* update internal defaults */

	submodule->ignore_default = submodule->ignore;
	submodule->update_default = submodule->update;
	submodule->fetch_recurse_default = submodule->fetch_recurse;
	submodule->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;

cleanup:
	git_config_file_free(mods);
	git_buf_free(&key);

	return error;
}

git_repository *git_submodule_owner(git_submodule *submodule)
{
	assert(submodule);
	return submodule->repo;
}

const char *git_submodule_name(git_submodule *submodule)
{
	assert(submodule);
	return submodule->name;
}

const char *git_submodule_path(git_submodule *submodule)
{
	assert(submodule);
	return submodule->path;
}

const char *git_submodule_url(git_submodule *submodule)
{
	assert(submodule);
	return submodule->url;
}

int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url)
{
	int error = 0;

	assert(out && repo && url);

	git_buf_sanitize(out);

	if (git_path_is_relative(url)) {
		if (!(error = get_url_base(out, repo)))
			error = git_path_apply_relative(out, url);
	} else if (strchr(url, ':') != NULL || url[0] == '/') {
		error = git_buf_sets(out, url);
	} else {
		giterr_set(GITERR_SUBMODULE, "Invalid format for submodule URL");
		error = -1;
	}

	return error;
}

const char *git_submodule_branch(git_submodule *submodule)
{
	assert(submodule);
	return submodule->branch;
}

int git_submodule_set_url(git_submodule *submodule, const char *url)
{
	assert(submodule && url);

	git__free(submodule->url);

	submodule->url = git__strdup(url);
	GITERR_CHECK_ALLOC(submodule->url);

	return 0;
}

const git_oid *git_submodule_index_id(git_submodule *submodule)
{
	assert(submodule);

	if (submodule->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID)
		return &submodule->index_oid;
	else
		return NULL;
}

const git_oid *git_submodule_head_id(git_submodule *submodule)
{
	assert(submodule);

	if (submodule->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID)
		return &submodule->head_oid;
	else
		return NULL;
}

const git_oid *git_submodule_wd_id(git_submodule *submodule)
{
	assert(submodule);

	/* load unless we think we have a valid oid */
	if (!(submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)) {
		git_repository *subrepo;

		/* calling submodule open grabs the HEAD OID if possible */
		if (!git_submodule_open_bare(&subrepo, submodule))
			git_repository_free(subrepo);
		else
			giterr_clear();
	}

	if (submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)
		return &submodule->wd_oid;
	else
		return NULL;
}

git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule)
{
	assert(submodule);
	return (submodule->ignore < GIT_SUBMODULE_IGNORE_NONE) ?
		GIT_SUBMODULE_IGNORE_NONE : submodule->ignore;
}

git_submodule_ignore_t git_submodule_set_ignore(
	git_submodule *submodule, git_submodule_ignore_t ignore)
{
	git_submodule_ignore_t old;

	assert(submodule);

	if (ignore == GIT_SUBMODULE_IGNORE_RESET)
		ignore = submodule->ignore_default;

	old = submodule->ignore;
	submodule->ignore = ignore;
	return old;
}

git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule)
{
	assert(submodule);
	return (submodule->update < GIT_SUBMODULE_UPDATE_CHECKOUT) ?
		GIT_SUBMODULE_UPDATE_CHECKOUT : submodule->update;
}

git_submodule_update_t git_submodule_set_update(
	git_submodule *submodule, git_submodule_update_t update)
{
	git_submodule_update_t old;

	assert(submodule);

	if (update == GIT_SUBMODULE_UPDATE_RESET)
		update = submodule->update_default;

	old = submodule->update;
	submodule->update = update;
	return old;
}

git_submodule_recurse_t git_submodule_fetch_recurse_submodules(
	git_submodule *submodule)
{
	assert(submodule);
	return submodule->fetch_recurse;
}

git_submodule_recurse_t git_submodule_set_fetch_recurse_submodules(
	git_submodule *submodule,
	git_submodule_recurse_t fetch_recurse_submodules)
{
	git_submodule_recurse_t old;

	assert(submodule);

	if (fetch_recurse_submodules == GIT_SUBMODULE_RECURSE_RESET)
		fetch_recurse_submodules = submodule->fetch_recurse_default;

	old = submodule->fetch_recurse;
	submodule->fetch_recurse = fetch_recurse_submodules;
	return old;
}

static int submodule_repo_create(
	git_repository **out,
	git_repository *parent_repo,
	const char *path)
{
	int error = 0;
	git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT;
	git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	git_repository *subrepo = NULL;

	initopt.flags =
		GIT_REPOSITORY_INIT_MKPATH |
		GIT_REPOSITORY_INIT_NO_REINIT |
		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR |
		GIT_REPOSITORY_INIT_RELATIVE_GITLINK;

	/* Workdir: path to sub-repo working directory */
	error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path);
	if (error < 0)
		goto cleanup;

	initopt.workdir_path = workdir.ptr;

	/**
	 * Repodir: path to the sub-repo. sub-repo goes in:
	 * <repo-dir>/modules/<name>/ with a gitlink in the 
	 * sub-repo workdir directory to that repository.
	 */
	error = git_buf_join3(
		&repodir, '/', git_repository_path(parent_repo), "modules", path);
	if (error < 0)
		goto cleanup;

	error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);

cleanup:
	git_buf_free(&workdir);
	git_buf_free(&repodir);

	*out = subrepo;

	return error;
}

/**
 * Callback to override sub-repository creation when
 * cloning a sub-repository.
 */
static int git_submodule_update_repo_init_cb(
	git_repository **out,
	const char *path,
	int bare,
	void *payload)
{
	git_submodule *sm;

	GIT_UNUSED(bare);

	sm = payload;

	return submodule_repo_create(out, sm->repo, path);
}

int git_submodule_update_init_options(git_submodule_update_options *opts, unsigned int version)
{
	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
		opts, version, git_submodule_update_options, GIT_SUBMODULE_UPDATE_OPTIONS_INIT);
	return 0;
}

int git_submodule_update(git_submodule *sm, int init, git_submodule_update_options *_update_options)
{
	int error;
	unsigned int submodule_status;
	git_config *config = NULL;
	const char *submodule_url;
	git_repository *sub_repo = NULL;
	git_remote *remote = NULL;
	git_object *target_commit = NULL;
	git_buf buf = GIT_BUF_INIT;
	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
	git_clone_options clone_options = GIT_CLONE_OPTIONS_INIT;

	assert(sm);

	if (_update_options)
		memcpy(&update_options, _update_options, sizeof(git_submodule_update_options));

	GITERR_CHECK_VERSION(&update_options, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, "git_submodule_update_options");

	/* Copy over the remote callbacks */
	clone_options.remote_callbacks = update_options.remote_callbacks;

	/* Get the status of the submodule to determine if it is already initialized  */
	if ((error = git_submodule_status(&submodule_status, sm)) < 0)
		goto done;

	/*
	 * If submodule work dir is not already initialized, check to see
	 * what we need to do (initialize, clone, return error...)
	 */
	if (submodule_status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) {
		/*
		 * Work dir is not initialized, check to see if the submodule
		 * info has been copied into .git/config
		 */
		if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 ||
			(error = git_buf_printf(&buf, "submodule.%s.url", git_submodule_name(sm))) < 0)
			goto done;

		if ((error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0) {
			/*
			 * If the error is not "not found" or if it is "not found" and we are not
			 * initializing the submodule, then return error.
			 */
			if (error != GIT_ENOTFOUND)
				goto done;

			if (error == GIT_ENOTFOUND && !init) {
				giterr_set(GITERR_SUBMODULE, "Submodule is not initialized.");
				error = GIT_ERROR;
				goto done;
			}

			/* The submodule has not been initialized yet - initialize it now.*/
			if ((error = git_submodule_init(sm, 0)) < 0)
				goto done;

			git_config_free(config);
			config = NULL;

			if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 ||
				(error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0)
				goto done;
		}

		/** submodule is initialized - now clone it **/
		/* override repo creation */
		clone_options.repository_cb = git_submodule_update_repo_init_cb;
		clone_options.repository_cb_payload = sm;

		/*
		 * Do not perform checkout as part of clone, instead we 
		 * will checkout the specific commit manually.
		 */
		clone_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
		update_options.checkout_opts.checkout_strategy = update_options.clone_checkout_strategy;

		if ((error = git_clone(&sub_repo, submodule_url, sm->path, &clone_options)) < 0 ||
			(error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0 ||
			(error = git_checkout_head(sub_repo, &update_options.checkout_opts)) != 0)
			goto done;
	} else {
		/**
		 * Work dir is initialized - look up the commit in the parent repository's index,
		 * update the workdir contents of the subrepository, and set the subrepository's
		 * head to the new commit.
		 */
		if ((error = git_submodule_open(&sub_repo, sm)) < 0 ||
			(error = git_object_lookup(&target_commit, sub_repo, git_submodule_index_id(sm), GIT_OBJ_COMMIT)) < 0 ||
			(error = git_checkout_tree(sub_repo, target_commit, &update_options.checkout_opts)) != 0 ||
			(error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0)
			goto done;

		/* Invalidate the wd flags as the workdir has been updated. */
		sm->flags = sm->flags &
			~(GIT_SUBMODULE_STATUS_IN_WD |
		  	GIT_SUBMODULE_STATUS__WD_OID_VALID |
		  	GIT_SUBMODULE_STATUS__WD_SCANNED);
	}

done:
	git_buf_free(&buf);
	git_config_free(config);
	git_object_free(target_commit);
	git_remote_free(remote);
	git_repository_free(sub_repo);

	return error;
}

int git_submodule_init(git_submodule *sm, int overwrite)
{
	int error;
	const char *val;
	git_buf key = GIT_BUF_INIT, effective_submodule_url = GIT_BUF_INIT;
	git_config *cfg = NULL;

	if (!sm->url) {
		giterr_set(GITERR_SUBMODULE,
			"No URL configured for submodule '%s'", sm->name);
		return -1;
	}

	if ((error = git_repository_config(&cfg, sm->repo)) < 0)
		return error;

	/* write "submodule.NAME.url" */

	if ((error = git_submodule_resolve_url(&effective_submodule_url, sm->repo, sm->url)) < 0 ||
		(error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 ||
		(error = git_config__update_entry(
			cfg, key.ptr, effective_submodule_url.ptr, overwrite != 0, false)) < 0)
		goto cleanup;

	/* write "submodule.NAME.update" if not default */

	val = (sm->update == GIT_SUBMODULE_UPDATE_CHECKOUT) ?
		NULL : git_submodule_update_to_str(sm->update);

	if ((error = git_buf_printf(&key, "submodule.%s.update", sm->name)) < 0 ||
		(error = git_config__update_entry(
			cfg, key.ptr, val, overwrite != 0, false)) < 0)
		goto cleanup;

	/* success */

cleanup:
	git_config_free(cfg);
	git_buf_free(&key);
	git_buf_free(&effective_submodule_url);

	return error;
}

int git_submodule_sync(git_submodule *sm)
{
	int error = 0;
	git_config *cfg = NULL;
	git_buf key = GIT_BUF_INIT;
	git_repository *smrepo = NULL;

	if (!sm->url) {
		giterr_set(GITERR_SUBMODULE,
			"No URL configured for submodule '%s'", sm->name);
		return -1;
	}

	/* copy URL over to config only if it already exists */

	if (!(error = git_repository_config__weakptr(&cfg, sm->repo)) &&
		!(error = git_buf_printf(&key, "submodule.%s.url", sm->name)))
		error = git_config__update_entry(cfg, key.ptr, sm->url, true, true);

	/* if submodule exists in the working directory, update remote url */

	if (!error &&
		(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0 &&
		!(error = git_submodule_open(&smrepo, sm)))
	{
		git_buf remote_name = GIT_BUF_INIT;

		if ((error = git_repository_config__weakptr(&cfg, smrepo)) < 0)
			/* return error from reading submodule config */;
		else if ((error = lookup_head_remote_key(&remote_name, smrepo)) < 0) {
			giterr_clear();
			error = git_buf_sets(&key, "remote.origin.url");
		} else {
			error = git_buf_join3(
				&key, '.', "remote", remote_name.ptr, "url");
			git_buf_free(&remote_name);
		}

		if (!error)
			error = git_config__update_entry(cfg, key.ptr, sm->url, true, false);

		git_repository_free(smrepo);
	}

	git_buf_free(&key);

	return error;
}

static int git_submodule__open(
	git_repository **subrepo, git_submodule *sm, bool bare)
{
	int error;
	git_buf path = GIT_BUF_INIT;
	unsigned int flags = GIT_REPOSITORY_OPEN_NO_SEARCH;
	const char *wd;

	assert(sm && subrepo);

	if (git_repository__ensure_not_bare(
			sm->repo, "open submodule repository") < 0)
		return GIT_EBAREREPO;

	wd = git_repository_workdir(sm->repo);

	if (git_buf_joinpath(&path, wd, sm->path) < 0 ||
		git_buf_joinpath(&path, path.ptr, DOT_GIT) < 0)
		return -1;

	sm->flags = sm->flags &
		~(GIT_SUBMODULE_STATUS_IN_WD |
		  GIT_SUBMODULE_STATUS__WD_OID_VALID |
		  GIT_SUBMODULE_STATUS__WD_SCANNED);

	if (bare)
		flags |= GIT_REPOSITORY_OPEN_BARE;

	error = git_repository_open_ext(subrepo, path.ptr, flags, wd);

	/* if we opened the submodule successfully, grab HEAD OID, etc. */
	if (!error) {
		sm->flags |= GIT_SUBMODULE_STATUS_IN_WD |
			GIT_SUBMODULE_STATUS__WD_SCANNED;

		if (!git_reference_name_to_id(&sm->wd_oid, *subrepo, GIT_HEAD_FILE))
			sm->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID;
		else
			giterr_clear();
	} else if (git_path_exists(path.ptr)) {
		sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED |
			GIT_SUBMODULE_STATUS_IN_WD;
	} else {
		git_buf_rtruncate_at_char(&path, '/'); /* remove "/.git" */

		if (git_path_isdir(path.ptr))
			sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;
	}

	git_buf_free(&path);

	return error;
}

int git_submodule_open_bare(git_repository **subrepo, git_submodule *sm)
{
	return git_submodule__open(subrepo, sm, true);
}

int git_submodule_open(git_repository **subrepo, git_submodule *sm)
{
	return git_submodule__open(subrepo, sm, false);
}

int git_submodule_reload_all(git_repository *repo, int force)
{
	return submodule_cache_init(repo, force ? CACHE_FLUSH : CACHE_REFRESH);
}

static void submodule_update_from_index_entry(
	git_submodule *sm, const git_index_entry *ie)
{
	bool already_found = (sm->flags & GIT_SUBMODULE_STATUS_IN_INDEX) != 0;

	if (!S_ISGITLINK(ie->mode)) {
		if (!already_found)
			sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
	} else {
		if (already_found)
			sm->flags |= GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
		else
			git_oid_cpy(&sm->index_oid, &ie->id);

		sm->flags |= GIT_SUBMODULE_STATUS_IN_INDEX |
			GIT_SUBMODULE_STATUS__INDEX_OID_VALID;
	}
}

static int submodule_update_index(git_submodule *sm)
{
	git_index *index;
	const git_index_entry *ie;

	if (git_repository_index__weakptr(&index, sm->repo) < 0)
		return -1;

	sm->flags = sm->flags &
		~(GIT_SUBMODULE_STATUS_IN_INDEX |
		  GIT_SUBMODULE_STATUS__INDEX_OID_VALID);

	if (!(ie = git_index_get_bypath(index, sm->path, 0)))
		return 0;

	submodule_update_from_index_entry(sm, ie);

	return 0;
}

static void submodule_update_from_head_data(
	git_submodule *sm, mode_t mode, const git_oid *id)
{
	if (!S_ISGITLINK(mode))
		sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
	else {
		git_oid_cpy(&sm->head_oid, id);

		sm->flags |= GIT_SUBMODULE_STATUS_IN_HEAD |
			GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
	}
}

static int submodule_update_head(git_submodule *submodule)
{
	git_tree *head = NULL;
	git_tree_entry *te = NULL;

	submodule->flags = submodule->flags &
		~(GIT_SUBMODULE_STATUS_IN_HEAD |
		  GIT_SUBMODULE_STATUS__HEAD_OID_VALID);

	/* if we can't look up file in current head, then done */
	if (git_repository_head_tree(&head, submodule->repo) < 0 ||
		git_tree_entry_bypath(&te, head, submodule->path) < 0)
		giterr_clear();
	else
		submodule_update_from_head_data(submodule, te->attr, &te->oid);

	git_tree_entry_free(te);
	git_tree_free(head);
	return 0;
}


int git_submodule_reload(git_submodule *sm, int force)
{
	int error = 0;
	git_config_backend *mods;
	git_submodule_cache *cache;

	GIT_UNUSED(force);

	assert(sm);

	cache = sm->repo->_submodules;

	/* refresh index data */
	if ((error = submodule_update_index(sm)) < 0)
		return error;

	/* refresh HEAD tree data */
	if ((error = submodule_update_head(sm)) < 0)
		return error;

	/* done if bare */
	if (git_repository_is_bare(sm->repo))
		return error;

	/* refresh config data */
	mods = open_gitmodules(cache, GITMODULES_EXISTING);
	if (mods != NULL) {
		git_buf path = GIT_BUF_INIT;

		git_buf_sets(&path, "submodule\\.");
		git_buf_text_puts_escape_regex(&path, sm->name);
		git_buf_puts(&path, ".*");

		if (git_buf_oom(&path))
			error = -1;
		else
			error = git_config_file_foreach_match(
				mods, path.ptr, submodule_load_from_config, cache);

		git_buf_free(&path);
		git_config_file_free(mods);

		if (error < 0)
			return error;
	}

	/* refresh wd data */
	sm->flags &=
		~(GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_OID_VALID |
		  GIT_SUBMODULE_STATUS__WD_FLAGS);

	return submodule_load_from_wd_lite(sm);
}

static void submodule_copy_oid_maybe(
	git_oid *tgt, const git_oid *src, bool valid)
{
	if (tgt) {
		if (valid)
			memcpy(tgt, src, sizeof(*tgt));
		else
			memset(tgt, 0, sizeof(*tgt));
	}
}

int git_submodule__status(
	unsigned int *out_status,
	git_oid *out_head_id,
	git_oid *out_index_id,
	git_oid *out_wd_id,
	git_submodule *sm,
	git_submodule_ignore_t ign)
{
	unsigned int status;
	git_repository *smrepo = NULL;

	if (ign < GIT_SUBMODULE_IGNORE_NONE)
		ign = sm->ignore;

	/* only return location info if ignore == all */
	if (ign == GIT_SUBMODULE_IGNORE_ALL) {
		*out_status = (sm->flags & GIT_SUBMODULE_STATUS__IN_FLAGS);
		return 0;
	}

	/* refresh the index OID */
	if (submodule_update_index(sm) < 0)
		return -1;

	/* refresh the HEAD OID */
	if (submodule_update_head(sm) < 0)
		return -1;

	/* for ignore == dirty, don't scan the working directory */
	if (ign == GIT_SUBMODULE_IGNORE_DIRTY) {
		/* git_submodule_open_bare will load WD OID data */
		if (git_submodule_open_bare(&smrepo, sm) < 0)
			giterr_clear();
		else
			git_repository_free(smrepo);
		smrepo = NULL;
	} else if (git_submodule_open(&smrepo, sm) < 0) {
		giterr_clear();
		smrepo = NULL;
	}

	status = GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(sm->flags);

	submodule_get_index_status(&status, sm);
	submodule_get_wd_status(&status, sm, smrepo, ign);

	git_repository_free(smrepo);

	*out_status = status;

	submodule_copy_oid_maybe(out_head_id, &sm->head_oid,
		(sm->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID) != 0);
	submodule_copy_oid_maybe(out_index_id, &sm->index_oid,
		(sm->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID) != 0);
	submodule_copy_oid_maybe(out_wd_id, &sm->wd_oid,
		(sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) != 0);

	return 0;
}

int git_submodule_status(unsigned int *status, git_submodule *sm)
{
	assert(status && sm);

	return git_submodule__status(status, NULL, NULL, NULL, sm, 0);
}

int git_submodule_location(unsigned int *location, git_submodule *sm)
{
	assert(location && sm);

	return git_submodule__status(
		location, NULL, NULL, NULL, sm, GIT_SUBMODULE_IGNORE_ALL);
}


/*
 * INTERNAL FUNCTIONS
 */

static int submodule_alloc(
	git_submodule **out, git_submodule_cache *cache, const char *name)
{
	size_t namelen;
	git_submodule *sm;

	if (!name || !(namelen = strlen(name))) {
		giterr_set(GITERR_SUBMODULE, "Invalid submodule name");
		return -1;
	}

	sm = git__calloc(1, sizeof(git_submodule));
	GITERR_CHECK_ALLOC(sm);

	sm->name = sm->path = git__strdup(name);
	if (!sm->name) {
		git__free(sm);
		return -1;
	}

	GIT_REFCOUNT_INC(sm);
	sm->ignore = sm->ignore_default = GIT_SUBMODULE_IGNORE_NONE;
	sm->update = sm->update_default = GIT_SUBMODULE_UPDATE_CHECKOUT;
	sm->fetch_recurse = sm->fetch_recurse_default = GIT_SUBMODULE_RECURSE_NO;
	sm->repo   = cache->repo;
	sm->branch = NULL;

	*out = sm;
	return 0;
}

static void submodule_cache_remove_item(
	git_submodule_cache *cache,
	git_submodule *item,
	bool free_after_remove)
{
	git_strmap *map;
	const char *name, *alt;

	if (!cache || !(map = cache->submodules) || !item)
		return;

	name = item->name;
	alt  = (item->path != item->name) ? item->path : NULL;

	for (; name; name = alt, alt = NULL) {
		khiter_t pos = git_strmap_lookup_index(map, name);
		git_submodule *found;

		if (!git_strmap_valid_index(map, pos))
			continue;

		found = git_strmap_value_at(map, pos);

		if (found != item)
			continue;

		git_strmap_set_value_at(map, pos, NULL);
		git_strmap_delete_at(map, pos);

		if (free_after_remove)
			git_submodule_free(found);
	}
}

static void submodule_release(git_submodule *sm)
{
	if (!sm)
		return;

	if (sm->repo) {
		git_submodule_cache *cache = sm->repo->_submodules;
		sm->repo = NULL;
		submodule_cache_remove_item(cache, sm, false);
	}

	if (sm->path != sm->name)
		git__free(sm->path);
	git__free(sm->name);
	git__free(sm->url);
	git__free(sm->branch);
	git__memzero(sm, sizeof(*sm));
	git__free(sm);
}

void git_submodule_free(git_submodule *sm)
{
	if (!sm)
		return;
	GIT_REFCOUNT_DEC(sm, submodule_release);
}

static int submodule_get(
	git_submodule **out,
	git_submodule_cache *cache,
	const char *name,
	const char *alternate)
{
	int error = 0;
	khiter_t pos;
	git_submodule *sm;

	pos = git_strmap_lookup_index(cache->submodules, name);

	if (!git_strmap_valid_index(cache->submodules, pos) && alternate)
		pos = git_strmap_lookup_index(cache->submodules, alternate);

	if (!git_strmap_valid_index(cache->submodules, pos)) {
		if ((error = submodule_alloc(&sm, cache, name)) < 0)
			return error;

		/* insert value at name - if another thread beats us to it, then use
		 * their record and release our own.
		 */
		pos = kh_put(str, cache->submodules, sm->name, &error);

		if (error < 0)
			goto done;
		else if (error == 0) {
			git_submodule_free(sm);
			sm = git_strmap_value_at(cache->submodules, pos);
		} else {
			error = 0;
			git_strmap_set_value_at(cache->submodules, pos, sm);
		}
	} else {
		sm = git_strmap_value_at(cache->submodules, pos);
	}

done:
	if (error < 0)
		git_submodule_free(sm);
	else if (out) {
		GIT_REFCOUNT_INC(sm);
		*out = sm;
	}

	return error;
}

static int submodule_config_error(const char *property, const char *value)
{
	giterr_set(GITERR_INVALID,
		"Invalid value for submodule '%s' property: '%s'", property, value);
	return -1;
}

int git_submodule_parse_ignore(git_submodule_ignore_t *out, const char *value)
{
	int val;

	if (git_config_lookup_map_value(
			&val, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), value) < 0) {
		*out = GIT_SUBMODULE_IGNORE_NONE;
		return submodule_config_error("ignore", value);
	}

	*out = (git_submodule_ignore_t)val;
	return 0;
}

int git_submodule_parse_update(git_submodule_update_t *out, const char *value)
{
	int val;

	if (git_config_lookup_map_value(
			&val, _sm_update_map, ARRAY_SIZE(_sm_update_map), value) < 0) {
		*out = GIT_SUBMODULE_UPDATE_CHECKOUT;
		return submodule_config_error("update", value);
	}

	*out = (git_submodule_update_t)val;
	return 0;
}

int git_submodule_parse_recurse(git_submodule_recurse_t *out, const char *value)
{
	int val;

	if (git_config_lookup_map_value(
			&val, _sm_recurse_map, ARRAY_SIZE(_sm_recurse_map), value) < 0) {
		*out = GIT_SUBMODULE_RECURSE_YES;
		return submodule_config_error("recurse", value);
	}

	*out = (git_submodule_recurse_t)val;
	return 0;
}

static int submodule_load_from_config(
	const git_config_entry *entry, void *payload)
{
	git_submodule_cache *cache = payload;
	const char *namestart, *property;
	const char *key = entry->name, *value = entry->value, *path;
	char *alternate = NULL, *replaced = NULL;
	git_buf name = GIT_BUF_INIT;
	git_submodule *sm = NULL;
	int error = 0;

	if (git__prefixcmp(key, "submodule.") != 0)
		return 0;

	namestart = key + strlen("submodule.");
	property  = strrchr(namestart, '.');

	if (!property || (property == namestart))
		return 0;

	property++;
	path = !strcasecmp(property, "path") ? value : NULL;

	if ((error = git_buf_set(&name, namestart, property - namestart - 1)) < 0 ||
		(error = submodule_get(&sm, cache, name.ptr, path)) < 0)
		goto done;

	sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;

	/* Only from config might we get differing names & paths.  If so, then
	 * update the submodule and insert under the alternative key.
	 */

	/* TODO: if case insensitive filesystem, then the following strcmps
	 * should be strcasecmp
	 */

	if (strcmp(sm->name, name.ptr) != 0) { /* name changed */
		if (!strcmp(sm->path, name.ptr)) { /* already set as path */
			replaced = sm->name;
			sm->name = sm->path;
		} else {
			if (sm->name != sm->path)
				replaced = sm->name;
			alternate = sm->name = git_buf_detach(&name);
		}
	}
	else if (path && strcmp(path, sm->path) != 0) { /* path changed */
		if (!strcmp(sm->name, value)) { /* already set as name */
			replaced = sm->path;
			sm->path = sm->name;
		} else {
			if (sm->path != sm->name)
				replaced = sm->path;
			if ((alternate = git__strdup(value)) == NULL) {
				error = -1;
				goto done;
			}
			sm->path = alternate;
		}
	}

	/* Deregister under name being replaced */
	if (replaced) {
		git_strmap_delete(cache->submodules, replaced);
		git_submodule_free(sm);
		git__free(replaced);
	}

	/* Insert under alternate key */
	if (alternate) {
		void *old_sm = NULL;
		git_strmap_insert2(cache->submodules, alternate, sm, old_sm, error);

		if (error < 0)
			goto done;
		if (error > 0)
			error = 0;

		GIT_REFCOUNT_INC(sm); /* increase refcount for new key */

		/* if we replaced an old module under this key, release the old one */
		if (old_sm && ((git_submodule *)old_sm) != sm) {
			git_submodule_free(old_sm);
			/* TODO: log warning about multiple submodules with same path */
		}
	}

	/* TODO: Look up path in index and if it is present but not a GITLINK
	 * then this should be deleted (at least to match git's behavior)
	 */

	if (path)
		goto done;

	/* copy other properties into submodule entry */
	if (strcasecmp(property, "url") == 0) {
		git__free(sm->url);
		sm->url = NULL;

		if (value != NULL && (sm->url = git__strdup(value)) == NULL) {
			error = -1;
			goto done;
		}
	}
	else if (strcasecmp(property, "branch") == 0) {
		git__free(sm->branch);
		sm->branch = NULL;

		if (value != NULL && (sm->branch = git__strdup(value)) == NULL) {
			error = -1;
			goto done;
		}
	}
	else if (strcasecmp(property, "update") == 0) {
		if ((error = git_submodule_parse_update(&sm->update, value)) < 0)
			goto done;
		sm->update_default = sm->update;
	}
	else if (strcasecmp(property, "fetchRecurseSubmodules") == 0) {
		if ((error = git_submodule_parse_recurse(&sm->fetch_recurse, value)) < 0)
			goto done;
		sm->fetch_recurse_default = sm->fetch_recurse;
	}
	else if (strcasecmp(property, "ignore") == 0) {
		if ((error = git_submodule_parse_ignore(&sm->ignore, value)) < 0)
			goto done;
		sm->ignore_default = sm->ignore;
	}
	/* ignore other unknown submodule properties */

done:
	git_submodule_free(sm); /* offset refcount inc from submodule_get() */
	git_buf_free(&name);
	return error;
}

static int submodule_load_from_wd_lite(git_submodule *sm)
{
	git_buf path = GIT_BUF_INIT;

	if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0)
		return -1;

	if (git_path_isdir(path.ptr))
		sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;

	if (git_path_contains(&path, DOT_GIT))
		sm->flags |= GIT_SUBMODULE_STATUS_IN_WD;

	git_buf_free(&path);
	return 0;
}

static int submodule_cache_refresh_from_index(
	git_submodule_cache *cache, git_index *idx)
{
	int error;
	git_iterator *i;
	const git_index_entry *entry;

	if ((error = git_iterator_for_index(&i, idx, 0, NULL, NULL)) < 0)
		return error;

	while (!(error = git_iterator_advance(&entry, i))) {
		khiter_t pos = git_strmap_lookup_index(cache->submodules, entry->path);
		git_submodule *sm;

		if (git_strmap_valid_index(cache->submodules, pos)) {
			sm = git_strmap_value_at(cache->submodules, pos);

			if (S_ISGITLINK(entry->mode))
				submodule_update_from_index_entry(sm, entry);
			else
				sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
		} else if (S_ISGITLINK(entry->mode)) {
			if (!submodule_get(&sm, cache, entry->path, NULL)) {
				submodule_update_from_index_entry(sm, entry);
				git_submodule_free(sm);
			}
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_iterator_free(i);

	return error;
}

static int submodule_cache_refresh_from_head(
	git_submodule_cache *cache, git_tree *head)
{
	int error;
	git_iterator *i;
	const git_index_entry *entry;

	if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0)
		return error;

	while (!(error = git_iterator_advance(&entry, i))) {
		khiter_t pos = git_strmap_lookup_index(cache->submodules, entry->path);
		git_submodule *sm;

		if (git_strmap_valid_index(cache->submodules, pos)) {
			sm = git_strmap_value_at(cache->submodules, pos);

			if (S_ISGITLINK(entry->mode))
				submodule_update_from_head_data(sm, entry->mode, &entry->id);
			else
				sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
		} else if (S_ISGITLINK(entry->mode)) {
			if (!submodule_get(&sm, cache, entry->path, NULL)) {
				submodule_update_from_head_data(
					sm, entry->mode, &entry->id);
				git_submodule_free(sm);
			}
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_iterator_free(i);

	return error;
}

static git_config_backend *open_gitmodules(
	git_submodule_cache *cache,
	int okay_to_create)
{
	const char *workdir = git_repository_workdir(cache->repo);
	git_buf path = GIT_BUF_INIT;
	git_config_backend *mods = NULL;

	if (workdir != NULL) {
		if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0)
			return NULL;

		if (okay_to_create || git_path_isfile(path.ptr)) {
			/* git_config_file__ondisk should only fail if OOM */
			if (git_config_file__ondisk(&mods, path.ptr) < 0)
				mods = NULL;
			/* open should only fail here if the file is malformed */
			else if (git_config_file_open(mods, GIT_CONFIG_LEVEL_LOCAL) < 0) {
				git_config_file_free(mods);
				mods = NULL;
			}
		}
	}

	git_buf_free(&path);

	return mods;
}

static void submodule_cache_free(git_submodule_cache *cache)
{
	git_submodule *sm;

	if (!cache)
		return;

	git_strmap_foreach_value(cache->submodules, sm, {
		sm->repo = NULL; /* disconnect from repo */
		git_submodule_free(sm);
	});
	git_strmap_free(cache->submodules);

	git_buf_free(&cache->gitmodules_path);
	git_mutex_free(&cache->lock);
	git__free(cache);
}

static int submodule_cache_alloc(
	git_submodule_cache **out, git_repository *repo)
{
	git_submodule_cache *cache = git__calloc(1, sizeof(git_submodule_cache));
	GITERR_CHECK_ALLOC(cache);

	if (git_mutex_init(&cache->lock) < 0) {
		giterr_set(GITERR_OS, "Unable to initialize submodule cache lock");
		git__free(cache);
		return -1;
	}

	if (git_strmap_alloc(&cache->submodules) < 0) {
		submodule_cache_free(cache);
		return -1;
	}

	cache->repo = repo;
	git_buf_init(&cache->gitmodules_path, 0);

	*out = cache;
	return 0;
}

static int submodule_cache_refresh(git_submodule_cache *cache, int refresh)
{
	int error = 0, update_index, update_head, update_gitmod;
	git_index *idx = NULL;
	git_tree *head = NULL;
	const char *wd = NULL;
	git_buf path = GIT_BUF_INIT;
	git_submodule *sm;
	git_config_backend *mods = NULL;
	uint32_t mask;

	if (!cache || !cache->repo || !refresh)
		return 0;

	if (git_mutex_lock(&cache->lock) < 0) {
		giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
		return -1;
	}

	/* get sources that we will need to check */

	if (git_repository_index(&idx, cache->repo) < 0)
		giterr_clear();
	if (git_repository_head_tree(&head, cache->repo) < 0)
		giterr_clear();

	wd = git_repository_workdir(cache->repo);
	if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0)
		goto cleanup;

	/* check for invalidation */

	if (refresh == CACHE_FLUSH)
		update_index = update_head = update_gitmod = true;
	else {
		update_index =
			!idx || git_index__changed_relative_to(idx, &cache->index_stamp);
		update_head =
			!head || !git_oid_equal(&cache->head_id, git_tree_id(head));

		update_gitmod = (wd != NULL) ?
			git_futils_filestamp_check(&cache->gitmodules_stamp, path.ptr) :
			(cache->gitmodules_stamp.mtime != 0);
	}

	/* clear submodule flags that are to be refreshed */

	mask = 0;
	if (!idx || update_index)
		mask |= GIT_SUBMODULE_STATUS_IN_INDEX |
			GIT_SUBMODULE_STATUS__INDEX_FLAGS |
			GIT_SUBMODULE_STATUS__INDEX_OID_VALID |
			GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
	if (!head || update_head)
		mask |= GIT_SUBMODULE_STATUS_IN_HEAD |
			GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
	if (update_gitmod)
		mask |= GIT_SUBMODULE_STATUS_IN_CONFIG;
	if (mask != 0)
		mask |= GIT_SUBMODULE_STATUS_IN_WD |
			GIT_SUBMODULE_STATUS__WD_SCANNED |
			GIT_SUBMODULE_STATUS__WD_FLAGS |
			GIT_SUBMODULE_STATUS__WD_OID_VALID;
	else
		goto cleanup; /* nothing to do */

	submodule_cache_clear_flags(cache, mask);

	/* add back submodule information from index */

	if (idx && update_index) {
		if ((error = submodule_cache_refresh_from_index(cache, idx)) < 0)
			goto cleanup;

		git_futils_filestamp_set(
			&cache->index_stamp, git_index__filestamp(idx));
	}

	/* add submodule information from HEAD */

	if (head && update_head) {
		if ((error = submodule_cache_refresh_from_head(cache, head)) < 0)
			goto cleanup;

		git_oid_cpy(&cache->head_id, git_tree_id(head));
	}

	/* add submodule information from .gitmodules */

	if (wd && update_gitmod > 0) {
		if ((mods = open_gitmodules(cache, false)) != NULL &&
			(error = git_config_file_foreach(
				mods, submodule_load_from_config, cache)) < 0)
			goto cleanup;
	}

	/* shallow scan submodules in work tree as needed */

	if (wd && mask != 0) {
		git_strmap_foreach_value(cache->submodules, sm, {
			submodule_load_from_wd_lite(sm);
		});
	}

	/* remove submodules that no longer exist */

	git_strmap_foreach_value(cache->submodules, sm, {
		/* purge unless in HEAD, index, or .gitmodules; no sm for wd only */
		if (sm != NULL &&
			!(sm->flags &
			 (GIT_SUBMODULE_STATUS_IN_HEAD |
			  GIT_SUBMODULE_STATUS_IN_INDEX |
			  GIT_SUBMODULE_STATUS_IN_CONFIG)))
			submodule_cache_remove_item(cache, sm, true);
	});

cleanup:
	git_config_file_free(mods);

	/* TODO: if we got an error, mark submodule config as invalid? */

	git_mutex_unlock(&cache->lock);

	git_index_free(idx);
	git_tree_free(head);
	git_buf_free(&path);

	return error;
}

static int submodule_cache_init(git_repository *repo, int cache_refresh)
{
	int error = 0;
	git_submodule_cache *cache = NULL;

	/* if submodules already exist, just refresh as requested */
	if (repo->_submodules)
		return submodule_cache_refresh(repo->_submodules, cache_refresh);

	/* otherwise create a new cache, load it, and atomically swap it in */
	if (!(error = submodule_cache_alloc(&cache, repo)) &&
		!(error = submodule_cache_refresh(cache, CACHE_FLUSH)))
		cache = git__compare_and_swap(&repo->_submodules, NULL, cache);

	/* might have raced with another thread to set cache, so free if needed */
	if (cache)
		submodule_cache_free(cache);

	return error;
}

/* Lookup name of remote of the local tracking branch HEAD points to */
static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo)
{
	int error;
	git_reference *head = NULL;
	git_buf upstream_name = GIT_BUF_INIT;

	/* lookup and dereference HEAD */
	if ((error = git_repository_head(&head, repo)) < 0)
		return error;

	/**
	 * If head does not refer to a branch, then return
	 * GIT_ENOTFOUND to indicate that we could not find
	 * a remote key for the local tracking branch HEAD points to.
	 **/
	if (!git_reference_is_branch(head)) {
		giterr_set(GITERR_INVALID,
			"HEAD does not refer to a branch.");
		error = GIT_ENOTFOUND;
		goto done;
	}

	/* lookup remote tracking branch of HEAD */
	if ((error = git_branch_upstream_name(
		&upstream_name,
		repo,
		git_reference_name(head))) < 0)
		goto done;

	/* lookup remote of remote tracking branch */
	if ((error = git_branch_remote_name(remote_name, repo, upstream_name.ptr)) < 0)
		goto done;

done:
	git_buf_free(&upstream_name);
	git_reference_free(head);

	return error;
}

/* Lookup the remote of the local tracking branch HEAD points to */
static int lookup_head_remote(git_remote **remote, git_repository *repo)
{
	int error;
	git_buf remote_name = GIT_BUF_INIT;

	/* lookup remote of remote tracking branch name */
	if (!(error = lookup_head_remote_key(&remote_name, repo)))
		error = git_remote_lookup(remote, repo, remote_name.ptr);

	git_buf_free(&remote_name);

	return error;
}

/* Lookup remote, either from HEAD or fall back on origin */
static int lookup_default_remote(git_remote **remote, git_repository *repo)
{
	int error = lookup_head_remote(remote, repo);

	/* if that failed, use 'origin' instead */
	if (error == GIT_ENOTFOUND)
		error = git_remote_lookup(remote, repo, "origin");

	if (error == GIT_ENOTFOUND)
		giterr_set(
			GITERR_SUBMODULE,
			"Cannot get default remote for submodule - no local tracking "
			"branch for HEAD and origin does not exist");

	return error;
}

static int get_url_base(git_buf *url, git_repository *repo)
{
	int error;
	git_remote *remote = NULL;

	if (!(error = lookup_default_remote(&remote, repo))) {
		error = git_buf_sets(url, git_remote_url(remote));
		git_remote_free(remote);
	}
	else if (error == GIT_ENOTFOUND) {
		/* if repository does not have a default remote, use workdir instead */
		giterr_clear();
		error = git_buf_sets(url, git_repository_workdir(repo));
	}

	return error;
}

static void submodule_get_index_status(unsigned int *status, git_submodule *sm)
{
	const git_oid *head_oid  = git_submodule_head_id(sm);
	const git_oid *index_oid = git_submodule_index_id(sm);

	*status = *status & ~GIT_SUBMODULE_STATUS__INDEX_FLAGS;

	if (!head_oid) {
		if (index_oid)
			*status |= GIT_SUBMODULE_STATUS_INDEX_ADDED;
	}
	else if (!index_oid)
		*status |= GIT_SUBMODULE_STATUS_INDEX_DELETED;
	else if (!git_oid_equal(head_oid, index_oid))
		*status |= GIT_SUBMODULE_STATUS_INDEX_MODIFIED;
}


static void submodule_get_wd_status(
	unsigned int *status,
	git_submodule *sm,
	git_repository *sm_repo,
	git_submodule_ignore_t ign)
{
	const git_oid *index_oid = git_submodule_index_id(sm);
	const git_oid *wd_oid =
		(sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) ? &sm->wd_oid : NULL;
	git_tree *sm_head = NULL;
	git_index *index = NULL;
	git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
	git_diff *diff;

	*status = *status & ~GIT_SUBMODULE_STATUS__WD_FLAGS;

	if (!index_oid) {
		if (wd_oid)
			*status |= GIT_SUBMODULE_STATUS_WD_ADDED;
	}
	else if (!wd_oid) {
		if ((sm->flags & GIT_SUBMODULE_STATUS__WD_SCANNED) != 0 &&
			(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) == 0)
			*status |= GIT_SUBMODULE_STATUS_WD_UNINITIALIZED;
		else
			*status |= GIT_SUBMODULE_STATUS_WD_DELETED;
	}
	else if (!git_oid_equal(index_oid, wd_oid))
		*status |= GIT_SUBMODULE_STATUS_WD_MODIFIED;

	/* if we have no repo, then we're done */
	if (!sm_repo)
		return;

	/* the diffs below could be optimized with an early termination
	 * option to the git_diff functions, but for now this is sufficient
	 * (and certainly no worse that what core git does).
	 */

	if (ign == GIT_SUBMODULE_IGNORE_NONE)
		opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;

	(void)git_repository_index__weakptr(&index, sm_repo);

	/* if we don't have an unborn head, check diff with index */
	if (git_repository_head_tree(&sm_head, sm_repo) < 0)
		giterr_clear();
	else {
		/* perform head to index diff on submodule */
		if (git_diff_tree_to_index(&diff, sm_repo, sm_head, index, &opt) < 0)
			giterr_clear();
		else {
			if (git_diff_num_deltas(diff) > 0)
				*status |= GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED;
			git_diff_free(diff);
			diff = NULL;
		}

		git_tree_free(sm_head);
	}

	/* perform index-to-workdir diff on submodule */
	if (git_diff_index_to_workdir(&diff, sm_repo, index, &opt) < 0)
		giterr_clear();
	else {
		size_t untracked =
			git_diff_num_deltas_of_type(diff, GIT_DELTA_UNTRACKED);

		if (untracked > 0)
			*status |= GIT_SUBMODULE_STATUS_WD_UNTRACKED;

		if (git_diff_num_deltas(diff) != untracked)
			*status |= GIT_SUBMODULE_STATUS_WD_WD_MODIFIED;

		git_diff_free(diff);
		diff = NULL;
	}
}
