/*
 * 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.
 */
#ifndef INCLUDE_git_repository_h__
#define INCLUDE_git_repository_h__

#include "common.h"
#include "types.h"
#include "oid.h"
#include "buffer.h"

/**
 * @file git2/repository.h
 * @brief Git repository management routines
 * @defgroup git_repository Git repository management routines
 * @ingroup Git
 * @{
 */
GIT_BEGIN_DECL

/**
 * Open a git repository.
 *
 * The 'path' argument must point to either a git repository
 * folder, or an existing work dir.
 *
 * The method will automatically detect if 'path' is a normal
 * or bare repository or fail is 'path' is neither.
 *
 * @param out pointer to the repo which will be opened
 * @param path the path to the repository
 * @return 0 or an error code
 */
GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
/**
 * Open working tree as a repository
 *
 * Open the working directory of the working tree as a normal
 * repository that can then be worked on.
 *
 * @param out Output pointer containing opened repository
 * @param wt Working tree to open
 * @return 0 or an error code
 */
GIT_EXTERN(int) git_repository_open_from_worktree(git_repository **out, git_worktree *wt);

/**
 * Create a "fake" repository to wrap an object database
 *
 * Create a repository object to wrap an object database to be used
 * with the API when all you have is an object database. This doesn't
 * have any paths associated with it, so use with care.
 *
 * @param out pointer to the repo
 * @param odb the object database to wrap
 * @return 0 or an error code
 */
GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);

/**
 * Look for a git repository and copy its path in the given buffer.
 * The lookup start from base_path and walk across parent directories
 * if nothing has been found. The lookup ends when the first repository
 * is found, or when reaching a directory referenced in ceiling_dirs
 * or when the filesystem changes (in case across_fs is true).
 *
 * The method will automatically detect if the repository is bare
 * (if there is a repository).
 *
 * @param out A pointer to a user-allocated git_buf which will contain
 * the found path.
 *
 * @param start_path The base path where the lookup starts.
 *
 * @param across_fs If true, then the lookup will not stop when a
 * filesystem device change is detected while exploring parent directories.
 *
 * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR separated list of
 * absolute symbolic link free paths. The lookup will stop when any
 * of this paths is reached. Note that the lookup always performs on
 * start_path no matter start_path appears in ceiling_dirs ceiling_dirs
 * might be NULL (which is equivalent to an empty string)
 *
 * @return 0 or an error code
 */
GIT_EXTERN(int) git_repository_discover(
		git_buf *out,
		const char *start_path,
		int across_fs,
		const char *ceiling_dirs);

/**
 * Option flags for `git_repository_open_ext`.
 *
 * * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be
 *   immediately found in the start_path.  Do not walk up from the
 *   start_path looking at parent directories.
 * * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not
 *   continue searching across filesystem boundaries (i.e. when `st_dev`
 *   changes from the `stat` system call).  (E.g. Searching in a user's home
 *   directory "/home/user/source/" will not return "/.git/" as the found
 *   repo if "/" is a different filesystem than "/home".)
 * * GIT_REPOSITORY_OPEN_BARE - Open repository as a bare repo regardless
 *   of core.bare config, and defer loading config file for faster setup.
 *   Unlike `git_repository_open_bare`, this can follow gitlinks.
 * * GIT_REPOSITORY_OPEN_NO_DOTGIT - Do not check for a repository by
 *   appending /.git to the start_path; only open the repository if
 *   start_path itself points to the git directory.
 * * GIT_REPOSITORY_OPEN_FROM_ENV - Find and open a git repository,
 *   respecting the environment variables used by the git command-line
 *   tools. If set, `git_repository_open_ext` will ignore the other
 *   flags and the `ceiling_dirs` argument, and will allow a NULL `path`
 *   to use `GIT_DIR` or search from the current directory. The search
 *   for a repository will respect $GIT_CEILING_DIRECTORIES and
 *   $GIT_DISCOVERY_ACROSS_FILESYSTEM.  The opened repository will
 *   respect $GIT_INDEX_FILE, $GIT_NAMESPACE, $GIT_OBJECT_DIRECTORY, and
 *   $GIT_ALTERNATE_OBJECT_DIRECTORIES.  In the future, this flag will
 *   also cause `git_repository_open_ext` to respect $GIT_WORK_TREE and
 *   $GIT_COMMON_DIR; currently, `git_repository_open_ext` with this
 *   flag will error out if either $GIT_WORK_TREE or $GIT_COMMON_DIR is
 *   set.
 */
typedef enum {
	GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
	GIT_REPOSITORY_OPEN_CROSS_FS  = (1 << 1),
	GIT_REPOSITORY_OPEN_BARE      = (1 << 2),
	GIT_REPOSITORY_OPEN_NO_DOTGIT = (1 << 3),
	GIT_REPOSITORY_OPEN_FROM_ENV  = (1 << 4),
} git_repository_open_flag_t;

/**
 * Find and open a repository with extended controls.
 *
 * @param out Pointer to the repo which will be opened.  This can
 *        actually be NULL if you only want to use the error code to
 *        see if a repo at this path could be opened.
 * @param path Path to open as git repository.  If the flags
 *        permit "searching", then this can be a path to a subdirectory
 *        inside the working directory of the repository. May be NULL if
 *        flags is GIT_REPOSITORY_OPEN_FROM_ENV.
 * @param flags A combination of the GIT_REPOSITORY_OPEN flags above.
 * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR delimited list of path
 *        prefixes at which the search for a containing repository should
 *        terminate.
 * @return 0 on success, GIT_ENOTFOUND if no repository could be found,
 *        or -1 if there was a repository but open failed for some reason
 *        (such as repo corruption or system errors).
 */
GIT_EXTERN(int) git_repository_open_ext(
	git_repository **out,
	const char *path,
	unsigned int flags,
	const char *ceiling_dirs);

/**
 * Open a bare repository on the serverside.
 *
 * This is a fast open for bare repositories that will come in handy
 * if you're e.g. hosting git repositories and need to access them
 * efficiently
 *
 * @param out Pointer to the repo which will be opened.
 * @param bare_path Direct path to the bare repository
 * @return 0 on success, or an error code
 */
GIT_EXTERN(int) git_repository_open_bare(git_repository **out, const char *bare_path);

/**
 * Free a previously allocated repository
 *
 * Note that after a repository is free'd, all the objects it has spawned
 * will still exist until they are manually closed by the user
 * with `git_object_free`, but accessing any of the attributes of
 * an object without a backing repository will result in undefined
 * behavior
 *
 * @param repo repository handle to close. If NULL nothing occurs.
 */
GIT_EXTERN(void) git_repository_free(git_repository *repo);

/**
 * Creates a new Git repository in the given folder.
 *
 * TODO:
 *	- Reinit the repository
 *
 * @param out pointer to the repo which will be created or reinitialized
 * @param path the path to the repository
 * @param is_bare if true, a Git repository without a working directory is
 *		created at the pointed path. If false, provided path will be
 *		considered as the working directory into which the .git directory
 *		will be created.
 *
 * @return 0 or an error code
 */
GIT_EXTERN(int) git_repository_init(
	git_repository **out,
	const char *path,
	unsigned is_bare);

/**
 * Option flags for `git_repository_init_ext`.
 *
 * These flags configure extra behaviors to `git_repository_init_ext`.
 * In every case, the default behavior is the zero value (i.e. flag is
 * not set).  Just OR the flag values together for the `flags` parameter
 * when initializing a new repo.  Details of individual values are:
 *
 * * BARE   - Create a bare repository with no working directory.
 * * NO_REINIT - Return an GIT_EEXISTS error if the repo_path appears to
 *        already be an git repository.
 * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo
 *        path for non-bare repos (if it is not already there), but
 *        passing this flag prevents that behavior.
 * * MKDIR  - Make the repo_path (and workdir_path) as needed.  Init is
 *        always willing to create the ".git" directory even without this
 *        flag.  This flag tells init to create the trailing component of
 *        the repo and workdir paths as needed.
 * * MKPATH - Recursively make all components of the repo and workdir
 *        paths as necessary.
 * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to
 *        initialize a new repo.  This flags enables external templates,
 *        looking the "template_path" from the options if set, or the
 *        `init.templatedir` global config if not, or falling back on
 *        "/usr/share/git-core/templates" if it exists.
 * * GIT_REPOSITORY_INIT_RELATIVE_GITLINK - If an alternate workdir is
 *        specified, use relative paths for the gitdir and core.worktree.
 */
typedef enum {
	GIT_REPOSITORY_INIT_BARE              = (1u << 0),
	GIT_REPOSITORY_INIT_NO_REINIT         = (1u << 1),
	GIT_REPOSITORY_INIT_NO_DOTGIT_DIR     = (1u << 2),
	GIT_REPOSITORY_INIT_MKDIR             = (1u << 3),
	GIT_REPOSITORY_INIT_MKPATH            = (1u << 4),
	GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5),
	GIT_REPOSITORY_INIT_RELATIVE_GITLINK  = (1u << 6),
} git_repository_init_flag_t;

/**
 * Mode options for `git_repository_init_ext`.
 *
 * Set the mode field of the `git_repository_init_options` structure
 * either to the custom mode that you would like, or to one of the
 * following modes:
 *
 * * SHARED_UMASK - Use permissions configured by umask - the default.
 * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo
 *        to be group writable and "g+sx" for sticky group assignment.
 * * SHARED_ALL - Use "--shared=all" behavior, adding world readability.
 * * Anything else - Set to custom value.
 */
typedef enum {
	GIT_REPOSITORY_INIT_SHARED_UMASK = 0,
	GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775,
	GIT_REPOSITORY_INIT_SHARED_ALL   = 0002777,
} git_repository_init_mode_t;

/**
 * Extended options structure for `git_repository_init_ext`.
 *
 * This contains extra options for `git_repository_init_ext` that enable
 * additional initialization features.  The fields are:
 *
 * * flags - Combination of GIT_REPOSITORY_INIT flags above.
 * * mode  - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...
 *        constants above, or to a custom value that you would like.
 * * workdir_path - The path to the working dir or NULL for default (i.e.
 *        repo_path parent on non-bare repos).  IF THIS IS RELATIVE PATH,
 *        IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH.  If this is not
 *        the "natural" working directory, a .git gitlink file will be
 *        created here linking to the repo_path.
 * * description - If set, this will be used to initialize the "description"
 *        file in the repository, instead of using the template content.
 * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,
 *        this contains the path to use for the template directory.  If
 *        this is NULL, the config or default directory options will be
 *        used instead.
 * * initial_head - The name of the head to point HEAD at.  If NULL, then
 *        this will be treated as "master" and the HEAD ref will be set
 *        to "refs/heads/master".  If this begins with "refs/" it will be
 *        used verbatim; otherwise "refs/heads/" will be prefixed.
 * * origin_url - If this is non-NULL, then after the rest of the
 *        repository initialization is completed, an "origin" remote
 *        will be added pointing to this URL.
 */
typedef struct {
	unsigned int version;
	uint32_t    flags;
	uint32_t    mode;
	const char *workdir_path;
	const char *description;
	const char *template_path;
	const char *initial_head;
	const char *origin_url;
} git_repository_init_options;

#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1
#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}

/**
 * Initializes a `git_repository_init_options` with default values. Equivalent
 * to creating an instance with GIT_REPOSITORY_INIT_OPTIONS_INIT.
 *
 * @param opts the `git_repository_init_options` struct to initialize
 * @param version Version of struct; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`
 * @return Zero on success; -1 on failure.
 */
GIT_EXTERN(int) git_repository_init_init_options(
	git_repository_init_options *opts,
	unsigned int version);

/**
 * Create a new Git repository in the given folder with extended controls.
 *
 * This will initialize a new git repository (creating the repo_path
 * if requested by flags) and working directory as needed.  It will
 * auto-detect the case sensitivity of the file system and if the
 * file system supports file mode bits correctly.
 *
 * @param out Pointer to the repo which will be created or reinitialized.
 * @param repo_path The path to the repository.
 * @param opts Pointer to git_repository_init_options struct.
 * @return 0 or an error code on failure.
 */
GIT_EXTERN(int) git_repository_init_ext(
	git_repository **out,
	const char *repo_path,
	git_repository_init_options *opts);

/**
 * Retrieve and resolve the reference pointed at by HEAD.
 *
 * The returned `git_reference` will be owned by caller and
 * `git_reference_free()` must be called when done with it to release the
 * allocated memory and prevent a leak.
 *
 * @param out pointer to the reference which will be retrieved
 * @param repo a repository object
 *
 * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
 * branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise
 */
GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);

/**
 * Retrieve the referenced HEAD for the worktree
 *
 * @param out pointer to the reference which will be retrieved
 * @param repo a repository object
 * @param name name of the worktree to retrieve HEAD for
 * @return 0 when successful, error-code otherwise
 */
GIT_EXTERN(int) git_repository_head_for_worktree(git_reference **out, git_repository *repo,
	const char *name);

/**
 * Check if a repository's HEAD is detached
 *
 * A repository's HEAD is detached when it points directly to a commit
 * instead of a branch.
 *
 * @param repo Repo to test
 * @return 1 if HEAD is detached, 0 if it's not; error code if there
 * was an error.
 */
GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);

/*
 * Check if a worktree's HEAD is detached
 *
 * A worktree's HEAD is detached when it points directly to a
 * commit instead of a branch.
 *
 * @param repo a repository object
 * @param name name of the worktree to retrieve HEAD for
 * @return 1 if HEAD is detached, 0 if its not; error code if
 *  there was an error
 */
GIT_EXTERN(int) git_repository_head_detached_for_worktree(git_repository *repo,
	const char *name);

/**
 * Check if the current branch is unborn
 *
 * An unborn branch is one named from HEAD but which doesn't exist in
 * the refs namespace, because it doesn't have any commit to point to.
 *
 * @param repo Repo to test
 * @return 1 if the current branch is unborn, 0 if it's not; error
 * code if there was an error
 */
GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);

/**
 * Check if a repository is empty
 *
 * An empty repository has just been initialized and contains no references
 * apart from HEAD, which must be pointing to the unborn master branch.
 *
 * @param repo Repo to test
 * @return 1 if the repository is empty, 0 if it isn't, error code
 * if the repository is corrupted
 */
GIT_EXTERN(int) git_repository_is_empty(git_repository *repo);

/**
 * List of items which belong to the git repository layout
 */
typedef enum {
	GIT_REPOSITORY_ITEM_GITDIR,
	GIT_REPOSITORY_ITEM_WORKDIR,
	GIT_REPOSITORY_ITEM_COMMONDIR,
	GIT_REPOSITORY_ITEM_INDEX,
	GIT_REPOSITORY_ITEM_OBJECTS,
	GIT_REPOSITORY_ITEM_REFS,
	GIT_REPOSITORY_ITEM_PACKED_REFS,
	GIT_REPOSITORY_ITEM_REMOTES,
	GIT_REPOSITORY_ITEM_CONFIG,
	GIT_REPOSITORY_ITEM_INFO,
	GIT_REPOSITORY_ITEM_HOOKS,
	GIT_REPOSITORY_ITEM_LOGS,
	GIT_REPOSITORY_ITEM_MODULES,
	GIT_REPOSITORY_ITEM_WORKTREES
} git_repository_item_t;

/**
 * Get the location of a specific repository file or directory
 *
 * This function will retrieve the path of a specific repository
 * item. It will thereby honor things like the repository's
 * common directory, gitdir, etc. In case a file path cannot
 * exist for a given item (e.g. the working directory of a bare
 * repository), an error is returned.
 *
 * @param out Buffer to store the path at
 * @param repo Repository to get path for
 * @param item The repository item for which to retrieve the path
 * @return 0 on success, otherwise a negative value
 */
GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item);

/**
 * Get the path of this repository
 *
 * This is the path of the `.git` folder for normal repositories,
 * or of the repository itself for bare repositories.
 *
 * @param repo A repository object
 * @return the path to the repository
 */
GIT_EXTERN(const char *) git_repository_path(git_repository *repo);

/**
 * Get the path of the working directory for this repository
 *
 * If the repository is bare, this function will always return
 * NULL.
 *
 * @param repo A repository object
 * @return the path to the working dir, if it exists
 */
GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);

/**
 * Get the path of the shared common directory for this repository
 *
 * If the repository is bare is not a worktree, the git directory
 * path is returned.
 *
 * @param repo A repository object
 * @return the path to the common dir
 */
GIT_EXTERN(const char *) git_repository_commondir(git_repository *repo);

/**
 * Set the path to the working directory for this repository
 *
 * The working directory doesn't need to be the same one
 * that contains the `.git` folder for this repository.
 *
 * If this repository is bare, setting its working directory
 * will turn it into a normal repository, capable of performing
 * all the common workdir operations (checkout, status, index
 * manipulation, etc).
 *
 * @param repo A repository object
 * @param workdir The path to a working directory
 * @param update_gitlink Create/update gitlink in workdir and set config
 *        "core.worktree" (if workdir is not the parent of the .git directory)
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_set_workdir(
	git_repository *repo, const char *workdir, int update_gitlink);

/**
 * Check if a repository is bare
 *
 * @param repo Repo to test
 * @return 1 if the repository is bare, 0 otherwise.
 */
GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);

/**
 * Check if a repository is a linked work tree
 *
 * @param repo Repo to test
 * @return 1 if the repository is a linked work tree, 0 otherwise.
 */
GIT_EXTERN(int) git_repository_is_worktree(git_repository *repo);

/**
 * Get the configuration file for this repository.
 *
 * If a configuration file has not been set, the default
 * config set for the repository will be returned, including
 * global and system configurations (if they are available).
 *
 * The configuration file must be freed once it's no longer
 * being used by the user.
 *
 * @param out Pointer to store the loaded configuration
 * @param repo A repository object
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);

/**
 * Get a snapshot of the repository's configuration
 *
 * Convenience function to take a snapshot from the repository's
 * configuration.  The contents of this snapshot will not change,
 * even if the underlying config files are modified.
 *
 * The configuration file must be freed once it's no longer
 * being used by the user.
 *
 * @param out Pointer to store the loaded configuration
 * @param repo the repository
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_config_snapshot(git_config **out, git_repository *repo);

/**
 * Get the Object Database for this repository.
 *
 * If a custom ODB has not been set, the default
 * database for the repository will be returned (the one
 * located in `.git/objects`).
 *
 * The ODB must be freed once it's no longer being used by
 * the user.
 *
 * @param out Pointer to store the loaded ODB
 * @param repo A repository object
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);

/**
 * Get the Reference Database Backend for this repository.
 *
 * If a custom refsdb has not been set, the default database for
 * the repository will be returned (the one that manipulates loose
 * and packed references in the `.git` directory).
 *
 * The refdb must be freed once it's no longer being used by
 * the user.
 *
 * @param out Pointer to store the loaded refdb
 * @param repo A repository object
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo);

/**
 * Get the Index file for this repository.
 *
 * If a custom index has not been set, the default
 * index for the repository will be returned (the one
 * located in `.git/index`).
 *
 * The index must be freed once it's no longer being used by
 * the user.
 *
 * @param out Pointer to store the loaded index
 * @param repo A repository object
 * @return 0, or an error code
 */
GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);

/**
 * Retrieve git's prepared message
 *
 * Operations such as git revert/cherry-pick/merge with the -n option
 * stop just short of creating a commit with the changes and save
 * their prepared message in .git/MERGE_MSG so the next git-commit
 * execution can present it to the user for them to amend if they
 * wish.
 *
 * Use this function to get the contents of this file. Don't forget to
 * remove the file after you create the commit.
 *
 * @param out git_buf to write data into
 * @param repo Repository to read prepared message from
 * @return 0, GIT_ENOTFOUND if no message exists or an error code
 */
GIT_EXTERN(int) git_repository_message(git_buf *out, git_repository *repo);

/**
 * Remove git's prepared message.
 *
 * Remove the message that `git_repository_message` retrieves.
 */
GIT_EXTERN(int) git_repository_message_remove(git_repository *repo);

/**
 * Remove all the metadata associated with an ongoing command like merge,
 * revert, cherry-pick, etc.  For example: MERGE_HEAD, MERGE_MSG, etc.
 *
 * @param repo A repository object
 * @return 0 on success, or error
 */
GIT_EXTERN(int) git_repository_state_cleanup(git_repository *repo);

typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
	const char *remote_url,
	const git_oid *oid,
	unsigned int is_merge,
	void *payload);

/**
 * Invoke 'callback' for each entry in the given FETCH_HEAD file.
 *
 * Return a non-zero value from the callback to stop the loop.
 *
 * @param repo A repository object
 * @param callback Callback function
 * @param payload Pointer to callback data (optional)
 * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
 *         there is no FETCH_HEAD file, or other error code.
 */
GIT_EXTERN(int) git_repository_fetchhead_foreach(
	git_repository *repo,
	git_repository_fetchhead_foreach_cb callback,
	void *payload);

typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid,
	void *payload);

/**
 * If a merge is in progress, invoke 'callback' for each commit ID in the
 * MERGE_HEAD file.
 *
 * Return a non-zero value from the callback to stop the loop.
 *
 * @param repo A repository object
 * @param callback Callback function
 * @param payload Pointer to callback data (optional)
 * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
 *         there is no MERGE_HEAD file, or other error code.
 */
GIT_EXTERN(int) git_repository_mergehead_foreach(
	git_repository *repo,
	git_repository_mergehead_foreach_cb callback,
	void *payload);

/**
 * Calculate hash of file using repository filtering rules.
 *
 * If you simply want to calculate the hash of a file on disk with no filters,
 * you can just use the `git_odb_hashfile()` API.  However, if you want to
 * hash a file in the repository and you want to apply filtering rules (e.g.
 * crlf filters) before generating the SHA, then use this function.
 *
 * Note: if the repository has `core.safecrlf` set to fail and the
 * filtering triggers that failure, then this function will return an
 * error and not calculate the hash of the file.
 *
 * @param out Output value of calculated SHA
 * @param repo Repository pointer
 * @param path Path to file on disk whose contents should be hashed. If the
 *             repository is not NULL, this can be a relative path.
 * @param type The object type to hash as (e.g. GIT_OBJ_BLOB)
 * @param as_path The path to use to look up filtering rules. If this is
 *             NULL, then the `path` parameter will be used instead. If
 *             this is passed as the empty string, then no filters will be
 *             applied when calculating the hash.
 * @return 0 on success, or an error code
 */
GIT_EXTERN(int) git_repository_hashfile(
	git_oid *out,
	git_repository *repo,
	const char *path,
	git_otype type,
	const char *as_path);

/**
 * Make the repository HEAD point to the specified reference.
 *
 * If the provided reference points to a Tree or a Blob, the HEAD is
 * unaltered and -1 is returned.
 *
 * If the provided reference points to a branch, the HEAD will point
 * to that branch, staying attached, or become attached if it isn't yet.
 * If the branch doesn't exist yet, no error will be return. The HEAD
 * will then be attached to an unborn branch.
 *
 * Otherwise, the HEAD will be detached and will directly point to
 * the Commit.
 *
 * @param repo Repository pointer
 * @param refname Canonical name of the reference the HEAD should point at
 * @return 0 on success, or an error code
 */
GIT_EXTERN(int) git_repository_set_head(
	git_repository* repo,
	const char* refname);

/**
 * Make the repository HEAD directly point to the Commit.
 *
 * If the provided committish cannot be found in the repository, the HEAD
 * is unaltered and GIT_ENOTFOUND is returned.
 *
 * If the provided commitish cannot be peeled into a commit, the HEAD
 * is unaltered and -1 is returned.
 *
 * Otherwise, the HEAD will eventually be detached and will directly point to
 * the peeled Commit.
 *
 * @param repo Repository pointer
 * @param commitish Object id of the Commit the HEAD should point to
 * @return 0 on success, or an error code
 */
GIT_EXTERN(int) git_repository_set_head_detached(
	git_repository* repo,
	const git_oid* commitish);

/**
 * Make the repository HEAD directly point to the Commit.
 *
 * This behaves like `git_repository_set_head_detached()` but takes an
 * annotated commit, which lets you specify which extended sha syntax
 * string was specified by a user, allowing for more exact reflog
 * messages.
 *
 * See the documentation for `git_repository_set_head_detached()`.
 *
 * @see git_repository_set_head_detached
 */
GIT_EXTERN(int) git_repository_set_head_detached_from_annotated(
	git_repository *repo,
	const git_annotated_commit *commitish);

/**
 * Detach the HEAD.
 *
 * If the HEAD is already detached and points to a Commit, 0 is returned.
 *
 * If the HEAD is already detached and points to a Tag, the HEAD is
 * updated into making it point to the peeled Commit, and 0 is returned.
 *
 * If the HEAD is already detached and points to a non commitish, the HEAD is
 * unaltered, and -1 is returned.
 *
 * Otherwise, the HEAD will be detached and point to the peeled Commit.
 *
 * @param repo Repository pointer
 * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
 * branch or an error code
 */
GIT_EXTERN(int) git_repository_detach_head(
	git_repository* repo);

/**
 * Repository state
 *
 * These values represent possible states for the repository to be in,
 * based on the current operation which is ongoing.
 */
typedef enum {
	GIT_REPOSITORY_STATE_NONE,
	GIT_REPOSITORY_STATE_MERGE,
	GIT_REPOSITORY_STATE_REVERT,
	GIT_REPOSITORY_STATE_REVERT_SEQUENCE,
	GIT_REPOSITORY_STATE_CHERRYPICK,
	GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE,
	GIT_REPOSITORY_STATE_BISECT,
	GIT_REPOSITORY_STATE_REBASE,
	GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
	GIT_REPOSITORY_STATE_REBASE_MERGE,
	GIT_REPOSITORY_STATE_APPLY_MAILBOX,
	GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE,
} git_repository_state_t;

/**
 * Determines the status of a git repository - ie, whether an operation
 * (merge, cherry-pick, etc) is in progress.
 *
 * @param repo Repository pointer
 * @return The state of the repository
 */
GIT_EXTERN(int) git_repository_state(git_repository *repo);

/**
 * Sets the active namespace for this Git Repository
 *
 * This namespace affects all reference operations for the repo.
 * See `man gitnamespaces`
 *
 * @param repo The repo
 * @param nmspace The namespace. This should not include the refs
 *	folder, e.g. to namespace all references under `refs/namespaces/foo/`,
 *	use `foo` as the namespace.
 *	@return 0 on success, -1 on error
 */
GIT_EXTERN(int) git_repository_set_namespace(git_repository *repo, const char *nmspace);

/**
 * Get the currently active namespace for this repository
 *
 * @param repo The repo
 * @return the active namespace, or NULL if there isn't one
 */
GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo);


/**
 * Determine if the repository was a shallow clone
 *
 * @param repo The repository
 * @return 1 if shallow, zero if not
 */
GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo);

/**
 * Retrieve the configured identity to use for reflogs
 *
 * The memory is owned by the repository and must not be freed by the
 * user.
 *
 * @param name where to store the pointer to the name
 * @param email where to store the pointer to the email
 * @param repo the repository
 */
GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, const git_repository *repo);

/**
 * Set the identity to be used for writing reflogs
 *
 * If both are set, this name and email will be used to write to the
 * reflog. Pass NULL to unset. When unset, the identity will be taken
 * from the repository's configuration.
 *
 * @param repo the repository to configure
 * @param name the name to use for the reflog entries
 * @param email the email to use for the reflog entries
 */
GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email);

/** @} */
GIT_END_DECL
#endif
