summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/git2.h74
-rw-r--r--include/git2/annotated_commit.h125
-rw-r--r--include/git2/apply.h165
-rw-r--r--include/git2/attr.h370
-rw-r--r--include/git2/blame.h285
-rw-r--r--include/git2/blob.h311
-rw-r--r--include/git2/branch.h336
-rw-r--r--include/git2/buffer.h74
-rw-r--r--include/git2/cert.h172
-rw-r--r--include/git2/checkout.h417
-rw-r--r--include/git2/cherrypick.h92
-rw-r--r--include/git2/clone.h209
-rw-r--r--include/git2/commit.h546
-rw-r--r--include/git2/common.h517
-rw-r--r--include/git2/config.h782
-rw-r--r--include/git2/cred_helpers.h15
-rw-r--r--include/git2/credential.h315
-rw-r--r--include/git2/credential_helpers.h53
-rw-r--r--include/git2/deprecated.h939
-rw-r--r--include/git2/describe.h194
-rw-r--r--include/git2/diff.h1477
-rw-r--r--include/git2/email.h127
-rw-r--r--include/git2/errors.h181
-rw-r--r--include/git2/experimental.h20
-rw-r--r--include/git2/filter.h276
-rw-r--r--include/git2/global.h44
-rw-r--r--include/git2/graph.h77
-rw-r--r--include/git2/ignore.h78
-rw-r--r--include/git2/index.h848
-rw-r--r--include/git2/indexer.h195
-rw-r--r--include/git2/mailmap.h115
-rw-r--r--include/git2/merge.h626
-rw-r--r--include/git2/message.h86
-rw-r--r--include/git2/net.h54
-rw-r--r--include/git2/notes.h306
-rw-r--r--include/git2/object.h279
-rw-r--r--include/git2/odb.h654
-rw-r--r--include/git2/odb_backend.h223
-rw-r--r--include/git2/oid.h373
-rw-r--r--include/git2/oidarray.h37
-rw-r--r--include/git2/pack.h267
-rw-r--r--include/git2/patch.h290
-rw-r--r--include/git2/pathspec.h280
-rw-r--r--include/git2/proxy.h98
-rw-r--r--include/git2/rebase.h399
-rw-r--r--include/git2/refdb.h71
-rw-r--r--include/git2/reflog.h170
-rw-r--r--include/git2/refs.h771
-rw-r--r--include/git2/refspec.h121
-rw-r--r--include/git2/remote.h1173
-rw-r--r--include/git2/repository.h983
-rw-r--r--include/git2/reset.h111
-rw-r--r--include/git2/revert.h91
-rw-r--r--include/git2/revparse.h113
-rw-r--r--include/git2/revwalk.h302
-rw-r--r--include/git2/signature.h103
-rw-r--r--include/git2/stash.h314
-rw-r--r--include/git2/status.h452
-rw-r--r--include/git2/stdint.h247
-rw-r--r--include/git2/strarray.h43
-rw-r--r--include/git2/submodule.h668
-rw-r--r--include/git2/sys/alloc.h67
-rw-r--r--include/git2/sys/commit.h80
-rw-r--r--include/git2/sys/commit_graph.h184
-rw-r--r--include/git2/sys/config.h130
-rw-r--r--include/git2/sys/cred.h15
-rw-r--r--include/git2/sys/credential.h90
-rw-r--r--include/git2/sys/diff.h94
-rw-r--r--include/git2/sys/email.h45
-rw-r--r--include/git2/sys/filter.h353
-rw-r--r--include/git2/sys/hashsig.h106
-rw-r--r--include/git2/sys/index.h182
-rw-r--r--include/git2/sys/mempack.h87
-rw-r--r--include/git2/sys/merge.h182
-rw-r--r--include/git2/sys/midx.h78
-rw-r--r--include/git2/sys/odb_backend.h172
-rw-r--r--include/git2/sys/openssl.h38
-rw-r--r--include/git2/sys/path.h64
-rw-r--r--include/git2/sys/refdb_backend.h361
-rw-r--r--include/git2/sys/reflog.h21
-rw-r--r--include/git2/sys/refs.h49
-rw-r--r--include/git2/sys/remote.h46
-rw-r--r--include/git2/sys/repository.h180
-rw-r--r--include/git2/sys/stream.h152
-rw-r--r--include/git2/sys/transport.h465
-rw-r--r--include/git2/tag.h383
-rw-r--r--include/git2/trace.h67
-rw-r--r--include/git2/transaction.h121
-rw-r--r--include/git2/transport.h42
-rw-r--r--include/git2/tree.h475
-rw-r--r--include/git2/types.h371
-rw-r--r--include/git2/version.h39
-rw-r--r--include/git2/worktree.h268
93 files changed, 24141 insertions, 0 deletions
diff --git a/include/git2.h b/include/git2.h
new file mode 100644
index 0000000..3457e5f
--- /dev/null
+++ b/include/git2.h
@@ -0,0 +1,74 @@
+/*
+ * 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_git_h__
+#define INCLUDE_git_git_h__
+
+#include "git2/annotated_commit.h"
+#include "git2/apply.h"
+#include "git2/attr.h"
+#include "git2/blob.h"
+#include "git2/blame.h"
+#include "git2/branch.h"
+#include "git2/buffer.h"
+#include "git2/cert.h"
+#include "git2/checkout.h"
+#include "git2/cherrypick.h"
+#include "git2/clone.h"
+#include "git2/commit.h"
+#include "git2/common.h"
+#include "git2/config.h"
+#include "git2/credential.h"
+#include "git2/deprecated.h"
+#include "git2/describe.h"
+#include "git2/diff.h"
+#include "git2/email.h"
+#include "git2/errors.h"
+#include "git2/experimental.h"
+#include "git2/filter.h"
+#include "git2/global.h"
+#include "git2/graph.h"
+#include "git2/ignore.h"
+#include "git2/index.h"
+#include "git2/indexer.h"
+#include "git2/mailmap.h"
+#include "git2/merge.h"
+#include "git2/message.h"
+#include "git2/net.h"
+#include "git2/notes.h"
+#include "git2/object.h"
+#include "git2/odb.h"
+#include "git2/odb_backend.h"
+#include "git2/oid.h"
+#include "git2/pack.h"
+#include "git2/patch.h"
+#include "git2/pathspec.h"
+#include "git2/proxy.h"
+#include "git2/rebase.h"
+#include "git2/refdb.h"
+#include "git2/reflog.h"
+#include "git2/refs.h"
+#include "git2/refspec.h"
+#include "git2/remote.h"
+#include "git2/repository.h"
+#include "git2/reset.h"
+#include "git2/revert.h"
+#include "git2/revparse.h"
+#include "git2/revwalk.h"
+#include "git2/signature.h"
+#include "git2/stash.h"
+#include "git2/status.h"
+#include "git2/submodule.h"
+#include "git2/tag.h"
+#include "git2/transport.h"
+#include "git2/transaction.h"
+#include "git2/tree.h"
+#include "git2/types.h"
+#include "git2/version.h"
+#include "git2/worktree.h"
+
+#endif
diff --git a/include/git2/annotated_commit.h b/include/git2/annotated_commit.h
new file mode 100644
index 0000000..3b7103f
--- /dev/null
+++ b/include/git2/annotated_commit.h
@@ -0,0 +1,125 @@
+/*
+ * 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_annotated_commit_h__
+#define INCLUDE_git_annotated_commit_h__
+
+#include "common.h"
+#include "repository.h"
+#include "types.h"
+
+/**
+ * @file git2/annotated_commit.h
+ * @brief Git annotated commit routines
+ * @defgroup git_annotated_commit Git annotated commit routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Creates a `git_annotated_commit` from the given reference.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given reference
+ * @param ref reference to use to lookup the git_annotated_commit
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_ref(
+ git_annotated_commit **out,
+ git_repository *repo,
+ const git_reference *ref);
+
+/**
+ * Creates a `git_annotated_commit` from the given fetch head data.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param branch_name name of the (remote) branch
+ * @param remote_url url of the remote
+ * @param id the commit object id of the remote branch
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_fetchhead(
+ git_annotated_commit **out,
+ git_repository *repo,
+ const char *branch_name,
+ const char *remote_url,
+ const git_oid *id);
+
+/**
+ * Creates a `git_annotated_commit` from the given commit id.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * An annotated commit contains information about how it was
+ * looked up, which may be useful for functions like merge or
+ * rebase to provide context to the operation. For example,
+ * conflict files will include the name of the source or target
+ * branches being merged. It is therefore preferable to use the
+ * most specific function (eg `git_annotated_commit_from_ref`)
+ * instead of this one when that data is known.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param id the commit object id to lookup
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_lookup(
+ git_annotated_commit **out,
+ git_repository *repo,
+ const git_oid *id);
+
+/**
+ * Creates a `git_annotated_commit` from a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param revspec the extended sha syntax string to use to lookup the commit
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_revspec(
+ git_annotated_commit **out,
+ git_repository *repo,
+ const char *revspec);
+
+/**
+ * Gets the commit ID that the given `git_annotated_commit` refers to.
+ *
+ * @param commit the given annotated commit
+ * @return commit id
+ */
+GIT_EXTERN(const git_oid *) git_annotated_commit_id(
+ const git_annotated_commit *commit);
+
+/**
+ * Get the refname that the given `git_annotated_commit` refers to.
+ *
+ * @param commit the given annotated commit
+ * @return ref name.
+ */
+GIT_EXTERN(const char *) git_annotated_commit_ref(
+ const git_annotated_commit *commit);
+
+/**
+ * Frees a `git_annotated_commit`.
+ *
+ * @param commit annotated commit to free
+ */
+GIT_EXTERN(void) git_annotated_commit_free(
+ git_annotated_commit *commit);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/apply.h b/include/git2/apply.h
new file mode 100644
index 0000000..db652bd
--- /dev/null
+++ b/include/git2/apply.h
@@ -0,0 +1,165 @@
+/*
+ * 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_apply_h__
+#define INCLUDE_git_apply_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "diff.h"
+
+/**
+ * @file git2/apply.h
+ * @brief Git patch application routines
+ * @defgroup git_apply Git patch application routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * When applying a patch, callback that will be made per delta (file).
+ *
+ * When the callback:
+ * - returns < 0, the apply process will be aborted.
+ * - returns > 0, the delta will not be applied, but the apply process
+ * continues
+ * - returns 0, the delta is applied, and the apply process continues.
+ *
+ * @param delta The delta to be applied
+ * @param payload User-specified payload
+ * @return 0 if the delta is applied, < 0 if the apply process will be aborted
+ * or > 0 if the delta will not be applied.
+ */
+typedef int GIT_CALLBACK(git_apply_delta_cb)(
+ const git_diff_delta *delta,
+ void *payload);
+
+/**
+ * When applying a patch, callback that will be made per hunk.
+ *
+ * When the callback:
+ * - returns < 0, the apply process will be aborted.
+ * - returns > 0, the hunk will not be applied, but the apply process
+ * continues
+ * - returns 0, the hunk is applied, and the apply process continues.
+ *
+ * @param hunk The hunk to be applied
+ * @param payload User-specified payload
+ * @return 0 if the hunk is applied, < 0 if the apply process will be aborted
+ * or > 0 if the hunk will not be applied.
+ */
+typedef int GIT_CALLBACK(git_apply_hunk_cb)(
+ const git_diff_hunk *hunk,
+ void *payload);
+
+/** Flags controlling the behavior of git_apply */
+typedef enum {
+ /**
+ * Don't actually make changes, just test that the patch applies.
+ * This is the equivalent of `git apply --check`.
+ */
+ GIT_APPLY_CHECK = (1 << 0)
+} git_apply_flags_t;
+
+/**
+ * Apply options structure
+ *
+ * Initialize with `GIT_APPLY_OPTIONS_INIT`. Alternatively, you can
+ * use `git_apply_options_init`.
+ *
+ * @see git_apply_to_tree, git_apply
+ */
+typedef struct {
+ unsigned int version; /**< The version */
+
+ /** When applying a patch, callback that will be made per delta (file). */
+ git_apply_delta_cb delta_cb;
+
+ /** When applying a patch, callback that will be made per hunk. */
+ git_apply_hunk_cb hunk_cb;
+
+ /** Payload passed to both delta_cb & hunk_cb. */
+ void *payload;
+
+ /** Bitmask of git_apply_flags_t */
+ unsigned int flags;
+} git_apply_options;
+
+#define GIT_APPLY_OPTIONS_VERSION 1
+#define GIT_APPLY_OPTIONS_INIT {GIT_APPLY_OPTIONS_VERSION}
+
+/**
+ * Initialize git_apply_options structure
+ *
+ * Initialize a `git_apply_options` with default values. Equivalent to creating
+ * an instance with GIT_APPLY_OPTIONS_INIT.
+ *
+ * @param opts The `git_apply_options` struct to initialize.
+ * @param version The struct version; pass `GIT_APPLY_OPTIONS_VERSION`
+ * @return 0 on success or -1 on failure.
+ */
+GIT_EXTERN(int) git_apply_options_init(git_apply_options *opts, unsigned int version);
+
+/**
+ * Apply a `git_diff` to a `git_tree`, and return the resulting image
+ * as an index.
+ *
+ * @param out the postimage of the application
+ * @param repo the repository to apply
+ * @param preimage the tree to apply the diff to
+ * @param diff the diff to apply
+ * @param options the options for the apply (or null for defaults)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_apply_to_tree(
+ git_index **out,
+ git_repository *repo,
+ git_tree *preimage,
+ git_diff *diff,
+ const git_apply_options *options);
+
+/** Possible application locations for git_apply */
+typedef enum {
+ /**
+ * Apply the patch to the workdir, leaving the index untouched.
+ * This is the equivalent of `git apply` with no location argument.
+ */
+ GIT_APPLY_LOCATION_WORKDIR = 0,
+
+ /**
+ * Apply the patch to the index, leaving the working directory
+ * untouched. This is the equivalent of `git apply --cached`.
+ */
+ GIT_APPLY_LOCATION_INDEX = 1,
+
+ /**
+ * Apply the patch to both the working directory and the index.
+ * This is the equivalent of `git apply --index`.
+ */
+ GIT_APPLY_LOCATION_BOTH = 2
+} git_apply_location_t;
+
+/**
+ * Apply a `git_diff` to the given repository, making changes directly
+ * in the working directory, the index, or both.
+ *
+ * @param repo the repository to apply to
+ * @param diff the diff to apply
+ * @param location the location to apply (workdir, index or both)
+ * @param options the options for the apply (or null for defaults)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_apply(
+ git_repository *repo,
+ git_diff *diff,
+ git_apply_location_t location,
+ const git_apply_options *options);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/attr.h b/include/git2/attr.h
new file mode 100644
index 0000000..0c83872
--- /dev/null
+++ b/include/git2/attr.h
@@ -0,0 +1,370 @@
+/*
+ * 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_attr_h__
+#define INCLUDE_git_attr_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/attr.h
+ * @brief Git attribute management routines
+ * @defgroup git_attr Git attribute management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * GIT_ATTR_TRUE checks if an attribute is set on. In core git
+ * parlance, this the value for "Set" attributes.
+ *
+ * For example, if the attribute file contains:
+ *
+ * *.c foo
+ *
+ * Then for file `xyz.c` looking up attribute "foo" gives a value for
+ * which `GIT_ATTR_TRUE(value)` is true.
+ */
+#define GIT_ATTR_IS_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_TRUE)
+
+/**
+ * GIT_ATTR_FALSE checks if an attribute is set off. In core git
+ * parlance, this is the value for attributes that are "Unset" (not to
+ * be confused with values that a "Unspecified").
+ *
+ * For example, if the attribute file contains:
+ *
+ * *.h -foo
+ *
+ * Then for file `zyx.h` looking up attribute "foo" gives a value for
+ * which `GIT_ATTR_FALSE(value)` is true.
+ */
+#define GIT_ATTR_IS_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_FALSE)
+
+/**
+ * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This
+ * may be due to the attribute not being mentioned at all or because
+ * the attribute was explicitly set unspecified via the `!` operator.
+ *
+ * For example, if the attribute file contains:
+ *
+ * *.c foo
+ * *.h -foo
+ * onefile.c !foo
+ *
+ * Then for `onefile.c` looking up attribute "foo" yields a value with
+ * `GIT_ATTR_UNSPECIFIED(value)` of true. Also, looking up "foo" on
+ * file `onefile.rb` or looking up "bar" on any file will all give
+ * `GIT_ATTR_UNSPECIFIED(value)` of true.
+ */
+#define GIT_ATTR_IS_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_UNSPECIFIED)
+
+/**
+ * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
+ * opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if
+ * for a file with something like:
+ *
+ * *.txt eol=lf
+ *
+ * Given this, looking up "eol" for `onefile.txt` will give back the
+ * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true.
+ */
+#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_STRING)
+
+/**
+ * Possible states for an attribute
+ */
+typedef enum {
+ GIT_ATTR_VALUE_UNSPECIFIED = 0, /**< The attribute has been left unspecified */
+ GIT_ATTR_VALUE_TRUE, /**< The attribute has been set */
+ GIT_ATTR_VALUE_FALSE, /**< The attribute has been unset */
+ GIT_ATTR_VALUE_STRING /**< This attribute has a value */
+} git_attr_value_t;
+
+/**
+ * Return the value type for a given attribute.
+ *
+ * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute
+ * was not set at all), or `VALUE`, if the attribute was set to an
+ * actual string.
+ *
+ * If the attribute has a `VALUE` string, it can be accessed normally
+ * as a NULL-terminated C string.
+ *
+ * @param attr The attribute
+ * @return the value type for the attribute
+ */
+GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr);
+
+/**
+ * Check attribute flags: Reading values from index and working directory.
+ *
+ * When checking attributes, it is possible to check attribute files
+ * in both the working directory (if there is one) and the index (if
+ * there is one). You can explicitly choose where to check and in
+ * which order using the following flags.
+ *
+ * Core git usually checks the working directory then the index,
+ * except during a checkout when it checks the index first. It will
+ * use index only for creating archives or for a bare repo (if an
+ * index has been specified for the bare repo).
+ */
+#define GIT_ATTR_CHECK_FILE_THEN_INDEX 0
+#define GIT_ATTR_CHECK_INDEX_THEN_FILE 1
+#define GIT_ATTR_CHECK_INDEX_ONLY 2
+
+/**
+ * Check attribute flags: controlling extended attribute behavior.
+ *
+ * Normally, attribute checks include looking in the /etc (or system
+ * equivalent) directory for a `gitattributes` file. Passing this
+ * flag will cause attribute checks to ignore that file.
+ * equivalent) directory for a `gitattributes` file. Passing the
+ * `GIT_ATTR_CHECK_NO_SYSTEM` flag will cause attribute checks to
+ * ignore that file.
+ *
+ * Passing the `GIT_ATTR_CHECK_INCLUDE_HEAD` flag will use attributes
+ * from a `.gitattributes` file in the repository at the HEAD revision.
+ *
+ * Passing the `GIT_ATTR_CHECK_INCLUDE_COMMIT` flag will use attributes
+ * from a `.gitattributes` file in a specific commit.
+ */
+#define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2)
+#define GIT_ATTR_CHECK_INCLUDE_HEAD (1 << 3)
+#define GIT_ATTR_CHECK_INCLUDE_COMMIT (1 << 4)
+
+/**
+* An options structure for querying attributes.
+*/
+typedef struct {
+ unsigned int version;
+
+ /** A combination of GIT_ATTR_CHECK flags */
+ unsigned int flags;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ git_oid *commit_id;
+#endif
+
+ /**
+ * The commit to load attributes from, when
+ * `GIT_ATTR_CHECK_INCLUDE_COMMIT` is specified.
+ */
+ git_oid attr_commit_id;
+} git_attr_options;
+
+#define GIT_ATTR_OPTIONS_VERSION 1
+#define GIT_ATTR_OPTIONS_INIT {GIT_ATTR_OPTIONS_VERSION}
+
+/**
+ * Look up the value of one git attribute for path.
+ *
+ * @param value_out Output of the value of the attribute. Use the GIT_ATTR_...
+ * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
+ * use the string value for attributes set to a value. You
+ * should NOT modify or free this value.
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path The path to check for attributes. Relative paths are
+ * interpreted relative to the repo root. The file does
+ * not have to exist, but if it does not, then it will be
+ * treated as a plain file (not a directory).
+ * @param name The name of the attribute to look up.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_attr_get(
+ const char **value_out,
+ git_repository *repo,
+ uint32_t flags,
+ const char *path,
+ const char *name);
+
+/**
+ * Look up the value of one git attribute for path with extended options.
+ *
+ * @param value_out Output of the value of the attribute. Use the GIT_ATTR_...
+ * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
+ * use the string value for attributes set to a value. You
+ * should NOT modify or free this value.
+ * @param repo The repository containing the path.
+ * @param opts The `git_attr_options` to use when querying these attributes.
+ * @param path The path to check for attributes. Relative paths are
+ * interpreted relative to the repo root. The file does
+ * not have to exist, but if it does not, then it will be
+ * treated as a plain file (not a directory).
+ * @param name The name of the attribute to look up.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_attr_get_ext(
+ const char **value_out,
+ git_repository *repo,
+ git_attr_options *opts,
+ const char *path,
+ const char *name);
+
+/**
+ * Look up a list of git attributes for path.
+ *
+ * Use this if you have a known list of attributes that you want to
+ * look up in a single call. This is somewhat more efficient than
+ * calling `git_attr_get()` multiple times.
+ *
+ * For example, you might write:
+ *
+ * const char *attrs[] = { "crlf", "diff", "foo" };
+ * const char **values[3];
+ * git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs);
+ *
+ * Then you could loop through the 3 values to get the settings for
+ * the three attributes you asked about.
+ *
+ * @param values_out An array of num_attr entries that will have string
+ * pointers written into it for the values of the attributes.
+ * You should not modify or free the values that are written
+ * into this array (although of course, you should free the
+ * array itself if you allocated it).
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path The path inside the repo to check attributes. This
+ * does not have to exist, but if it does not, then
+ * it will be treated as a plain file (i.e. not a directory).
+ * @param num_attr The number of attributes being looked up
+ * @param names An array of num_attr strings containing attribute names.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_attr_get_many(
+ const char **values_out,
+ git_repository *repo,
+ uint32_t flags,
+ const char *path,
+ size_t num_attr,
+ const char **names);
+
+/**
+ * Look up a list of git attributes for path with extended options.
+ *
+ * @param values_out An array of num_attr entries that will have string
+ * pointers written into it for the values of the attributes.
+ * You should not modify or free the values that are written
+ * into this array (although of course, you should free the
+ * array itself if you allocated it).
+ * @param repo The repository containing the path.
+ * @param opts The `git_attr_options` to use when querying these attributes.
+ * @param path The path inside the repo to check attributes. This
+ * does not have to exist, but if it does not, then
+ * it will be treated as a plain file (i.e. not a directory).
+ * @param num_attr The number of attributes being looked up
+ * @param names An array of num_attr strings containing attribute names.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_attr_get_many_ext(
+ const char **values_out,
+ git_repository *repo,
+ git_attr_options *opts,
+ const char *path,
+ size_t num_attr,
+ const char **names);
+
+/**
+ * The callback used with git_attr_foreach.
+ *
+ * This callback will be invoked only once per attribute name, even if there
+ * are multiple rules for a given file. The highest priority rule will be
+ * used.
+ *
+ * @see git_attr_foreach.
+ *
+ * @param name The attribute name.
+ * @param value The attribute value. May be NULL if the attribute is explicitly
+ * set to UNSPECIFIED using the '!' sign.
+ * @param payload A user-specified pointer.
+ * @return 0 to continue looping, non-zero to stop. This value will be returned
+ * from git_attr_foreach.
+ */
+typedef int GIT_CALLBACK(git_attr_foreach_cb)(const char *name, const char *value, void *payload);
+
+/**
+ * Loop over all the git attributes for a path.
+ *
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path Path inside the repo to check attributes. This does not have
+ * to exist, but if it does not, then it will be treated as a
+ * plain file (i.e. not a directory).
+ * @param callback Function to invoke on each attribute name and value.
+ * See git_attr_foreach_cb.
+ * @param payload Passed on as extra parameter to callback function.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_attr_foreach(
+ git_repository *repo,
+ uint32_t flags,
+ const char *path,
+ git_attr_foreach_cb callback,
+ void *payload);
+
+/**
+ * Loop over all the git attributes for a path with extended options.
+ *
+ * @param repo The repository containing the path.
+ * @param opts The `git_attr_options` to use when querying these attributes.
+ * @param path Path inside the repo to check attributes. This does not have
+ * to exist, but if it does not, then it will be treated as a
+ * plain file (i.e. not a directory).
+ * @param callback Function to invoke on each attribute name and value.
+ * See git_attr_foreach_cb.
+ * @param payload Passed on as extra parameter to callback function.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_attr_foreach_ext(
+ git_repository *repo,
+ git_attr_options *opts,
+ const char *path,
+ git_attr_foreach_cb callback,
+ void *payload);
+
+/**
+ * Flush the gitattributes cache.
+ *
+ * Call this if you have reason to believe that the attributes files on
+ * disk no longer match the cached contents of memory. This will cause
+ * the attributes files to be reloaded the next time that an attribute
+ * access function is called.
+ *
+ * @param repo The repository containing the gitattributes cache
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_attr_cache_flush(
+ git_repository *repo);
+
+/**
+ * Add a macro definition.
+ *
+ * Macros will automatically be loaded from the top level `.gitattributes`
+ * file of the repository (plus the built-in "binary" macro). This
+ * function allows you to add others. For example, to add the default
+ * macro, you would call:
+ *
+ * git_attr_add_macro(repo, "binary", "-diff -crlf");
+ *
+ * @param repo The repository to add the macro in.
+ * @param name The name of the macro.
+ * @param values The value for the macro.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_attr_add_macro(
+ git_repository *repo,
+ const char *name,
+ const char *values);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/blame.h b/include/git2/blame.h
new file mode 100644
index 0000000..cb961a5
--- /dev/null
+++ b/include/git2/blame.h
@@ -0,0 +1,285 @@
+/*
+ * 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_blame_h__
+#define INCLUDE_git_blame_h__
+
+#include "common.h"
+#include "oid.h"
+
+/**
+ * @file git2/blame.h
+ * @brief Git blame routines
+ * @defgroup git_blame Git blame routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags for indicating option behavior for git_blame APIs.
+ */
+typedef enum {
+ /** Normal blame, the default */
+ GIT_BLAME_NORMAL = 0,
+
+ /**
+ * Track lines that have moved within a file (like `git blame -M`).
+ *
+ * This is not yet implemented and reserved for future use.
+ */
+ GIT_BLAME_TRACK_COPIES_SAME_FILE = (1<<0),
+
+ /**
+ * Track lines that have moved across files in the same commit
+ * (like `git blame -C`).
+ *
+ * This is not yet implemented and reserved for future use.
+ */
+ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES = (1<<1),
+
+ /**
+ * Track lines that have been copied from another file that exists
+ * in the same commit (like `git blame -CC`). Implies SAME_FILE.
+ *
+ * This is not yet implemented and reserved for future use.
+ */
+ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES = (1<<2),
+
+ /**
+ * Track lines that have been copied from another file that exists in
+ * *any* commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES.
+ *
+ * This is not yet implemented and reserved for future use.
+ */
+ GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3),
+
+ /**
+ * Restrict the search of commits to those reachable following only
+ * the first parents.
+ */
+ GIT_BLAME_FIRST_PARENT = (1<<4),
+
+ /**
+ * Use mailmap file to map author and committer names and email
+ * addresses to canonical real names and email addresses. The
+ * mailmap will be read from the working directory, or HEAD in a
+ * bare repository.
+ */
+ GIT_BLAME_USE_MAILMAP = (1<<5),
+
+ /** Ignore whitespace differences */
+ GIT_BLAME_IGNORE_WHITESPACE = (1<<6)
+} git_blame_flag_t;
+
+/**
+ * Blame options structure
+ *
+ * Initialize with `GIT_BLAME_OPTIONS_INIT`. Alternatively, you can
+ * use `git_blame_options_init`.
+ *
+ */
+typedef struct git_blame_options {
+ unsigned int version;
+
+ /** A combination of `git_blame_flag_t` */
+ uint32_t flags;
+
+ /**
+ * The lower bound on the number of alphanumeric characters that
+ * must be detected as moving/copying within a file for it to
+ * associate those lines with the parent commit. The default value
+ * is 20.
+ *
+ * This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*`
+ * flags are specified.
+ */
+ uint16_t min_match_characters;
+
+ /** The id of the newest commit to consider. The default is HEAD. */
+ git_oid newest_commit;
+
+ /**
+ * The id of the oldest commit to consider.
+ * The default is the first commit encountered with a NULL parent.
+ */
+ git_oid oldest_commit;
+
+ /**
+ * The first line in the file to blame.
+ * The default is 1 (line numbers start with 1).
+ */
+ size_t min_line;
+
+ /**
+ * The last line in the file to blame.
+ * The default is the last line of the file.
+ */
+ size_t max_line;
+} git_blame_options;
+
+#define GIT_BLAME_OPTIONS_VERSION 1
+#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
+
+/**
+ * Initialize git_blame_options structure
+ *
+ * Initializes a `git_blame_options` with default values. Equivalent to creating
+ * an instance with GIT_BLAME_OPTIONS_INIT.
+ *
+ * @param opts The `git_blame_options` struct to initialize.
+ * @param version The struct version; pass `GIT_BLAME_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_blame_options_init(
+ git_blame_options *opts,
+ unsigned int version);
+
+/**
+ * Structure that represents a blame hunk.
+ */
+typedef struct git_blame_hunk {
+ /**
+ * The number of lines in this hunk.
+ */
+ size_t lines_in_hunk;
+
+ /**
+ * The OID of the commit where this line was last changed.
+ */
+ git_oid final_commit_id;
+
+ /**
+ * The 1-based line number where this hunk begins, in the final version
+ * of the file.
+ */
+ size_t final_start_line_number;
+
+ /**
+ * The author of `final_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been
+ * specified, it will contain the canonical real name and email address.
+ */
+ git_signature *final_signature;
+
+ /**
+ * The OID of the commit where this hunk was found.
+ * This will usually be the same as `final_commit_id`, except when
+ * `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified.
+ */
+ git_oid orig_commit_id;
+
+ /**
+ * The path to the file where this hunk originated, as of the commit
+ * specified by `orig_commit_id`.
+ */
+ const char *orig_path;
+
+ /**
+ * The 1-based line number where this hunk begins in the file named by
+ * `orig_path` in the commit specified by `orig_commit_id`.
+ */
+ size_t orig_start_line_number;
+
+ /**
+ * The author of `orig_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been
+ * specified, it will contain the canonical real name and email address.
+ */
+ git_signature *orig_signature;
+
+ /**
+ * The 1 iff the hunk has been tracked to a boundary commit (the root,
+ * or the commit specified in git_blame_options.oldest_commit)
+ */
+ char boundary;
+} git_blame_hunk;
+
+
+/** Opaque structure to hold blame results */
+typedef struct git_blame git_blame;
+
+/**
+ * Gets the number of hunks that exist in the blame structure.
+ *
+ * @param blame The blame structure to query.
+ * @return The number of hunks.
+ */
+GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame);
+
+/**
+ * Gets the blame hunk at the given index.
+ *
+ * @param blame the blame structure to query
+ * @param index index of the hunk to retrieve
+ * @return the hunk at the given index, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex(
+ git_blame *blame,
+ uint32_t index);
+
+/**
+ * Gets the hunk that relates to the given line number in the newest commit.
+ *
+ * @param blame the blame structure to query
+ * @param lineno the (1-based) line number to find a hunk for
+ * @return the hunk that contains the given line, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byline(
+ git_blame *blame,
+ size_t lineno);
+
+/**
+ * Get the blame for a single file.
+ *
+ * @param out pointer that will receive the blame object
+ * @param repo repository whose history is to be walked
+ * @param path path to file to consider
+ * @param options options for the blame operation. If NULL, this is treated as
+ * though GIT_BLAME_OPTIONS_INIT were passed.
+ * @return 0 on success, or an error code. (use git_error_last for information
+ * about the error.)
+ */
+GIT_EXTERN(int) git_blame_file(
+ git_blame **out,
+ git_repository *repo,
+ const char *path,
+ git_blame_options *options);
+
+
+/**
+ * Get blame data for a file that has been modified in memory. The `reference`
+ * parameter is a pre-calculated blame for the in-odb history of the file. This
+ * means that once a file blame is completed (which can be expensive), updating
+ * the buffer blame is very fast.
+ *
+ * Lines that differ between the buffer and the committed version are marked as
+ * having a zero OID for their final_commit_id.
+ *
+ * @param out pointer that will receive the resulting blame data
+ * @param reference cached blame from the history of the file (usually the output
+ * from git_blame_file)
+ * @param buffer the (possibly) modified contents of the file
+ * @param buffer_len number of valid bytes in the buffer
+ * @return 0 on success, or an error code. (use git_error_last for information
+ * about the error)
+ */
+GIT_EXTERN(int) git_blame_buffer(
+ git_blame **out,
+ git_blame *reference,
+ const char *buffer,
+ size_t buffer_len);
+
+/**
+ * Free memory allocated by git_blame_file or git_blame_buffer.
+ *
+ * @param blame the blame structure to free
+ */
+GIT_EXTERN(void) git_blame_free(git_blame *blame);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/blob.h b/include/git2/blob.h
new file mode 100644
index 0000000..6db85f3
--- /dev/null
+++ b/include/git2/blob.h
@@ -0,0 +1,311 @@
+/*
+ * 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_blob_h__
+#define INCLUDE_git_blob_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+#include "buffer.h"
+
+/**
+ * @file git2/blob.h
+ * @brief Git blob load and write routines
+ * @defgroup git_blob Git blob load and write routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a blob object from a repository.
+ *
+ * @param blob pointer to the looked up blob
+ * @param repo the repo to use when locating the blob.
+ * @param id identity of the blob to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a blob object from a repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param blob pointer to the looked up blob
+ * @param repo the repo to use when locating the blob.
+ * @param id identity of the blob to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open blob
+ *
+ * This is a wrapper around git_object_free()
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop
+ * using a blob. Failure to do so will cause a memory leak.
+ *
+ * @param blob the blob to close
+ */
+GIT_EXTERN(void) git_blob_free(git_blob *blob);
+
+/**
+ * Get the id of a blob.
+ *
+ * @param blob a previously loaded blob.
+ * @return SHA1 hash for this blob.
+ */
+GIT_EXTERN(const git_oid *) git_blob_id(const git_blob *blob);
+
+/**
+ * Get the repository that contains the blob.
+ *
+ * @param blob A previously loaded blob.
+ * @return Repository that contains this blob.
+ */
+GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob);
+
+/**
+ * Get a read-only buffer with the raw content of a blob.
+ *
+ * A pointer to the raw content of a blob is returned;
+ * this pointer is owned internally by the object and shall
+ * not be free'd. The pointer may be invalidated at a later
+ * time.
+ *
+ * @param blob pointer to the blob
+ * @return the pointer, or NULL on error
+ */
+GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
+
+/**
+ * Get the size in bytes of the contents of a blob
+ *
+ * @param blob pointer to the blob
+ * @return size on bytes
+ */
+GIT_EXTERN(git_object_size_t) git_blob_rawsize(const git_blob *blob);
+
+/**
+ * Flags to control the functionality of `git_blob_filter`.
+ */
+typedef enum {
+ /** When set, filters will not be applied to binary files. */
+ GIT_BLOB_FILTER_CHECK_FOR_BINARY = (1 << 0),
+
+ /**
+ * When set, filters will not load configuration from the
+ * system-wide `gitattributes` in `/etc` (or system equivalent).
+ */
+ GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES = (1 << 1),
+
+ /**
+ * When set, filters will be loaded from a `.gitattributes` file
+ * in the HEAD commit.
+ */
+ GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD = (1 << 2),
+
+ /**
+ * When set, filters will be loaded from a `.gitattributes` file
+ * in the specified commit.
+ */
+ GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3)
+} git_blob_filter_flag_t;
+
+/**
+ * The options used when applying filter options to a file.
+ *
+ * Initialize with `GIT_BLOB_FILTER_OPTIONS_INIT`. Alternatively, you can
+ * use `git_blob_filter_options_init`.
+ *
+ */
+typedef struct {
+ int version;
+
+ /** Flags to control the filtering process, see `git_blob_filter_flag_t` above */
+ uint32_t flags;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ git_oid *commit_id;
+#endif
+
+ /**
+ * The commit to load attributes from, when
+ * `GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
+ */
+ git_oid attr_commit_id;
+} git_blob_filter_options;
+
+#define GIT_BLOB_FILTER_OPTIONS_VERSION 1
+#define GIT_BLOB_FILTER_OPTIONS_INIT {GIT_BLOB_FILTER_OPTIONS_VERSION, GIT_BLOB_FILTER_CHECK_FOR_BINARY}
+
+/**
+ * Initialize git_blob_filter_options structure
+ *
+ * Initializes a `git_blob_filter_options` with default values. Equivalent
+ * to creating an instance with `GIT_BLOB_FILTER_OPTIONS_INIT`.
+ *
+ * @param opts The `git_blob_filter_options` struct to initialize.
+ * @param version The struct version; pass `GIT_BLOB_FILTER_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_blob_filter_options_init(git_blob_filter_options *opts, unsigned int version);
+
+/**
+ * Get a buffer with the filtered content of a blob.
+ *
+ * This applies filters as if the blob was being checked out to the
+ * working directory under the specified filename. This may apply
+ * CRLF filtering or other types of changes depending on the file
+ * attributes set for the blob and the content detected in it.
+ *
+ * The output is written into a `git_buf` which the caller must free
+ * when done (via `git_buf_dispose`).
+ *
+ * If no filters need to be applied, then the `out` buffer will just
+ * be populated with a pointer to the raw content of the blob. In
+ * that case, be careful to *not* free the blob until done with the
+ * buffer or copy it into memory you own.
+ *
+ * @param out The git_buf to be filled in
+ * @param blob Pointer to the blob
+ * @param as_path Path used for file attribute lookups, etc.
+ * @param opts Options to use for filtering the blob
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_blob_filter(
+ git_buf *out,
+ git_blob *blob,
+ const char *as_path,
+ git_blob_filter_options *opts);
+
+/**
+ * Read a file from the working folder of a repository
+ * and write it to the Object Database as a loose blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where the blob will be written.
+ * this repository cannot be bare
+ * @param relative_path file from which the blob will be created,
+ * relative to the repository's working dir
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_from_workdir(git_oid *id, git_repository *repo, const char *relative_path);
+
+/**
+ * Read a file from the filesystem and write its content
+ * to the Object Database as a loose blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where the blob will be written.
+ * this repository can be bare or not
+ * @param path file from which the blob will be created
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_from_disk(git_oid *id, git_repository *repo, const char *path);
+
+/**
+ * Create a stream to write a new blob into the object db
+ *
+ * This function may need to buffer the data on disk and will in
+ * general not be the right choice if you know the size of the data
+ * to write. If you have data in memory, use
+ * `git_blob_create_from_buffer()`. If you do not, but know the size of
+ * the contents (and don't want/need to perform filtering), use
+ * `git_odb_open_wstream()`.
+ *
+ * Don't close this stream yourself but pass it to
+ * `git_blob_create_from_stream_commit()` to commit the write to the
+ * object db and get the object id.
+ *
+ * If the `hintpath` parameter is filled, it will be used to determine
+ * what git filters should be applied to the object before it is written
+ * to the object database.
+ *
+ * @param out the stream into which to write
+ * @param repo Repository where the blob will be written.
+ * This repository can be bare or not.
+ * @param hintpath If not NULL, will be used to select data filters
+ * to apply onto the content of the blob to be created.
+ * @return 0 or error code
+ */
+GIT_EXTERN(int) git_blob_create_from_stream(
+ git_writestream **out,
+ git_repository *repo,
+ const char *hintpath);
+
+/**
+ * Close the stream and write the blob to the object db
+ *
+ * The stream will be closed and freed.
+ *
+ * @param out the id of the new blob
+ * @param stream the stream to close
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_from_stream_commit(
+ git_oid *out,
+ git_writestream *stream);
+
+/**
+ * Write an in-memory buffer to the ODB as a blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where the blob will be written
+ * @param buffer data to be written into the blob
+ * @param len length of the data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_from_buffer(
+ git_oid *id, git_repository *repo, const void *buffer, size_t len);
+
+/**
+ * Determine if the blob content is most certainly binary or not.
+ *
+ * The heuristic used to guess if a file is binary is taken from core git:
+ * Searching for NUL bytes and looking for a reasonable ratio of printable
+ * to non-printable characters among the first 8000 bytes.
+ *
+ * @param blob The blob which content should be analyzed
+ * @return 1 if the content of the blob is detected
+ * as binary; 0 otherwise.
+ */
+GIT_EXTERN(int) git_blob_is_binary(const git_blob *blob);
+
+/**
+ * Determine if the given content is most certainly binary or not;
+ * this is the same mechanism used by `git_blob_is_binary` but only
+ * looking at raw data.
+ *
+ * @param data The blob data which content should be analyzed
+ * @param len The length of the data
+ * @return 1 if the content of the blob is detected
+ * as binary; 0 otherwise.
+ */
+GIT_EXTERN(int) git_blob_data_is_binary(const char *data, size_t len);
+
+/**
+ * Create an in-memory copy of a blob. The copy must be explicitly
+ * free'd or it will leak.
+ *
+ * @param out Pointer to store the copy of the object
+ * @param source Original object to copy
+ * @return 0.
+ */
+GIT_EXTERN(int) git_blob_dup(git_blob **out, git_blob *source);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/branch.h b/include/git2/branch.h
new file mode 100644
index 0000000..27c6fa1
--- /dev/null
+++ b/include/git2/branch.h
@@ -0,0 +1,336 @@
+/*
+ * 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_branch_h__
+#define INCLUDE_git_branch_h__
+
+#include "common.h"
+#include "oid.h"
+#include "types.h"
+
+/**
+ * @file git2/branch.h
+ * @brief Git branch parsing routines
+ * @defgroup git_branch Git branch management
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new branch pointing at a target commit
+ *
+ * A new direct reference will be created pointing to
+ * this target commit. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The returned reference must be freed by the user.
+ *
+ * The branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param out Pointer where to store the underlying reference.
+ *
+ * @param repo the repository to create the branch in.
+ *
+ * @param branch_name Name for the branch; this name is
+ * validated for consistency. It should also not conflict with
+ * an already existing branch name.
+ *
+ * @param target Commit to which this branch should point. This object
+ * must belong to the given `repo`.
+ *
+ * @param force Overwrite existing branch.
+ *
+ * @return 0, GIT_EINVALIDSPEC or an error code.
+ * A proper reference is written in the refs/heads namespace
+ * pointing to the provided target commit.
+ */
+GIT_EXTERN(int) git_branch_create(
+ git_reference **out,
+ git_repository *repo,
+ const char *branch_name,
+ const git_commit *target,
+ int force);
+
+/**
+ * Create a new branch pointing at a target commit
+ *
+ * This behaves like `git_branch_create()` 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_branch_create()`.
+ *
+ * @see git_branch_create
+ */
+GIT_EXTERN(int) git_branch_create_from_annotated(
+ git_reference **ref_out,
+ git_repository *repository,
+ const char *branch_name,
+ const git_annotated_commit *commit,
+ int force);
+
+/**
+ * Delete an existing branch reference.
+ *
+ * Note that if the deletion succeeds, the reference object will not
+ * be valid anymore, and should be freed immediately by the user using
+ * `git_reference_free()`.
+ *
+ * @param branch A valid reference representing a branch
+ * @return 0 on success, or an error code.
+ */
+GIT_EXTERN(int) git_branch_delete(git_reference *branch);
+
+/** Iterator type for branches */
+typedef struct git_branch_iterator git_branch_iterator;
+
+/**
+ * Create an iterator which loops over the requested branches.
+ *
+ * @param out the iterator
+ * @param repo Repository where to find the branches.
+ * @param list_flags Filtering flags for the branch
+ * listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
+ * or GIT_BRANCH_ALL.
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_branch_iterator_new(
+ git_branch_iterator **out,
+ git_repository *repo,
+ git_branch_t list_flags);
+
+/**
+ * Retrieve the next branch from the iterator
+ *
+ * @param out the reference
+ * @param out_type the type of branch (local or remote-tracking)
+ * @param iter the branch iterator
+ * @return 0 on success, GIT_ITEROVER if there are no more branches or an error code.
+ */
+GIT_EXTERN(int) git_branch_next(git_reference **out, git_branch_t *out_type, git_branch_iterator *iter);
+
+/**
+ * Free a branch iterator
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_branch_iterator_free(git_branch_iterator *iter);
+
+/**
+ * Move/rename an existing local branch reference.
+ *
+ * The new branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * Note that if the move succeeds, the old reference object will not
+ * be valid anymore, and should be freed immediately by the user using
+ * `git_reference_free()`.
+ *
+ * @param out New reference object for the updated name.
+ *
+ * @param branch Current underlying reference of the branch.
+ *
+ * @param new_branch_name Target name of the branch once the move
+ * is performed; this name is validated for consistency.
+ *
+ * @param force Overwrite existing branch.
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_branch_move(
+ git_reference **out,
+ git_reference *branch,
+ const char *new_branch_name,
+ int force);
+
+/**
+ * Lookup a branch by its name in a repository.
+ *
+ * The generated reference must be freed by the user.
+ * The branch name will be checked for validity.
+ *
+ * @see git_tag_create for rules about valid names.
+ *
+ * @param out pointer to the looked-up branch reference
+ * @param repo the repository to look up the branch
+ * @param branch_name Name of the branch to be looked-up;
+ * this name is validated for consistency.
+ * @param branch_type Type of the considered branch. This should
+ * be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
+ *
+ * @return 0 on success; GIT_ENOTFOUND when no matching branch
+ * exists, GIT_EINVALIDSPEC, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_lookup(
+ git_reference **out,
+ git_repository *repo,
+ const char *branch_name,
+ git_branch_t branch_type);
+
+/**
+ * Get the branch name
+ *
+ * Given a reference object, this will check that it really is a branch (ie.
+ * it lives under "refs/heads/" or "refs/remotes/"), and return the branch part
+ * of it.
+ *
+ * @param out Pointer to the abbreviated reference name.
+ * Owned by ref, do not free.
+ *
+ * @param ref A reference object, ideally pointing to a branch
+ *
+ * @return 0 on success; GIT_EINVALID if the reference isn't either a local or
+ * remote branch, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_name(
+ const char **out,
+ const git_reference *ref);
+
+/**
+ * Get the upstream of a branch
+ *
+ * Given a reference, this will return a new reference object corresponding
+ * to its remote tracking branch. The reference must be a local branch.
+ *
+ * @see git_branch_upstream_name for details on the resolution.
+ *
+ * @param out Pointer where to store the retrieved reference.
+ * @param branch Current underlying reference of the branch.
+ *
+ * @return 0 on success; GIT_ENOTFOUND when no remote tracking
+ * reference exists, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_upstream(
+ git_reference **out,
+ const git_reference *branch);
+
+/**
+ * Set a branch's upstream branch
+ *
+ * This will update the configuration to set the branch named `branch_name` as the upstream of `branch`.
+ * Pass a NULL name to unset the upstream information.
+ *
+ * @note the actual tracking reference must have been already created for the
+ * operation to succeed.
+ *
+ * @param branch the branch to configure
+ * @param branch_name remote-tracking or local branch to set as upstream.
+ *
+ * @return 0 on success; GIT_ENOTFOUND if there's no branch named `branch_name`
+ * or an error code
+ */
+GIT_EXTERN(int) git_branch_set_upstream(
+ git_reference *branch,
+ const char *branch_name);
+
+/**
+ * Get the upstream name of a branch
+ *
+ * Given a local branch, this will return its remote-tracking branch information,
+ * as a full reference name, ie. "feature/nice" would become
+ * "refs/remote/origin/feature/nice", depending on that branch's configuration.
+ *
+ * @param out the buffer into which the name will be written.
+ * @param repo the repository where the branches live.
+ * @param refname reference name of the local branch.
+ *
+ * @return 0 on success, GIT_ENOTFOUND when no remote tracking reference exists,
+ * or an error code.
+ */
+GIT_EXTERN(int) git_branch_upstream_name(
+ git_buf *out,
+ git_repository *repo,
+ const char *refname);
+
+/**
+ * Determine if HEAD points to the given branch
+ *
+ * @param branch A reference to a local branch.
+ *
+ * @return 1 if HEAD points at the branch, 0 if it isn't, or a negative value
+ * as an error code.
+ */
+GIT_EXTERN(int) git_branch_is_head(
+ const git_reference *branch);
+
+/**
+ * Determine if any HEAD points to the current branch
+ *
+ * This will iterate over all known linked repositories (usually in the form of
+ * worktrees) and report whether any HEAD is pointing at the current branch.
+ *
+ * @param branch A reference to a local branch.
+ *
+ * @return 1 if branch is checked out, 0 if it isn't, an error code otherwise.
+ */
+GIT_EXTERN(int) git_branch_is_checked_out(
+ const git_reference *branch);
+
+/**
+ * Find the remote name of a remote-tracking branch
+ *
+ * This will return the name of the remote whose fetch refspec is matching
+ * the given branch. E.g. given a branch "refs/remotes/test/master", it will
+ * extract the "test" part. If refspecs from multiple remotes match,
+ * the function will return GIT_EAMBIGUOUS.
+ *
+ * @param out The buffer into which the name will be written.
+ * @param repo The repository where the branch lives.
+ * @param refname complete name of the remote tracking branch.
+ *
+ * @return 0 on success, GIT_ENOTFOUND when no matching remote was found,
+ * GIT_EAMBIGUOUS when the branch maps to several remotes,
+ * otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_remote_name(
+ git_buf *out,
+ git_repository *repo,
+ const char *refname);
+
+/**
+ * Retrieve the upstream remote of a local branch
+ *
+ * This will return the currently configured "branch.*.remote" for a given
+ * branch. This branch must be local.
+ *
+ * @param buf the buffer into which to write the name
+ * @param repo the repository in which to look
+ * @param refname the full name of the branch
+ * @return 0 or an error code
+ */
+ GIT_EXTERN(int) git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname);
+
+/**
+ * Retrieve the upstream merge of a local branch
+ *
+ * This will return the currently configured "branch.*.merge" for a given
+ * branch. This branch must be local.
+ *
+ * @param buf the buffer into which to write the name
+ * @param repo the repository in which to look
+ * @param refname the full name of the branch
+ * @return 0 or an error code
+ */
+ GIT_EXTERN(int) git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname);
+
+/**
+ * Determine whether a branch name is valid, meaning that (when prefixed
+ * with `refs/heads/`) that it is a valid reference name, and that any
+ * additional branch name restrictions are imposed (eg, it cannot start
+ * with a `-`).
+ *
+ * @param valid output pointer to set with validity of given branch name
+ * @param name a branch name to test
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_branch_name_is_valid(int *valid, const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/buffer.h b/include/git2/buffer.h
new file mode 100644
index 0000000..9fa9720
--- /dev/null
+++ b/include/git2/buffer.h
@@ -0,0 +1,74 @@
+/*
+ * 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_buf_h__
+#define INCLUDE_git_buf_h__
+
+#include "common.h"
+
+/**
+ * @file git2/buffer.h
+ * @brief Buffer export structure
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * A data buffer for exporting data from libgit2
+ *
+ * Sometimes libgit2 wants to return an allocated data buffer to the
+ * caller and have the caller take responsibility for freeing that memory.
+ * To make ownership clear in these cases, libgit2 uses `git_buf` to
+ * return this data. Callers should use `git_buf_dispose()` to release
+ * the memory when they are done.
+ *
+ * A `git_buf` contains a pointer to a NUL-terminated C string, and
+ * the length of the string (not including the NUL terminator).
+ */
+typedef struct {
+ /**
+ * The buffer contents. `ptr` points to the start of the buffer
+ * being returned. The buffer's length (in bytes) is specified
+ * by the `size` member of the structure, and contains a NUL
+ * terminator at position `(size + 1)`.
+ */
+ char *ptr;
+
+ /**
+ * This field is reserved and unused.
+ */
+ size_t reserved;
+
+ /**
+ * The length (in bytes) of the buffer pointed to by `ptr`,
+ * not including a NUL terminator.
+ */
+ size_t size;
+} git_buf;
+
+/**
+ * Use to initialize a `git_buf` before passing it to a function that
+ * will populate it.
+ */
+#define GIT_BUF_INIT { NULL, 0, 0 }
+
+/**
+ * Free the memory referred to by the git_buf.
+ *
+ * Note that this does not free the `git_buf` itself, just the memory
+ * pointed to by `buffer->ptr`.
+ *
+ * @param buffer The buffer to deallocate
+ */
+GIT_EXTERN(void) git_buf_dispose(git_buf *buffer);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/cert.h b/include/git2/cert.h
new file mode 100644
index 0000000..05213a5
--- /dev/null
+++ b/include/git2/cert.h
@@ -0,0 +1,172 @@
+/*
+ * 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_cert_h__
+#define INCLUDE_git_cert_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/cert.h
+ * @brief Git certificate objects
+ * @defgroup git_cert Certificate objects
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Type of host certificate structure that is passed to the check callback
+ */
+typedef enum git_cert_t {
+ /**
+ * No information about the certificate is available. This may
+ * happen when using curl.
+ */
+ GIT_CERT_NONE,
+ /**
+ * The `data` argument to the callback will be a pointer to
+ * the DER-encoded data.
+ */
+ GIT_CERT_X509,
+ /**
+ * The `data` argument to the callback will be a pointer to a
+ * `git_cert_hostkey` structure.
+ */
+ GIT_CERT_HOSTKEY_LIBSSH2,
+ /**
+ * The `data` argument to the callback will be a pointer to a
+ * `git_strarray` with `name:content` strings containing
+ * information about the certificate. This is used when using
+ * curl.
+ */
+ GIT_CERT_STRARRAY
+} git_cert_t;
+
+/**
+ * Parent type for `git_cert_hostkey` and `git_cert_x509`.
+ */
+struct git_cert {
+ /**
+ * Type of certificate. A `GIT_CERT_` value.
+ */
+ git_cert_t cert_type;
+};
+
+/**
+ * Callback for the user's custom certificate checks.
+ *
+ * @param cert The host certificate
+ * @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
+ * this certificate is valid
+ * @param host Hostname of the host libgit2 connected to
+ * @param payload Payload provided by the caller
+ * @return 0 to proceed with the connection, < 0 to fail the connection
+ * or > 0 to indicate that the callback refused to act and that
+ * the existing validity determination should be honored
+ */
+typedef int GIT_CALLBACK(git_transport_certificate_check_cb)(git_cert *cert, int valid, const char *host, void *payload);
+
+/**
+ * Type of SSH host fingerprint
+ */
+typedef enum {
+ /** MD5 is available */
+ GIT_CERT_SSH_MD5 = (1 << 0),
+ /** SHA-1 is available */
+ GIT_CERT_SSH_SHA1 = (1 << 1),
+ /** SHA-256 is available */
+ GIT_CERT_SSH_SHA256 = (1 << 2),
+ /** Raw hostkey is available */
+ GIT_CERT_SSH_RAW = (1 << 3)
+} git_cert_ssh_t;
+
+typedef enum {
+ /** The raw key is of an unknown type. */
+ GIT_CERT_SSH_RAW_TYPE_UNKNOWN = 0,
+ /** The raw key is an RSA key. */
+ GIT_CERT_SSH_RAW_TYPE_RSA = 1,
+ /** The raw key is a DSS key. */
+ GIT_CERT_SSH_RAW_TYPE_DSS = 2,
+ /** The raw key is a ECDSA 256 key. */
+ GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 = 3,
+ /** The raw key is a ECDSA 384 key. */
+ GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 = 4,
+ /** The raw key is a ECDSA 521 key. */
+ GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 = 5,
+ /** The raw key is a ED25519 key. */
+ GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 = 6
+} git_cert_ssh_raw_type_t;
+
+/**
+ * Hostkey information taken from libssh2
+ */
+typedef struct {
+ git_cert parent; /**< The parent cert */
+
+ /**
+ * A bitmask containing the available fields.
+ */
+ git_cert_ssh_t type;
+
+ /**
+ * Hostkey hash. If `type` has `GIT_CERT_SSH_MD5` set, this will
+ * have the MD5 hash of the hostkey.
+ */
+ unsigned char hash_md5[16];
+
+ /**
+ * Hostkey hash. If `type` has `GIT_CERT_SSH_SHA1` set, this will
+ * have the SHA-1 hash of the hostkey.
+ */
+ unsigned char hash_sha1[20];
+
+ /**
+ * Hostkey hash. If `type` has `GIT_CERT_SSH_SHA256` set, this will
+ * have the SHA-256 hash of the hostkey.
+ */
+ unsigned char hash_sha256[32];
+
+ /**
+ * Raw hostkey type. If `type` has `GIT_CERT_SSH_RAW` set, this will
+ * have the type of the raw hostkey.
+ */
+ git_cert_ssh_raw_type_t raw_type;
+
+ /**
+ * Pointer to the raw hostkey. If `type` has `GIT_CERT_SSH_RAW` set,
+ * this will have the raw contents of the hostkey.
+ */
+ const char *hostkey;
+
+ /**
+ * Raw hostkey length. If `type` has `GIT_CERT_SSH_RAW` set, this will
+ * have the length of the raw contents of the hostkey.
+ */
+ size_t hostkey_len;
+} git_cert_hostkey;
+
+/**
+ * X.509 certificate information
+ */
+typedef struct {
+ git_cert parent; /**< The parent cert */
+
+ /**
+ * Pointer to the X.509 certificate data
+ */
+ void *data;
+
+ /**
+ * Length of the memory block pointed to by `data`.
+ */
+ size_t len;
+} git_cert_x509;
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
new file mode 100644
index 0000000..9f83411
--- /dev/null
+++ b/include/git2/checkout.h
@@ -0,0 +1,417 @@
+/*
+ * 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_checkout_h__
+#define INCLUDE_git_checkout_h__
+
+#include "common.h"
+#include "types.h"
+#include "diff.h"
+
+/**
+ * @file git2/checkout.h
+ * @brief Git checkout routines
+ * @defgroup git_checkout Git checkout routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Checkout behavior flags
+ *
+ * In libgit2, checkout is used to update the working directory and index
+ * to match a target tree. Unlike git checkout, it does not move the HEAD
+ * commit for you - use `git_repository_set_head` or the like to do that.
+ *
+ * Checkout looks at (up to) four things: the "target" tree you want to
+ * check out, the "baseline" tree of what was checked out previously, the
+ * working directory for actual files, and the index for staged changes.
+ *
+ * You give checkout one of three strategies for update:
+ *
+ * - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts,
+ * etc., but doesn't make any actual changes.
+ *
+ * - `GIT_CHECKOUT_FORCE` is at the opposite extreme, taking any action to
+ * make the working directory match the target (including potentially
+ * discarding modified files).
+ *
+ * - `GIT_CHECKOUT_SAFE` is between these two options, it will only make
+ * modifications that will not lose changes.
+ *
+ * | target == baseline | target != baseline |
+ * ---------------------|-----------------------|----------------------|
+ * workdir == baseline | no action | create, update, or |
+ * | | delete file |
+ * ---------------------|-----------------------|----------------------|
+ * workdir exists and | no action | conflict (notify |
+ * is != baseline | notify dirty MODIFIED | and cancel checkout) |
+ * ---------------------|-----------------------|----------------------|
+ * workdir missing, | notify dirty DELETED | create file |
+ * baseline present | | |
+ * ---------------------|-----------------------|----------------------|
+ *
+ * To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout
+ * notification callback (see below) that displays information about dirty
+ * files. The default behavior will cancel checkout on conflicts.
+ *
+ * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE` with a
+ * notification callback that cancels the operation if a dirty-but-existing
+ * file is found in the working directory. This core git command isn't
+ * quite "force" but is sensitive about some types of changes.
+ *
+ * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`.
+ *
+ *
+ * There are some additional flags to modify the behavior of checkout:
+ *
+ * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates
+ * even if there are conflicts (instead of cancelling the checkout).
+ *
+ * - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not
+ * in target, baseline, or index, and not ignored) from the working dir.
+ *
+ * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also
+ * untracked) from the working directory as well.
+ *
+ * - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that
+ * already exist. Files will not be created nor deleted. This just skips
+ * applying adds, deletes, and typechanges.
+ *
+ * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the
+ * updated files' information to the index.
+ *
+ * - Normally, checkout will reload the index and git attributes from disk
+ * before any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload.
+ *
+ * - Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips
+ * files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and
+ * GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the
+ * stage 2 ("ours") or stage 3 ("theirs") version of files in the index.
+ *
+ * - GIT_CHECKOUT_DONT_OVERWRITE_IGNORED prevents ignored files from being
+ * overwritten. Normally, files that are ignored in the working directory
+ * are not considered "precious" and may be overwritten if the checkout
+ * target contains that file.
+ *
+ * - GIT_CHECKOUT_DONT_REMOVE_EXISTING prevents checkout from removing
+ * files or folders that fold to the same name on case insensitive
+ * filesystems. This can cause files to retain their existing names
+ * and write through existing symbolic links.
+ */
+typedef enum {
+ GIT_CHECKOUT_NONE = 0, /**< default is a dry run, no actual updates */
+
+ /**
+ * Allow safe updates that cannot overwrite uncommitted data.
+ * If the uncommitted changes don't conflict with the checked out files,
+ * the checkout will still proceed, leaving the changes intact.
+ *
+ * Mutually exclusive with GIT_CHECKOUT_FORCE.
+ * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE.
+ */
+ GIT_CHECKOUT_SAFE = (1u << 0),
+
+ /**
+ * Allow all updates to force working directory to look like index.
+ *
+ * Mutually exclusive with GIT_CHECKOUT_SAFE.
+ * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE.
+ */
+ GIT_CHECKOUT_FORCE = (1u << 1),
+
+
+ /** Allow checkout to recreate missing files */
+ GIT_CHECKOUT_RECREATE_MISSING = (1u << 2),
+
+ /** Allow checkout to make safe updates even if conflicts are found */
+ GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4),
+
+ /** Remove untracked files not in index (that are not ignored) */
+ GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5),
+
+ /** Remove ignored files not in index */
+ GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6),
+
+ /** Only update existing files, don't create new ones */
+ GIT_CHECKOUT_UPDATE_ONLY = (1u << 7),
+
+ /**
+ * Normally checkout updates index entries as it goes; this stops that.
+ * Implies `GIT_CHECKOUT_DONT_WRITE_INDEX`.
+ */
+ GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
+
+ /** Don't refresh index/config/etc before doing checkout */
+ GIT_CHECKOUT_NO_REFRESH = (1u << 9),
+
+ /** Allow checkout to skip unmerged files */
+ GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
+ /** For unmerged files, checkout stage 2 from index */
+ GIT_CHECKOUT_USE_OURS = (1u << 11),
+ /** For unmerged files, checkout stage 3 from index */
+ GIT_CHECKOUT_USE_THEIRS = (1u << 12),
+
+ /** Treat pathspec as simple list of exact match file paths */
+ GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
+
+ /** Ignore directories in use, they will be left empty */
+ GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
+
+ /** Don't overwrite ignored files that exist in the checkout target */
+ GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19),
+
+ /** Write normal merge files for conflicts */
+ GIT_CHECKOUT_CONFLICT_STYLE_MERGE = (1u << 20),
+
+ /** Include common ancestor data in diff3 format files for conflicts */
+ GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 = (1u << 21),
+
+ /** Don't overwrite existing files or folders */
+ GIT_CHECKOUT_DONT_REMOVE_EXISTING = (1u << 22),
+
+ /** Normally checkout writes the index upon completion; this prevents that. */
+ GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
+
+ /**
+ * Show what would be done by a checkout. Stop after sending
+ * notifications; don't update the working directory or index.
+ */
+ GIT_CHECKOUT_DRY_RUN = (1u << 24),
+
+ /** Include common ancestor data in zdiff3 format for conflicts */
+ GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3 = (1u << 25),
+
+ /**
+ * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
+ */
+
+ /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
+ GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
+ /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
+ GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17)
+
+} git_checkout_strategy_t;
+
+/**
+ * Checkout notification flags
+ *
+ * Checkout will invoke an options notification callback (`notify_cb`) for
+ * certain cases - you pick which ones via `notify_flags`:
+ *
+ * Returning a non-zero value from this callback will cancel the checkout.
+ * The non-zero return value will be propagated back and returned by the
+ * git_checkout_... call.
+ *
+ * Notification callbacks are made prior to modifying any files on disk,
+ * so canceling on any notification will still happen prior to any files
+ * being modified.
+ */
+typedef enum {
+ GIT_CHECKOUT_NOTIFY_NONE = 0,
+
+ /**
+ * Invokes checkout on conflicting paths.
+ */
+ GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0),
+
+ /**
+ * Notifies about "dirty" files, i.e. those that do not need an update
+ * but no longer match the baseline. Core git displays these files when
+ * checkout runs, but won't stop the checkout.
+ */
+ GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1),
+
+ /**
+ * Sends notification for any file changed.
+ */
+ GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2),
+
+ /**
+ * Notifies about untracked files.
+ */
+ GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
+
+ /**
+ * Notifies about ignored files.
+ */
+ GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4),
+
+ GIT_CHECKOUT_NOTIFY_ALL = 0x0FFFFu
+} git_checkout_notify_t;
+
+/** Checkout performance-reporting structure */
+typedef struct {
+ size_t mkdir_calls;
+ size_t stat_calls;
+ size_t chmod_calls;
+} git_checkout_perfdata;
+
+/** Checkout notification callback function */
+typedef int GIT_CALLBACK(git_checkout_notify_cb)(
+ git_checkout_notify_t why,
+ const char *path,
+ const git_diff_file *baseline,
+ const git_diff_file *target,
+ const git_diff_file *workdir,
+ void *payload);
+
+/** Checkout progress notification function */
+typedef void GIT_CALLBACK(git_checkout_progress_cb)(
+ const char *path,
+ size_t completed_steps,
+ size_t total_steps,
+ void *payload);
+
+/** Checkout perfdata notification function */
+typedef void GIT_CALLBACK(git_checkout_perfdata_cb)(
+ const git_checkout_perfdata *perfdata,
+ void *payload);
+
+/**
+ * Checkout options structure
+ *
+ * Initialize with `GIT_CHECKOUT_OPTIONS_INIT`. Alternatively, you can
+ * use `git_checkout_options_init`.
+ *
+ */
+typedef struct git_checkout_options {
+ unsigned int version; /**< The version */
+
+ unsigned int checkout_strategy; /**< default will be a safe checkout */
+
+ int disable_filters; /**< don't apply filters like CRLF conversion */
+ unsigned int dir_mode; /**< default is 0755 */
+ unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */
+ int file_open_flags; /**< default is O_CREAT | O_TRUNC | O_WRONLY */
+
+ unsigned int notify_flags; /**< see `git_checkout_notify_t` above */
+
+ /**
+ * Optional callback to get notifications on specific file states.
+ * @see git_checkout_notify_t
+ */
+ git_checkout_notify_cb notify_cb;
+
+ /** Payload passed to notify_cb */
+ void *notify_payload;
+
+ /** Optional callback to notify the consumer of checkout progress. */
+ git_checkout_progress_cb progress_cb;
+
+ /** Payload passed to progress_cb */
+ void *progress_payload;
+
+ /**
+ * A list of wildmatch patterns or paths.
+ *
+ * By default, all paths are processed. If you pass an array of wildmatch
+ * patterns, those will be used to filter which paths should be taken into
+ * account.
+ *
+ * Use GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as a simple list.
+ */
+ git_strarray paths;
+
+ /**
+ * The expected content of the working directory; defaults to HEAD.
+ *
+ * If the working directory does not match this baseline information,
+ * that will produce a checkout conflict.
+ */
+ git_tree *baseline;
+
+ /**
+ * Like `baseline` above, though expressed as an index. This
+ * option overrides `baseline`.
+ */
+ git_index *baseline_index;
+
+ const char *target_directory; /**< alternative checkout path to workdir */
+
+ const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
+ const char *our_label; /**< the name of the "our" side of conflicts */
+ const char *their_label; /**< the name of the "their" side of conflicts */
+
+ /** Optional callback to notify the consumer of performance data. */
+ git_checkout_perfdata_cb perfdata_cb;
+
+ /** Payload passed to perfdata_cb */
+ void *perfdata_payload;
+} git_checkout_options;
+
+#define GIT_CHECKOUT_OPTIONS_VERSION 1
+#define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE}
+
+/**
+ * Initialize git_checkout_options structure
+ *
+ * Initializes a `git_checkout_options` with default values. Equivalent to creating
+ * an instance with GIT_CHECKOUT_OPTIONS_INIT.
+ *
+ * @param opts The `git_checkout_options` struct to initialize.
+ * @param version The struct version; pass `GIT_CHECKOUT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_checkout_options_init(
+ git_checkout_options *opts,
+ unsigned int version);
+
+/**
+ * Updates files in the index and the working tree to match the content of
+ * the commit pointed at by HEAD.
+ *
+ * Note that this is _not_ the correct mechanism used to switch branches;
+ * do not change your `HEAD` and then call this method, that would leave
+ * you with checkout conflicts since your working directory would then
+ * appear to be dirty. Instead, checkout the target of the branch and
+ * then update `HEAD` using `git_repository_set_head` to point to the
+ * branch you checked out.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non
+ * existing branch, non-zero value returned by `notify_cb`, or
+ * other error code < 0 (use git_error_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_head(
+ git_repository *repo,
+ const git_checkout_options *opts);
+
+/**
+ * Updates files in the working tree to match the content of the index.
+ *
+ * @param repo repository into which to check out (must be non-bare)
+ * @param index index to be checked out (or NULL to use repository index)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ * code < 0 (use git_error_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_index(
+ git_repository *repo,
+ git_index *index,
+ const git_checkout_options *opts);
+
+/**
+ * Updates files in the index and working tree to match the content of the
+ * tree pointed at by the treeish.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param treeish a commit, tag or tree which content will be used to update
+ * the working directory (or NULL to use HEAD)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ * code < 0 (use git_error_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_tree(
+ git_repository *repo,
+ const git_object *treeish,
+ const git_checkout_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/cherrypick.h b/include/git2/cherrypick.h
new file mode 100644
index 0000000..0e6a252
--- /dev/null
+++ b/include/git2/cherrypick.h
@@ -0,0 +1,92 @@
+/*
+ * 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_cherrypick_h__
+#define INCLUDE_git_cherrypick_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/cherrypick.h
+ * @brief Git cherry-pick routines
+ * @defgroup git_cherrypick Git cherry-pick routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Cherry-pick options
+ */
+typedef struct {
+ unsigned int version;
+
+ /** For merge commits, the "mainline" is treated as the parent. */
+ unsigned int mainline;
+
+ git_merge_options merge_opts; /**< Options for the merging */
+ git_checkout_options checkout_opts; /**< Options for the checkout */
+} git_cherrypick_options;
+
+#define GIT_CHERRYPICK_OPTIONS_VERSION 1
+#define GIT_CHERRYPICK_OPTIONS_INIT {GIT_CHERRYPICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initialize git_cherrypick_options structure
+ *
+ * Initializes a `git_cherrypick_options` with default values. Equivalent to creating
+ * an instance with GIT_CHERRYPICK_OPTIONS_INIT.
+ *
+ * @param opts The `git_cherrypick_options` struct to initialize.
+ * @param version The struct version; pass `GIT_CHERRYPICK_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick_options_init(
+ git_cherrypick_options *opts,
+ unsigned int version);
+
+/**
+ * Cherry-picks the given commit against the given "our" commit, producing an
+ * index that reflects the result of the cherry-pick.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param cherrypick_commit the commit to cherry-pick
+ * @param our_commit the commit to cherry-pick against (eg, HEAD)
+ * @param mainline the parent of the `cherrypick_commit`, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *cherrypick_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_options);
+
+/**
+ * Cherry-pick the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to cherry-pick
+ * @param commit the commit to cherry-pick
+ * @param cherrypick_options the cherry-pick options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick(
+ git_repository *repo,
+ git_commit *commit,
+ const git_cherrypick_options *cherrypick_options);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/clone.h b/include/git2/clone.h
new file mode 100644
index 0000000..3481f25
--- /dev/null
+++ b/include/git2/clone.h
@@ -0,0 +1,209 @@
+/*
+ * 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_clone_h__
+#define INCLUDE_git_clone_h__
+
+#include "common.h"
+#include "types.h"
+#include "indexer.h"
+#include "checkout.h"
+#include "remote.h"
+#include "transport.h"
+
+
+/**
+ * @file git2/clone.h
+ * @brief Git cloning routines
+ * @defgroup git_clone Git cloning routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Options for bypassing the git-aware transport on clone. Bypassing
+ * it means that instead of a fetch, libgit2 will copy the object
+ * database directory instead of figuring out what it needs, which is
+ * faster. If possible, it will hardlink the files to save space.
+ */
+typedef enum {
+ /**
+ * Auto-detect (default), libgit2 will bypass the git-aware
+ * transport for local paths, but use a normal fetch for
+ * `file://` urls.
+ */
+ GIT_CLONE_LOCAL_AUTO,
+ /**
+ * Bypass the git-aware transport even for a `file://` url.
+ */
+ GIT_CLONE_LOCAL,
+ /**
+ * Do no bypass the git-aware transport
+ */
+ GIT_CLONE_NO_LOCAL,
+ /**
+ * Bypass the git-aware transport, but do not try to use
+ * hardlinks.
+ */
+ GIT_CLONE_LOCAL_NO_LINKS
+} git_clone_local_t;
+
+/**
+ * The signature of a function matching git_remote_create, with an additional
+ * void* as a callback payload.
+ *
+ * Callers of git_clone may provide a function matching this signature to override
+ * the remote creation and customization process during a clone operation.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @param payload an opaque payload
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+typedef int GIT_CALLBACK(git_remote_create_cb)(
+ git_remote **out,
+ git_repository *repo,
+ const char *name,
+ const char *url,
+ void *payload);
+
+/**
+ * The signature of a function matching git_repository_init, with an
+ * additional void * as callback payload.
+ *
+ * Callers of git_clone my provide a function matching this signature
+ * to override the repository creation and customization process
+ * during a clone operation.
+ *
+ * @param out the resulting repository
+ * @param path path in which to create the repository
+ * @param bare whether the repository is bare. This is the value from the clone options
+ * @param payload payload specified by the options
+ * @return 0, or a negative value to indicate error
+ */
+typedef int GIT_CALLBACK(git_repository_create_cb)(
+ git_repository **out,
+ const char *path,
+ int bare,
+ void *payload);
+
+/**
+ * Clone options structure
+ *
+ * Initialize with `GIT_CLONE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_clone_options_init`.
+ *
+ */
+typedef struct git_clone_options {
+ unsigned int version;
+
+ /**
+ * These options are passed to the checkout step. To disable
+ * checkout, set the `checkout_strategy` to
+ * `GIT_CHECKOUT_NONE`.
+ */
+ git_checkout_options checkout_opts;
+
+ /**
+ * Options which control the fetch, including callbacks.
+ *
+ * The callbacks are used for reporting fetch progress, and for acquiring
+ * credentials in the event they are needed.
+ */
+ git_fetch_options fetch_opts;
+
+ /**
+ * Set to zero (false) to create a standard repo, or non-zero
+ * for a bare repo
+ */
+ int bare;
+
+ /**
+ * Whether to use a fetch or copy the object database.
+ */
+ git_clone_local_t local;
+
+ /**
+ * The name of the branch to checkout. NULL means use the
+ * remote's default branch.
+ */
+ const char *checkout_branch;
+
+ /**
+ * A callback used to create the new repository into which to
+ * clone. If NULL, the 'bare' field will be used to determine
+ * whether to create a bare repository.
+ */
+ git_repository_create_cb repository_cb;
+
+ /**
+ * An opaque payload to pass to the git_repository creation callback.
+ * This parameter is ignored unless repository_cb is non-NULL.
+ */
+ void *repository_cb_payload;
+
+ /**
+ * A callback used to create the git_remote, prior to its being
+ * used to perform the clone operation. See the documentation for
+ * git_remote_create_cb for details. This parameter may be NULL,
+ * indicating that git_clone should provide default behavior.
+ */
+ git_remote_create_cb remote_cb;
+
+ /**
+ * An opaque payload to pass to the git_remote creation callback.
+ * This parameter is ignored unless remote_cb is non-NULL.
+ */
+ void *remote_cb_payload;
+} git_clone_options;
+
+#define GIT_CLONE_OPTIONS_VERSION 1
+#define GIT_CLONE_OPTIONS_INIT { GIT_CLONE_OPTIONS_VERSION, \
+ { GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
+ GIT_FETCH_OPTIONS_INIT }
+
+/**
+ * Initialize git_clone_options structure
+ *
+ * Initializes a `git_clone_options` with default values. Equivalent to creating
+ * an instance with GIT_CLONE_OPTIONS_INIT.
+ *
+ * @param opts The `git_clone_options` struct to initialize.
+ * @param version The struct version; pass `GIT_CLONE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_clone_options_init(
+ git_clone_options *opts,
+ unsigned int version);
+
+/**
+ * Clone a remote repository.
+ *
+ * By default this creates its repository and initial remote to match
+ * git's defaults. You can use the options in the callback to
+ * customize how these are created.
+ *
+ * @param out pointer that will receive the resulting repository object
+ * @param url the remote repository to clone
+ * @param local_path local directory to clone to
+ * @param options configuration options for the clone. If NULL, the
+ * function works as though GIT_OPTIONS_INIT were passed.
+ * @return 0 on success, any non-zero return value from a callback
+ * function, or a negative value to indicate an error (use
+ * `git_error_last` for a detailed error message)
+ */
+GIT_EXTERN(int) git_clone(
+ git_repository **out,
+ const char *url,
+ const char *local_path,
+ const git_clone_options *options);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/commit.h b/include/git2/commit.h
new file mode 100644
index 0000000..67170cb
--- /dev/null
+++ b/include/git2/commit.h
@@ -0,0 +1,546 @@
+/*
+ * 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_commit_h__
+#define INCLUDE_git_commit_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+
+/**
+ * @file git2/commit.h
+ * @brief Git commit parsing, formatting routines
+ * @defgroup git_commit Git commit parsing, formatting routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a commit object from a repository.
+ *
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
+ *
+ * @param commit pointer to the looked up commit
+ * @param repo the repo to use when locating the commit.
+ * @param id identity of the commit to locate. If the object is
+ * an annotated tag it will be peeled back to the commit.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_lookup(
+ git_commit **commit, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a commit object from a repository, given a prefix of its
+ * identifier (short id).
+ *
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param commit pointer to the looked up commit
+ * @param repo the repo to use when locating the commit.
+ * @param id identity of the commit to locate. If the object is
+ * an annotated tag it will be peeled back to the commit.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_lookup_prefix(
+ git_commit **commit, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open commit
+ *
+ * This is a wrapper around git_object_free()
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop
+ * using a commit. Failure to do so will cause a memory leak.
+ *
+ * @param commit the commit to close
+ */
+
+GIT_EXTERN(void) git_commit_free(git_commit *commit);
+
+/**
+ * Get the id of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return object identity for the commit.
+ */
+GIT_EXTERN(const git_oid *) git_commit_id(const git_commit *commit);
+
+/**
+ * Get the repository that contains the commit.
+ *
+ * @param commit A previously loaded commit.
+ * @return Repository that contains this commit.
+ */
+GIT_EXTERN(git_repository *) git_commit_owner(const git_commit *commit);
+
+/**
+ * Get the encoding for the message of a commit,
+ * as a string representing a standard encoding name.
+ *
+ * The encoding may be NULL if the `encoding` header
+ * in the commit is missing; in that case UTF-8 is assumed.
+ *
+ * @param commit a previously loaded commit.
+ * @return NULL, or the encoding
+ */
+GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit);
+
+/**
+ * Get the full message of a commit.
+ *
+ * The returned message will be slightly prettified by removing any
+ * potential leading newlines.
+ *
+ * @param commit a previously loaded commit.
+ * @return the message of a commit
+ */
+GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
+
+/**
+ * Get the full raw message of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the raw message of a commit
+ */
+GIT_EXTERN(const char *) git_commit_message_raw(const git_commit *commit);
+
+/**
+ * Get the short "summary" of the git commit message.
+ *
+ * The returned message is the summary of the commit, comprising the
+ * first paragraph of the message with whitespace trimmed and squashed.
+ *
+ * @param commit a previously loaded commit.
+ * @return the summary of a commit or NULL on error
+ */
+GIT_EXTERN(const char *) git_commit_summary(git_commit *commit);
+
+/**
+ * Get the long "body" of the git commit message.
+ *
+ * The returned message is the body of the commit, comprising
+ * everything but the first paragraph of the message. Leading and
+ * trailing whitespaces are trimmed.
+ *
+ * @param commit a previously loaded commit.
+ * @return the body of a commit or NULL when no the message only
+ * consists of a summary
+ */
+GIT_EXTERN(const char *) git_commit_body(git_commit *commit);
+
+/**
+ * Get the commit time (i.e. committer time) of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the time of a commit
+ */
+GIT_EXTERN(git_time_t) git_commit_time(const git_commit *commit);
+
+/**
+ * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return positive or negative timezone offset, in minutes from UTC
+ */
+GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit);
+
+/**
+ * Get the committer of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the committer of a commit
+ */
+GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit);
+
+/**
+ * Get the author of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the author of a commit
+ */
+GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
+
+/**
+ * Get the committer of a commit, using the mailmap to map names and email
+ * addresses to canonical real names and email addresses.
+ *
+ * Call `git_signature_free` to free the signature.
+ *
+ * @param out a pointer to store the resolved signature.
+ * @param commit a previously loaded commit.
+ * @param mailmap the mailmap to resolve with. (may be NULL)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_committer_with_mailmap(
+ git_signature **out, const git_commit *commit, const git_mailmap *mailmap);
+
+/**
+ * Get the author of a commit, using the mailmap to map names and email
+ * addresses to canonical real names and email addresses.
+ *
+ * Call `git_signature_free` to free the signature.
+ *
+ * @param out a pointer to store the resolved signature.
+ * @param commit a previously loaded commit.
+ * @param mailmap the mailmap to resolve with. (may be NULL)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_author_with_mailmap(
+ git_signature **out, const git_commit *commit, const git_mailmap *mailmap);
+
+/**
+ * Get the full raw text of the commit header.
+ *
+ * @param commit a previously loaded commit
+ * @return the header text of the commit
+ */
+GIT_EXTERN(const char *) git_commit_raw_header(const git_commit *commit);
+
+/**
+ * Get the tree pointed to by a commit.
+ *
+ * @param tree_out pointer where to store the tree object
+ * @param commit a previously loaded commit.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, const git_commit *commit);
+
+/**
+ * Get the id of the tree pointed to by a commit. This differs from
+ * `git_commit_tree` in that no attempts are made to fetch an object
+ * from the ODB.
+ *
+ * @param commit a previously loaded commit.
+ * @return the id of tree pointed to by commit.
+ */
+GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit);
+
+/**
+ * Get the number of parents of this commit
+ *
+ * @param commit a previously loaded commit.
+ * @return integer of count of parents
+ */
+GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit);
+
+/**
+ * Get the specified parent of the commit.
+ *
+ * @param out Pointer where to store the parent commit
+ * @param commit a previously loaded commit.
+ * @param n the position of the parent (from 0 to `parentcount`)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_parent(
+ git_commit **out,
+ const git_commit *commit,
+ unsigned int n);
+
+/**
+ * Get the oid of a specified parent for a commit. This is different from
+ * `git_commit_parent`, which will attempt to load the parent commit from
+ * the ODB.
+ *
+ * @param commit a previously loaded commit.
+ * @param n the position of the parent (from 0 to `parentcount`)
+ * @return the id of the parent, NULL on error.
+ */
+GIT_EXTERN(const git_oid *) git_commit_parent_id(
+ const git_commit *commit,
+ unsigned int n);
+
+/**
+ * Get the commit object that is the <n>th generation ancestor
+ * of the named commit object, following only the first parents.
+ * The returned commit has to be freed by the caller.
+ *
+ * Passing `0` as the generation number returns another instance of the
+ * base commit itself.
+ *
+ * @param ancestor Pointer where to store the ancestor commit
+ * @param commit a previously loaded commit.
+ * @param n the requested generation
+ * @return 0 on success; GIT_ENOTFOUND if no matching ancestor exists
+ * or an error code
+ */
+GIT_EXTERN(int) git_commit_nth_gen_ancestor(
+ git_commit **ancestor,
+ const git_commit *commit,
+ unsigned int n);
+
+/**
+ * Get an arbitrary header field
+ *
+ * @param out the buffer to fill; existing content will be
+ * overwritten
+ * @param commit the commit to look in
+ * @param field the header field to return
+ * @return 0 on succeess, GIT_ENOTFOUND if the field does not exist,
+ * or an error code
+ */
+GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
+
+/**
+ * Extract the signature from a commit
+ *
+ * If the id is not for a commit, the error class will be
+ * `GIT_ERROR_INVALID`. If the commit does not have a signature, the
+ * error class will be `GIT_ERROR_OBJECT`.
+ *
+ * @param signature the signature block; existing content will be
+ * overwritten
+ * @param signed_data signed data; this is the commit contents minus the signature block;
+ * existing content will be overwritten
+ * @param repo the repository in which the commit exists
+ * @param commit_id the commit from which to extract the data
+ * @param field the name of the header field containing the signature
+ * block; pass `NULL` to extract the default 'gpgsig'
+ * @return 0 on success, GIT_ENOTFOUND if the id is not for a commit
+ * or the commit does not have a signature.
+ */
+GIT_EXTERN(int) git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field);
+
+/**
+ * Create new commit in the repository from a list of `git_object` pointers
+ *
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
+ *
+ * @param id Pointer in which to store the OID of the newly created commit
+ *
+ * @param repo Repository where to store the commit
+ *
+ * @param update_ref If not NULL, name of the reference that
+ * will be updated to point to this commit. If the reference
+ * is not direct, it will be resolved to a direct reference.
+ * Use "HEAD" to update the HEAD of the current branch and
+ * make it point to this commit. If the reference doesn't
+ * exist yet, it will be created. If it does exist, the first
+ * parent must be the tip of this branch.
+ *
+ * @param author Signature with author and author time of commit
+ *
+ * @param committer Signature with committer and * commit time of commit
+ *
+ * @param message_encoding The encoding for the message in the
+ * commit, represented with a standard encoding name.
+ * E.g. "UTF-8". If NULL, no encoding header is written and
+ * UTF-8 is assumed.
+ *
+ * @param message Full message for this commit
+ *
+ * @param tree An instance of a `git_tree` object that will
+ * be used as the tree for the commit. This tree object must
+ * also be owned by the given `repo`.
+ *
+ * @param parent_count Number of parents for this commit
+ *
+ * @param parents Array of `parent_count` pointers to `git_commit`
+ * objects that will be used as the parents for this commit. This
+ * array may be NULL if `parent_count` is 0 (root commit). All the
+ * given commits must be owned by the `repo`.
+ *
+ * @return 0 or an error code
+ * The created commit will be written to the Object Database and
+ * the given reference will be updated to point to it
+ */
+GIT_EXTERN(int) git_commit_create(
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ size_t parent_count,
+ const git_commit *parents[]);
+
+/**
+ * Create new commit in the repository using a variable argument list.
+ *
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
+ *
+ * The parents for the commit are specified as a variable list of pointers
+ * to `const git_commit *`. Note that this is a convenience method which may
+ * not be safe to export for certain languages or compilers
+ *
+ * All other parameters remain the same as `git_commit_create()`.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_v(
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ size_t parent_count,
+ ...);
+
+/**
+ * Amend an existing commit by replacing only non-NULL values.
+ *
+ * This creates a new commit that is exactly the same as the old commit,
+ * except that any non-NULL values will be updated. The new commit has
+ * the same parents as the old commit.
+ *
+ * The `update_ref` value works as in the regular `git_commit_create()`,
+ * updating the ref to point to the newly rewritten commit. If you want
+ * to amend a commit that is not currently the tip of the branch and then
+ * rewrite the following commits to reach a ref, pass this as NULL and
+ * update the rest of the commit chain and ref separately.
+ *
+ * Unlike `git_commit_create()`, the `author`, `committer`, `message`,
+ * `message_encoding`, and `tree` parameters can be NULL in which case this
+ * will use the values from the original `commit_to_amend`.
+ *
+ * All parameters have the same meanings as in `git_commit_create()`.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_amend(
+ git_oid *id,
+ const git_commit *commit_to_amend,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree);
+
+/**
+ * Create a commit and write it into a buffer
+ *
+ * Create a commit as with `git_commit_create()` but instead of
+ * writing it to the objectdb, write the contents of the object into a
+ * buffer.
+ *
+ * @param out the buffer into which to write the commit object content
+ *
+ * @param repo Repository where the referenced tree and parents live
+ *
+ * @param author Signature with author and author time of commit
+ *
+ * @param committer Signature with committer and * commit time of commit
+ *
+ * @param message_encoding The encoding for the message in the
+ * commit, represented with a standard encoding name.
+ * E.g. "UTF-8". If NULL, no encoding header is written and
+ * UTF-8 is assumed.
+ *
+ * @param message Full message for this commit
+ *
+ * @param tree An instance of a `git_tree` object that will
+ * be used as the tree for the commit. This tree object must
+ * also be owned by the given `repo`.
+ *
+ * @param parent_count Number of parents for this commit
+ *
+ * @param parents Array of `parent_count` pointers to `git_commit`
+ * objects that will be used as the parents for this commit. This
+ * array may be NULL if `parent_count` is 0 (root commit). All the
+ * given commits must be owned by the `repo`.
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_create_buffer(
+ git_buf *out,
+ git_repository *repo,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ size_t parent_count,
+ const git_commit *parents[]);
+
+/**
+ * Create a commit object from the given buffer and signature
+ *
+ * Given the unsigned commit object's contents, its signature and the
+ * header field in which to store the signature, attach the signature
+ * to the commit and write it into the given repository.
+ *
+ * @param out the resulting commit id
+ * @param repo the repository to create the commit in.
+ * @param commit_content the content of the unsigned commit object
+ * @param signature the signature to add to the commit. Leave `NULL`
+ * to create a commit without adding a signature field.
+ * @param signature_field which header field should contain this
+ * signature. Leave `NULL` for the default of "gpgsig"
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_create_with_signature(
+ git_oid *out,
+ git_repository *repo,
+ const char *commit_content,
+ const char *signature,
+ const char *signature_field);
+
+/**
+ * Create an in-memory copy of a commit. The copy must be explicitly
+ * free'd or it will leak.
+ *
+ * @param out Pointer to store the copy of the commit
+ * @param source Original commit to copy
+ * @return 0
+ */
+GIT_EXTERN(int) git_commit_dup(git_commit **out, git_commit *source);
+
+/**
+ * Commit creation callback: used when a function is going to create
+ * commits (for example, in `git_rebase_commit`) to allow callers to
+ * override the commit creation behavior. For example, users may
+ * wish to sign commits by providing this information to
+ * `git_commit_create_buffer`, signing that buffer, then calling
+ * `git_commit_create_with_signature`. The resultant commit id
+ * should be set in the `out` object id parameter.
+ *
+ * @param out pointer that this callback will populate with the object
+ * id of the commit that is created
+ * @param author the author name and time of the commit
+ * @param committer the committer name and time of the commit
+ * @param message_encoding the encoding of the given message, or NULL
+ * to assume UTF8
+ * @param message the commit message
+ * @param tree the tree to be committed
+ * @param parent_count the number of parents for this commit
+ * @param parents the commit parents
+ * @param payload the payload pointer in the rebase options
+ * @return 0 if this callback has created the commit and populated the out
+ * parameter, GIT_PASSTHROUGH if the callback has not created a
+ * commit and wants the calling function to create the commit as
+ * if no callback had been specified, any other value to stop
+ * and return a failure
+ */
+typedef int (*git_commit_create_cb)(
+ git_oid *out,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ size_t parent_count,
+ const git_commit *parents[],
+ void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/common.h b/include/git2/common.h
new file mode 100644
index 0000000..ab6bc13
--- /dev/null
+++ b/include/git2/common.h
@@ -0,0 +1,517 @@
+/*
+ * 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_common_h__
+#define INCLUDE_git_common_h__
+
+#include <time.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+# define GIT_BEGIN_DECL extern "C" {
+# define GIT_END_DECL }
+#else
+ /** Start declarations in C mode */
+# define GIT_BEGIN_DECL /* empty */
+ /** End declarations in C mode */
+# define GIT_END_DECL /* empty */
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1800
+# include <stdint.h>
+#elif !defined(__CLANG_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#ifdef DOCURIUM
+/*
+ * This is so clang's doc parser acknowledges comments on functions
+ * with size_t parameters.
+ */
+typedef size_t size_t;
+#endif
+
+/** Declare a public function exported for application use. */
+#if __GNUC__ >= 4
+# define GIT_EXTERN(type) extern \
+ __attribute__((visibility("default"))) \
+ type
+#elif defined(_MSC_VER)
+# define GIT_EXTERN(type) __declspec(dllexport) type __cdecl
+#else
+# define GIT_EXTERN(type) extern type
+#endif
+
+/** Declare a callback function for application use. */
+#if defined(_MSC_VER)
+# define GIT_CALLBACK(name) (__cdecl *name)
+#else
+# define GIT_CALLBACK(name) (*name)
+#endif
+
+/** Declare a function as deprecated. */
+#if defined(__GNUC__)
+# define GIT_DEPRECATED(func) \
+ __attribute__((deprecated)) \
+ __attribute__((used)) \
+ func
+#elif defined(_MSC_VER)
+# define GIT_DEPRECATED(func) __declspec(deprecated) func
+#else
+# define GIT_DEPRECATED(func) func
+#endif
+
+/** Declare a function's takes printf style arguments. */
+#ifdef __GNUC__
+# define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b)))
+#else
+# define GIT_FORMAT_PRINTF(a,b) /* empty */
+#endif
+
+#if (defined(_WIN32)) && !defined(__CYGWIN__)
+#define GIT_WIN32 1
+#endif
+
+#ifdef __amigaos4__
+#include <netinet/in.h>
+#endif
+
+/**
+ * @file git2/common.h
+ * @brief Git common platform definitions
+ * @defgroup git_common Git common platform definitions
+ * @ingroup Git
+ * @{
+ */
+
+GIT_BEGIN_DECL
+
+/**
+ * The separator used in path list strings (ie like in the PATH
+ * environment variable). A semi-colon ";" is used on Windows and
+ * AmigaOS, and a colon ":" for all other systems.
+ */
+#if defined(GIT_WIN32) || defined(AMIGA)
+#define GIT_PATH_LIST_SEPARATOR ';'
+#else
+#define GIT_PATH_LIST_SEPARATOR ':'
+#endif
+
+/**
+ * The maximum length of a valid git path.
+ */
+#define GIT_PATH_MAX 4096
+
+/**
+ * Return the version of the libgit2 library
+ * being currently used.
+ *
+ * @param major Store the major version number
+ * @param minor Store the minor version number
+ * @param rev Store the revision (patch) number
+ * @return 0 on success or an error code on failure
+ */
+GIT_EXTERN(int) git_libgit2_version(int *major, int *minor, int *rev);
+
+/**
+ * Return the prerelease state of the libgit2 library currently being
+ * used. For nightly builds during active development, this will be
+ * "alpha". Releases may have a "beta" or release candidate ("rc1",
+ * "rc2", etc) prerelease. For a final release, this function returns
+ * NULL.
+ *
+ * @return the name of the prerelease state or NULL
+ */
+GIT_EXTERN(const char *) git_libgit2_prerelease(void);
+
+/**
+ * Combinations of these values describe the features with which libgit2
+ * was compiled
+ */
+typedef enum {
+ /**
+ * If set, libgit2 was built thread-aware and can be safely used from multiple
+ * threads.
+ */
+ GIT_FEATURE_THREADS = (1 << 0),
+ /**
+ * If set, libgit2 was built with and linked against a TLS implementation.
+ * Custom TLS streams may still be added by the user to support HTTPS
+ * regardless of this.
+ */
+ GIT_FEATURE_HTTPS = (1 << 1),
+ /**
+ * If set, libgit2 was built with and linked against libssh2. A custom
+ * transport may still be added by the user to support libssh2 regardless of
+ * this.
+ */
+ GIT_FEATURE_SSH = (1 << 2),
+ /**
+ * If set, libgit2 was built with support for sub-second resolution in file
+ * modification times.
+ */
+ GIT_FEATURE_NSEC = (1 << 3)
+} git_feature_t;
+
+/**
+ * Query compile time options for libgit2.
+ *
+ * @return A combination of GIT_FEATURE_* values.
+ *
+ * - GIT_FEATURE_THREADS
+ * Libgit2 was compiled with thread support. Note that thread support is
+ * still to be seen as a 'work in progress' - basic object lookups are
+ * believed to be threadsafe, but other operations may not be.
+ *
+ * - GIT_FEATURE_HTTPS
+ * Libgit2 supports the https:// protocol. This requires the openssl
+ * library to be found when compiling libgit2.
+ *
+ * - GIT_FEATURE_SSH
+ * Libgit2 supports the SSH protocol for network operations. This requires
+ * the libssh2 library to be found when compiling libgit2
+ *
+ * - GIT_FEATURE_NSEC
+ * Libgit2 supports the sub-second resolution in file modification times.
+ */
+GIT_EXTERN(int) git_libgit2_features(void);
+
+/**
+ * Global library options
+ *
+ * These are used to select which global option to set or get and are
+ * used in `git_libgit2_opts()`.
+ */
+typedef enum {
+ GIT_OPT_GET_MWINDOW_SIZE,
+ GIT_OPT_SET_MWINDOW_SIZE,
+ GIT_OPT_GET_MWINDOW_MAPPED_LIMIT,
+ GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
+ GIT_OPT_GET_SEARCH_PATH,
+ GIT_OPT_SET_SEARCH_PATH,
+ GIT_OPT_SET_CACHE_OBJECT_LIMIT,
+ GIT_OPT_SET_CACHE_MAX_SIZE,
+ GIT_OPT_ENABLE_CACHING,
+ GIT_OPT_GET_CACHED_MEMORY,
+ GIT_OPT_GET_TEMPLATE_PATH,
+ GIT_OPT_SET_TEMPLATE_PATH,
+ GIT_OPT_SET_SSL_CERT_LOCATIONS,
+ GIT_OPT_SET_USER_AGENT,
+ GIT_OPT_ENABLE_STRICT_OBJECT_CREATION,
+ GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION,
+ GIT_OPT_SET_SSL_CIPHERS,
+ GIT_OPT_GET_USER_AGENT,
+ GIT_OPT_ENABLE_OFS_DELTA,
+ GIT_OPT_ENABLE_FSYNC_GITDIR,
+ GIT_OPT_GET_WINDOWS_SHAREMODE,
+ GIT_OPT_SET_WINDOWS_SHAREMODE,
+ GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION,
+ GIT_OPT_SET_ALLOCATOR,
+ GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY,
+ GIT_OPT_GET_PACK_MAX_OBJECTS,
+ GIT_OPT_SET_PACK_MAX_OBJECTS,
+ GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS,
+ GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE,
+ GIT_OPT_GET_MWINDOW_FILE_LIMIT,
+ GIT_OPT_SET_MWINDOW_FILE_LIMIT,
+ GIT_OPT_SET_ODB_PACKED_PRIORITY,
+ GIT_OPT_SET_ODB_LOOSE_PRIORITY,
+ GIT_OPT_GET_EXTENSIONS,
+ GIT_OPT_SET_EXTENSIONS,
+ GIT_OPT_GET_OWNER_VALIDATION,
+ GIT_OPT_SET_OWNER_VALIDATION,
+ GIT_OPT_GET_HOMEDIR,
+ GIT_OPT_SET_HOMEDIR,
+ GIT_OPT_SET_SERVER_CONNECT_TIMEOUT,
+ GIT_OPT_GET_SERVER_CONNECT_TIMEOUT,
+ GIT_OPT_SET_SERVER_TIMEOUT,
+ GIT_OPT_GET_SERVER_TIMEOUT
+} git_libgit2_opt_t;
+
+/**
+ * Set or query a library global option
+ *
+ * Available options:
+ *
+ * * opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):
+ *
+ * > Get the maximum mmap window size
+ *
+ * * opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):
+ *
+ * > Set the maximum mmap window size
+ *
+ * * opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):
+ *
+ * > Get the maximum memory that will be mapped in total by the library
+ *
+ * * opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):
+ *
+ * > Set the maximum amount of memory that can be mapped at any time
+ * > by the library
+ *
+ * * opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT, size_t *):
+ *
+ * > Get the maximum number of files that will be mapped at any time by the
+ * > library
+ *
+ * * opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, size_t):
+ *
+ * > Set the maximum number of files that can be mapped at any time
+ * > by the library. The default (0) is unlimited.
+ *
+ * * opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)
+ *
+ * > Get the search path for a given level of config data. "level" must
+ * > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`,
+ * > `GIT_CONFIG_LEVEL_XDG`, or `GIT_CONFIG_LEVEL_PROGRAMDATA`.
+ * > The search path is written to the `out` buffer.
+ *
+ * * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
+ *
+ * > Set the search path for a level of config data. The search path
+ * > applied to shared attributes and ignore files, too.
+ * >
+ * > - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR.
+ * > Pass NULL to reset to the default (generally based on environment
+ * > variables). Use magic path `$PATH` to include the old value
+ * > of the path (if you want to prepend or append, for instance).
+ * >
+ * > - `level` must be `GIT_CONFIG_LEVEL_SYSTEM`,
+ * > `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or
+ * > `GIT_CONFIG_LEVEL_PROGRAMDATA`.
+ *
+ * * opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_object_t type, size_t size)
+ *
+ * > Set the maximum data size for the given type of object to be
+ * > considered eligible for caching in memory. Setting to value to
+ * > zero means that that type of object will not be cached.
+ * > Defaults to 0 for GIT_OBJECT_BLOB (i.e. won't cache blobs) and 4k
+ * > for GIT_OBJECT_COMMIT, GIT_OBJECT_TREE, and GIT_OBJECT_TAG.
+ *
+ * * opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes)
+ *
+ * > Set the maximum total data size that will be cached in memory
+ * > across all repositories before libgit2 starts evicting objects
+ * > from the cache. This is a soft limit, in that the library might
+ * > briefly exceed it, but will start aggressively evicting objects
+ * > from cache when that happens. The default cache size is 256MB.
+ *
+ * * opts(GIT_OPT_ENABLE_CACHING, int enabled)
+ *
+ * > Enable or disable caching completely.
+ * >
+ * > Because caches are repository-specific, disabling the cache
+ * > cannot immediately clear all cached objects, but each cache will
+ * > be cleared on the next attempt to update anything in it.
+ *
+ * * opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed)
+ *
+ * > Get the current bytes in cache and the maximum that would be
+ * > allowed in the cache.
+ *
+ * * opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)
+ *
+ * > Get the default template path.
+ * > The path is written to the `out` buffer.
+ *
+ * * opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)
+ *
+ * > Set the default template path.
+ * >
+ * > - `path` directory of template.
+ *
+ * * opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, const char *file, const char *path)
+ *
+ * > Set the SSL certificate-authority locations.
+ * >
+ * > - `file` is the location of a file containing several
+ * > certificates concatenated together.
+ * > - `path` is the location of a directory holding several
+ * > certificates, one per file.
+ * >
+ * > Either parameter may be `NULL`, but not both.
+ *
+ * * opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)
+ *
+ * > Set the value of the User-Agent header. This value will be
+ * > appended to "git/1.0", for compatibility with other git clients.
+ * >
+ * > - `user_agent` is the value that will be delivered as the
+ * > User-Agent header on HTTP requests.
+ *
+ * * opts(GIT_OPT_SET_WINDOWS_SHAREMODE, unsigned long value)
+ *
+ * > Set the share mode used when opening files on Windows.
+ * > For more information, see the documentation for CreateFile.
+ * > The default is: FILE_SHARE_READ | FILE_SHARE_WRITE. This is
+ * > ignored and unused on non-Windows platforms.
+ *
+ * * opts(GIT_OPT_GET_WINDOWS_SHAREMODE, unsigned long *value)
+ *
+ * > Get the share mode used when opening files on Windows.
+ *
+ * * opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled)
+ *
+ * > Enable strict input validation when creating new objects
+ * > to ensure that all inputs to the new objects are valid. For
+ * > example, when this is enabled, the parent(s) and tree inputs
+ * > will be validated when creating a new commit. This defaults
+ * > to enabled.
+ *
+ * * opts(GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION, int enabled)
+ *
+ * > Validate the target of a symbolic ref when creating it. For
+ * > example, `foobar` is not a valid ref, therefore `foobar` is
+ * > not a valid target for a symbolic ref by default, whereas
+ * > `refs/heads/foobar` is. Disabling this bypasses validation
+ * > so that an arbitrary strings such as `foobar` can be used
+ * > for a symbolic ref target. This defaults to enabled.
+ *
+ * * opts(GIT_OPT_SET_SSL_CIPHERS, const char *ciphers)
+ *
+ * > Set the SSL ciphers use for HTTPS connections.
+ * >
+ * > - `ciphers` is the list of ciphers that are eanbled.
+ *
+ * * opts(GIT_OPT_GET_USER_AGENT, git_buf *out)
+ *
+ * > Get the value of the User-Agent header.
+ * > The User-Agent is written to the `out` buffer.
+ *
+ * * opts(GIT_OPT_ENABLE_OFS_DELTA, int enabled)
+ *
+ * > Enable or disable the use of "offset deltas" when creating packfiles,
+ * > and the negotiation of them when talking to a remote server.
+ * > Offset deltas store a delta base location as an offset into the
+ * > packfile from the current location, which provides a shorter encoding
+ * > and thus smaller resultant packfiles.
+ * > Packfiles containing offset deltas can still be read.
+ * > This defaults to enabled.
+ *
+ * * opts(GIT_OPT_ENABLE_FSYNC_GITDIR, int enabled)
+ *
+ * > Enable synchronized writes of files in the gitdir using `fsync`
+ * > (or the platform equivalent) to ensure that new object data
+ * > is written to permanent storage, not simply cached. This
+ * > defaults to disabled.
+ *
+ * opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, int enabled)
+ *
+ * > Enable strict verification of object hashsums when reading
+ * > objects from disk. This may impact performance due to an
+ * > additional checksum calculation on each object. This defaults
+ * > to enabled.
+ *
+ * opts(GIT_OPT_SET_ALLOCATOR, git_allocator *allocator)
+ *
+ * > Set the memory allocator to a different memory allocator. This
+ * > allocator will then be used to make all memory allocations for
+ * > libgit2 operations. If the given `allocator` is NULL, then the
+ * > system default will be restored.
+ *
+ * opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, int enabled)
+ *
+ * > Ensure that there are no unsaved changes in the index before
+ * > beginning any operation that reloads the index from disk (eg,
+ * > checkout). If there are unsaved changes, the instruction will
+ * > fail. (Using the FORCE flag to checkout will still overwrite
+ * > these changes.)
+ *
+ * opts(GIT_OPT_GET_PACK_MAX_OBJECTS, size_t *out)
+ *
+ * > Get the maximum number of objects libgit2 will allow in a pack
+ * > file when downloading a pack file from a remote. This can be
+ * > used to limit maximum memory usage when fetching from an untrusted
+ * > remote.
+ *
+ * opts(GIT_OPT_SET_PACK_MAX_OBJECTS, size_t objects)
+ *
+ * > Set the maximum number of objects libgit2 will allow in a pack
+ * > file when downloading a pack file from a remote.
+ *
+ * opts(GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS, int enabled)
+ * > This will cause .keep file existence checks to be skipped when
+ * > accessing packfiles, which can help performance with remote filesystems.
+ *
+ * opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, int enabled)
+ * > When connecting to a server using NTLM or Negotiate
+ * > authentication, use expect/continue when POSTing data.
+ * > This option is not available on Windows.
+ *
+ * opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, int priority)
+ * > Override the default priority of the packed ODB backend which
+ * > is added when default backends are assigned to a repository
+ *
+ * opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, int priority)
+ * > Override the default priority of the loose ODB backend which
+ * > is added when default backends are assigned to a repository
+ *
+ * opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out)
+ * > Returns the list of git extensions that are supported. This
+ * > is the list of built-in extensions supported by libgit2 and
+ * > custom extensions that have been added with
+ * > `GIT_OPT_SET_EXTENSIONS`. Extensions that have been negated
+ * > will not be returned. The returned list should be released
+ * > with `git_strarray_dispose`.
+ *
+ * opts(GIT_OPT_SET_EXTENSIONS, const char **extensions, size_t len)
+ * > Set that the given git extensions are supported by the caller.
+ * > Extensions supported by libgit2 may be negated by prefixing
+ * > them with a `!`. For example: setting extensions to
+ * > { "!noop", "newext" } indicates that the caller does not want
+ * > to support repositories with the `noop` extension but does want
+ * > to support repositories with the `newext` extension.
+ *
+ * opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled)
+ * > Gets the owner validation setting for repository
+ * > directories.
+ *
+ * opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled)
+ * > Set that repository directories should be owned by the current
+ * > user. The default is to validate ownership.
+ *
+ * opts(GIT_OPT_GET_HOMEDIR, git_buf *out)
+ * > Gets the current user's home directory, as it will be used
+ * > for file lookups. The path is written to the `out` buffer.
+ *
+ * opts(GIT_OPT_SET_HOMEDIR, const char *path)
+ * > Sets the directory used as the current user's home directory,
+ * > for file lookups.
+ * >
+ * > - `path` directory of home directory.
+ *
+ * opts(GIT_OPT_GET_SERVER_CONNECT_TIMEOUT, int *timeout)
+ * > Gets the timeout (in milliseconds) to attempt connections to
+ * > a remote server.
+ *
+ * opts(GIT_OPT_SET_SERVER_CONNECT_TIMEOUT, int timeout)
+ * > Sets the timeout (in milliseconds) to attempt connections to
+ * > a remote server. This is supported only for HTTP(S) connections
+ * > and is not supported by SSH. Set to 0 to use the system default.
+ * > Note that this may not be able to be configured longer than the
+ * > system default, typically 75 seconds.
+ *
+ * opts(GIT_OPT_GET_SERVER_TIMEOUT, int *timeout)
+ * > Gets the timeout (in milliseconds) for reading from and writing
+ * > to a remote server.
+ *
+ * opts(GIT_OPT_SET_SERVER_TIMEOUT, int timeout)
+ * > Sets the timeout (in milliseconds) for reading from and writing
+ * > to a remote server. This is supported only for HTTP(S)
+ * > connections and is not supported by SSH. Set to 0 to use the
+ * > system default.
+ *
+ * @param option Option key
+ * @param ... value to set the option
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_libgit2_opts(int option, ...);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/config.h b/include/git2/config.h
new file mode 100644
index 0000000..cfab0c7
--- /dev/null
+++ b/include/git2/config.h
@@ -0,0 +1,782 @@
+/*
+ * 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_config_h__
+#define INCLUDE_git_config_h__
+
+#include "common.h"
+#include "types.h"
+#include "buffer.h"
+
+/**
+ * @file git2/config.h
+ * @brief Git config management routines
+ * @defgroup git_config Git config management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Priority level of a config file.
+ * These priority levels correspond to the natural escalation logic
+ * (from higher to lower) when searching for config entries in git.git.
+ *
+ * git_config_open_default() and git_repository_config() honor those
+ * priority levels as well.
+ */
+typedef enum {
+ /** System-wide on Windows, for compatibility with portable git */
+ GIT_CONFIG_LEVEL_PROGRAMDATA = 1,
+
+ /** System-wide configuration file; /etc/gitconfig on Linux systems */
+ GIT_CONFIG_LEVEL_SYSTEM = 2,
+
+ /** XDG compatible configuration file; typically ~/.config/git/config */
+ GIT_CONFIG_LEVEL_XDG = 3,
+
+ /** User-specific configuration file (also called Global configuration
+ * file); typically ~/.gitconfig
+ */
+ GIT_CONFIG_LEVEL_GLOBAL = 4,
+
+ /** Repository specific configuration file; $WORK_DIR/.git/config on
+ * non-bare repos
+ */
+ GIT_CONFIG_LEVEL_LOCAL = 5,
+
+ /** Application specific configuration file; freely defined by applications
+ */
+ GIT_CONFIG_LEVEL_APP = 6,
+
+ /** Represents the highest level available config file (i.e. the most
+ * specific config file available that actually is loaded)
+ */
+ GIT_CONFIG_HIGHEST_LEVEL = -1
+} git_config_level_t;
+
+/**
+ * An entry in a configuration file
+ */
+typedef struct git_config_entry {
+ const char *name; /**< Name of the entry (normalised) */
+ const char *value; /**< String value of the entry */
+ unsigned int include_depth; /**< Depth of includes where this variable was found */
+ git_config_level_t level; /**< Which config file this was found in */
+ void GIT_CALLBACK(free)(struct git_config_entry *entry); /**< Free function for this entry */
+ void *payload; /**< Opaque value for the free function. Do not read or write */
+} git_config_entry;
+
+/**
+ * Free a config entry
+ *
+ * @param entry The entry to free.
+ */
+GIT_EXTERN(void) git_config_entry_free(git_config_entry *entry);
+
+/**
+ * A config enumeration callback
+ *
+ * @param entry the entry currently being enumerated
+ * @param payload a user-specified pointer
+ * @return non-zero to terminate the iteration.
+ */
+typedef int GIT_CALLBACK(git_config_foreach_cb)(const git_config_entry *entry, void *payload);
+
+/**
+ * An opaque structure for a configuration iterator
+ */
+typedef struct git_config_iterator git_config_iterator;
+
+/**
+ * Config var type
+ */
+typedef enum {
+ GIT_CONFIGMAP_FALSE = 0,
+ GIT_CONFIGMAP_TRUE = 1,
+ GIT_CONFIGMAP_INT32,
+ GIT_CONFIGMAP_STRING
+} git_configmap_t;
+
+/**
+ * Mapping from config variables to values.
+ */
+typedef struct {
+ git_configmap_t type;
+ const char *str_match;
+ int map_value;
+} git_configmap;
+
+/**
+ * Locate the path to the global configuration file
+ *
+ * The user or global configuration file is usually
+ * located in `$HOME/.gitconfig`.
+ *
+ * This method will try to guess the full path to that
+ * file, if the file exists. The returned path
+ * may be used on any `git_config` call to load the
+ * global configuration file.
+ *
+ * This method will not guess the path to the xdg compatible
+ * config file (`.config/git/config`).
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a global configuration file has been found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_global(git_buf *out);
+
+/**
+ * Locate the path to the global xdg compatible configuration file
+ *
+ * The xdg compatible configuration file is usually
+ * located in `$HOME/.config/git/config`.
+ *
+ * This method will try to guess the full path to that
+ * file, if the file exists. The returned path
+ * may be used on any `git_config` call to load the
+ * xdg compatible configuration file.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a xdg compatible configuration file has been
+ * found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_xdg(git_buf *out);
+
+/**
+ * Locate the path to the system configuration file
+ *
+ * If `/etc/gitconfig` doesn't exist, it will look for
+ * `%PROGRAMFILES%\Git\etc\gitconfig`.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a system configuration file has been
+ * found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_system(git_buf *out);
+
+/**
+ * Locate the path to the configuration file in ProgramData
+ *
+ * Look for the file in `%PROGRAMDATA%\Git\config` used by portable git.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a ProgramData configuration file has been
+ * found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_programdata(git_buf *out);
+
+/**
+ * Open the global, XDG and system configuration files
+ *
+ * Utility wrapper that finds the global, XDG and system configuration files
+ * and opens them into a single prioritized config object that can be
+ * used when accessing default config data outside a repository.
+ *
+ * @param out Pointer to store the config instance
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_open_default(git_config **out);
+
+/**
+ * Allocate a new configuration object
+ *
+ * This object is empty, so you have to add a file to it before you
+ * can do anything with it.
+ *
+ * @param out pointer to the new configuration
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_new(git_config **out);
+
+/**
+ * Add an on-disk config file instance to an existing config
+ *
+ * The on-disk file pointed at by `path` will be opened and
+ * parsed; it's expected to be a native Git config file following
+ * the default Git config syntax (see man git-config).
+ *
+ * If the file does not exist, the file will still be added and it
+ * will be created the first time we write to it.
+ *
+ * Note that the configuration object will free the file
+ * automatically.
+ *
+ * Further queries on this config object will access each
+ * of the config file instances in order (instances with
+ * a higher priority level will be accessed first).
+ *
+ * @param cfg the configuration to add the file to
+ * @param path path to the configuration file to add
+ * @param level the priority level of the backend
+ * @param force replace config file at the given priority level
+ * @param repo optional repository to allow parsing of
+ * conditional includes
+ * @return 0 on success, GIT_EEXISTS when adding more than one file
+ * for a given priority level (and force_replace set to 0),
+ * GIT_ENOTFOUND when the file doesn't exist or error code
+ */
+GIT_EXTERN(int) git_config_add_file_ondisk(
+ git_config *cfg,
+ const char *path,
+ git_config_level_t level,
+ const git_repository *repo,
+ int force);
+
+/**
+ * Create a new config instance containing a single on-disk file
+ *
+ * This method is a simple utility wrapper for the following sequence
+ * of calls:
+ * - git_config_new
+ * - git_config_add_file_ondisk
+ *
+ * @param out The configuration instance to create
+ * @param path Path to the on-disk file to open
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
+
+/**
+ * Build a single-level focused config object from a multi-level one.
+ *
+ * The returned config object can be used to perform get/set/delete operations
+ * on a single specific level.
+ *
+ * Getting several times the same level from the same parent multi-level config
+ * will return different config instances, but containing the same config_file
+ * instance.
+ *
+ * @param out The configuration instance to create
+ * @param parent Multi-level config to search for the given level
+ * @param level Configuration level to search for
+ * @return 0, GIT_ENOTFOUND if the passed level cannot be found in the
+ * multi-level parent config, or an error code
+ */
+GIT_EXTERN(int) git_config_open_level(
+ git_config **out,
+ const git_config *parent,
+ git_config_level_t level);
+
+/**
+ * Open the global/XDG configuration file according to git's rules
+ *
+ * Git allows you to store your global configuration at
+ * `$HOME/.gitconfig` or `$XDG_CONFIG_HOME/git/config`. For backwards
+ * compatibility, the XDG file shouldn't be used unless the use has
+ * created it explicitly. With this function you'll open the correct
+ * one to write to.
+ *
+ * @param out pointer in which to store the config object
+ * @param config the config object in which to look
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
+
+/**
+ * Create a snapshot of the configuration
+ *
+ * Create a snapshot of the current state of a configuration, which
+ * allows you to look into a consistent view of the configuration for
+ * looking up complex values (e.g. a remote, submodule).
+ *
+ * The string returned when querying such a config object is valid
+ * until it is freed.
+ *
+ * @param out pointer in which to store the snapshot config object
+ * @param config configuration to snapshot
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_snapshot(git_config **out, git_config *config);
+
+/**
+ * Free the configuration and its associated memory and files
+ *
+ * @param cfg the configuration to free
+ */
+GIT_EXTERN(void) git_config_free(git_config *cfg);
+
+/**
+ * Get the git_config_entry of a config variable.
+ *
+ * Free the git_config_entry after use with `git_config_entry_free()`.
+ *
+ * @param out pointer to the variable git_config_entry
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_entry(
+ git_config_entry **out,
+ const git_config *cfg,
+ const char *name);
+
+/**
+ * Get the value of an integer config variable.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a long integer config variable.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a boolean config variable.
+ *
+ * This function uses the usual C convention of 0 being false and
+ * anything else true.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a path config variable.
+ *
+ * A leading '~' will be expanded to the global search path (which
+ * defaults to the user's home directory but can be overridden via
+ * `git_libgit2_opts()`.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out the buffer in which to store the result
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_path(git_buf *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a string config variable.
+ *
+ * This function can only be used on snapshot config objects. The
+ * string is owned by the config and should not be freed by the
+ * user. The pointer will be valid until the config is freed.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the string
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a string config variable.
+ *
+ * The value of the config will be copied into the buffer.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out buffer in which to store the string
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, const char *name);
+
+/**
+ * Get each value of a multivar in a foreach callback
+ *
+ * The callback will be called on each variable found
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp regular expression to filter which variables we're
+ * interested in. Use NULL to indicate all
+ * @param callback the function to be called on each value of the variable
+ * @param payload opaque pointer to pass to the callback
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
+
+/**
+ * Get each value of a multivar
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp regular expression to filter which variables we're
+ * interested in. Use NULL to indicate all
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp);
+
+/**
+ * Return the current entry and advance the iterator
+ *
+ * The pointers returned by this function are valid until the next call
+ * to `git_config_next` or until the iterator is freed.
+ *
+ * @param entry pointer to store the entry
+ * @param iter the iterator
+ * @return 0 or an error code. GIT_ITEROVER if the iteration has completed
+ */
+GIT_EXTERN(int) git_config_next(git_config_entry **entry, git_config_iterator *iter);
+
+/**
+ * Free a config iterator
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_config_iterator_free(git_config_iterator *iter);
+
+/**
+ * Set the value of an integer config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value Integer value for the variable
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value);
+
+/**
+ * Set the value of a long integer config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value Long integer value for the variable
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
+
+/**
+ * Set the value of a boolean config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value the value to store
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
+
+/**
+ * Set the value of a string config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * A copy of the string is made and the user is free to use it
+ * afterwards.
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value the string to store.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value);
+
+/**
+ * Set a multivar in the local config file.
+ *
+ * The regular expression is applied case-sensitively on the value.
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp a regular expression to indicate which values to replace
+ * @param value the new value.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value);
+
+/**
+ * Delete a config variable from the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg the configuration
+ * @param name the variable to delete
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
+
+/**
+ * Deletes one or several entries from a multivar in the local config file.
+ *
+ * The regular expression is applied case-sensitively on the value.
+ *
+ * @param cfg where to look for the variables
+ * @param name the variable's name
+ * @param regexp a regular expression to indicate which values to delete
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_delete_multivar(git_config *cfg, const char *name, const char *regexp);
+
+/**
+ * Perform an operation on each config variable.
+ *
+ * The callback receives the normalized name and value of each variable
+ * in the config backend, and the data pointer passed to this function.
+ * If the callback returns a non-zero value, the function stops iterating
+ * and returns that value to the caller.
+ *
+ * The pointers passed to the callback are only valid as long as the
+ * iteration is ongoing.
+ *
+ * @param cfg where to get the variables from
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_config_foreach(
+ const git_config *cfg,
+ git_config_foreach_cb callback,
+ void *payload);
+
+/**
+ * Iterate over all the config variables
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to get the variables from
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_config *cfg);
+
+/**
+ * Iterate over all the config variables whose name matches a pattern
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to ge the variables from
+ * @param regexp regular expression to match the names
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp);
+
+/**
+ * Perform an operation on each config variable matching a regular expression.
+ *
+ * This behaves like `git_config_foreach` with an additional filter of a
+ * regular expression that filters which config keys are passed to the
+ * callback.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the case-insensitive parts are lower-case.
+ *
+ * @param cfg where to get the variables from
+ * @param regexp regular expression to match against config names
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ * @return 0 or the return value of the callback which didn't return 0
+ */
+GIT_EXTERN(int) git_config_foreach_match(
+ const git_config *cfg,
+ const char *regexp,
+ git_config_foreach_cb callback,
+ void *payload);
+
+/**
+ * Query the value of a config variable and return it mapped to
+ * an integer constant.
+ *
+ * This is a helper method to easily map different possible values
+ * to a variable to integer constants that easily identify them.
+ *
+ * A mapping array looks as follows:
+ *
+ * git_configmap autocrlf_mapping[] = {
+ * {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
+ * {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
+ * {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT},
+ * {GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}};
+ *
+ * On any "false" value for the variable (e.g. "false", "FALSE", "no"), the
+ * mapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter.
+ *
+ * The same thing applies for any "true" value such as "true", "yes" or "1", storing
+ * the `GIT_AUTO_CRLF_TRUE` variable.
+ *
+ * Otherwise, if the value matches the string "input" (with case insensitive comparison),
+ * the given constant will be stored in `out`, and likewise for "default".
+ *
+ * If not a single match can be made to store in `out`, an error code will be
+ * returned.
+ *
+ * @param out place to store the result of the mapping
+ * @param cfg config file to get the variables from
+ * @param name name of the config variable to lookup
+ * @param maps array of `git_configmap` objects specifying the possible mappings
+ * @param map_n number of mapping objects in `maps`
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_config_get_mapped(
+ int *out,
+ const git_config *cfg,
+ const char *name,
+ const git_configmap *maps,
+ size_t map_n);
+
+/**
+ * Maps a string value to an integer constant
+ *
+ * @param out place to store the result of the parsing
+ * @param maps array of `git_configmap` objects specifying the possible mappings
+ * @param map_n number of mapping objects in `maps`
+ * @param value value to parse
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_lookup_map_value(
+ int *out,
+ const git_configmap *maps,
+ size_t map_n,
+ const char *value);
+
+/**
+ * Parse a string value as a bool.
+ *
+ * Valid values for true are: 'true', 'yes', 'on', 1 or any
+ * number different from 0
+ * Valid values for false are: 'false', 'no', 'off', 0
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value);
+
+/**
+ * Parse a string value as an int32.
+ *
+ * An optional value suffix of 'k', 'm', or 'g' will
+ * cause the value to be multiplied by 1024, 1048576,
+ * or 1073741824 prior to output.
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value);
+
+/**
+ * Parse a string value as an int64.
+ *
+ * An optional value suffix of 'k', 'm', or 'g' will
+ * cause the value to be multiplied by 1024, 1048576,
+ * or 1073741824 prior to output.
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
+
+/**
+ * Parse a string value as a path.
+ *
+ * A leading '~' will be expanded to the global search path (which
+ * defaults to the user's home directory but can be overridden via
+ * `git_libgit2_opts()`.
+ *
+ * If the value does not begin with a tilde, the input will be
+ * returned.
+ *
+ * @param out placae to store the result of parsing
+ * @param value the path to evaluate
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value);
+
+/**
+ * Perform an operation on each config variable in a given config backend,
+ * matching a regular expression.
+ *
+ * This behaves like `git_config_foreach_match` except that only config
+ * entries from the given backend entry are enumerated.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * @param backend where to get the variables from
+ * @param regexp regular expression to match against config names (can be NULL)
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_config_backend_foreach_match(
+ git_config_backend *backend,
+ const char *regexp,
+ git_config_foreach_cb callback,
+ void *payload);
+
+
+/**
+ * Lock the backend with the highest priority
+ *
+ * Locking disallows anybody else from writing to that backend. Any
+ * updates made after locking will not be visible to a reader until
+ * the file is unlocked.
+ *
+ * You can apply the changes by calling `git_transaction_commit()`
+ * before freeing the transaction. Either of these actions will unlock
+ * the config.
+ *
+ * @param tx the resulting transaction, use this to commit or undo the
+ * changes
+ * @param cfg the configuration in which to lock
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_lock(git_transaction **tx, git_config *cfg);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h
new file mode 100644
index 0000000..3721b6d
--- /dev/null
+++ b/include/git2/cred_helpers.h
@@ -0,0 +1,15 @@
+/*
+ * 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_cred_helpers_h__
+#define INCLUDE_git_cred_helpers_h__
+
+/* These declarations have moved. */
+#ifndef GIT_DEPRECATE_HARD
+# include "git2/credential_helpers.h"
+#endif
+
+#endif
diff --git a/include/git2/credential.h b/include/git2/credential.h
new file mode 100644
index 0000000..7a04bc0
--- /dev/null
+++ b/include/git2/credential.h
@@ -0,0 +1,315 @@
+/*
+ * 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_credential_h__
+#define INCLUDE_git_credential_h__
+
+#include "common.h"
+
+/**
+ * @file git2/credential.h
+ * @brief Git authentication & credential management
+ * @defgroup git_credential Authentication & credential management
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Supported credential types
+ *
+ * This represents the various types of authentication methods supported by
+ * the library.
+ */
+typedef enum {
+ /**
+ * A vanilla user/password request
+ * @see git_credential_userpass_plaintext_new
+ */
+ GIT_CREDENTIAL_USERPASS_PLAINTEXT = (1u << 0),
+
+ /**
+ * An SSH key-based authentication request
+ * @see git_credential_ssh_key_new
+ */
+ GIT_CREDENTIAL_SSH_KEY = (1u << 1),
+
+ /**
+ * An SSH key-based authentication request, with a custom signature
+ * @see git_credential_ssh_custom_new
+ */
+ GIT_CREDENTIAL_SSH_CUSTOM = (1u << 2),
+
+ /**
+ * An NTLM/Negotiate-based authentication request.
+ * @see git_credential_default
+ */
+ GIT_CREDENTIAL_DEFAULT = (1u << 3),
+
+ /**
+ * An SSH interactive authentication request
+ * @see git_credential_ssh_interactive_new
+ */
+ GIT_CREDENTIAL_SSH_INTERACTIVE = (1u << 4),
+
+ /**
+ * Username-only authentication request
+ *
+ * Used as a pre-authentication step if the underlying transport
+ * (eg. SSH, with no username in its URL) does not know which username
+ * to use.
+ *
+ * @see git_credential_username_new
+ */
+ GIT_CREDENTIAL_USERNAME = (1u << 5),
+
+ /**
+ * An SSH key-based authentication request
+ *
+ * Allows credentials to be read from memory instead of files.
+ * Note that because of differences in crypto backend support, it might
+ * not be functional.
+ *
+ * @see git_credential_ssh_key_memory_new
+ */
+ GIT_CREDENTIAL_SSH_MEMORY = (1u << 6)
+} git_credential_t;
+
+/**
+ * The base structure for all credential types
+ */
+typedef struct git_credential git_credential;
+
+typedef struct git_credential_userpass_plaintext git_credential_userpass_plaintext;
+
+/** Username-only credential information */
+typedef struct git_credential_username git_credential_username;
+
+/** A key for NTLM/Kerberos "default" credentials */
+typedef struct git_credential git_credential_default;
+
+/**
+ * A ssh key from disk
+ */
+typedef struct git_credential_ssh_key git_credential_ssh_key;
+
+/**
+ * Keyboard-interactive based ssh authentication
+ */
+typedef struct git_credential_ssh_interactive git_credential_ssh_interactive;
+
+/**
+ * A key with a custom signature function
+ */
+typedef struct git_credential_ssh_custom git_credential_ssh_custom;
+
+/**
+ * Credential acquisition callback.
+ *
+ * This callback is usually involved any time another system might need
+ * authentication. As such, you are expected to provide a valid
+ * git_credential object back, depending on allowed_types (a
+ * git_credential_t bitmask).
+ *
+ * Note that most authentication details are your responsibility - this
+ * callback will be called until the authentication succeeds, or you report
+ * an error. As such, it's easy to get in a loop if you fail to stop providing
+ * the same incorrect credentials.
+ *
+ * @param out The newly created credential object.
+ * @param url The resource for which we are demanding a credential.
+ * @param username_from_url The username that was embedded in a "user\@host"
+ * remote url, or NULL if not included.
+ * @param allowed_types A bitmask stating which credential types are OK to return.
+ * @param payload The payload provided when specifying this callback.
+ * @return 0 for success, < 0 to indicate an error, > 0 to indicate
+ * no credential was acquired
+ */
+typedef int GIT_CALLBACK(git_credential_acquire_cb)(
+ git_credential **out,
+ const char *url,
+ const char *username_from_url,
+ unsigned int allowed_types,
+ void *payload);
+
+/**
+ * Free a credential.
+ *
+ * This is only necessary if you own the object; that is, if you are a
+ * transport.
+ *
+ * @param cred the object to free
+ */
+GIT_EXTERN(void) git_credential_free(git_credential *cred);
+
+/**
+ * Check whether a credential object contains username information.
+ *
+ * @param cred object to check
+ * @return 1 if the credential object has non-NULL username, 0 otherwise
+ */
+GIT_EXTERN(int) git_credential_has_username(git_credential *cred);
+
+/**
+ * Return the username associated with a credential object.
+ *
+ * @param cred object to check
+ * @return the credential username, or NULL if not applicable
+ */
+GIT_EXTERN(const char *) git_credential_get_username(git_credential *cred);
+
+/**
+ * Create a new plain-text username and password credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username The username of the credential.
+ * @param password The password of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_userpass_plaintext_new(
+ git_credential **out,
+ const char *username,
+ const char *password);
+
+/**
+ * Create a "default" credential usable for Negotiate mechanisms like NTLM
+ * or Kerberos authentication.
+ *
+ * @param out The newly created credential object.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_default_new(git_credential **out);
+
+/**
+ * Create a credential to specify a username.
+ *
+ * This is used with ssh authentication to query for the username if
+ * none is specified in the url.
+ *
+ * @param out The newly created credential object.
+ * @param username The username to authenticate with
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_username_new(git_credential **out, const char *username);
+
+/**
+ * Create a new passphrase-protected ssh key credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @param publickey The path to the public key of the credential.
+ * @param privatekey The path to the private key of the credential.
+ * @param passphrase The passphrase of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_ssh_key_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ const char *privatekey,
+ const char *passphrase);
+
+/**
+ * Create a new ssh key credential object reading the keys from memory.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate.
+ * @param publickey The public key of the credential.
+ * @param privatekey The private key of the credential.
+ * @param passphrase The passphrase of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_ssh_key_memory_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ const char *privatekey,
+ const char *passphrase);
+
+/*
+ * If the user hasn't included libssh2.h before git2.h, we need to
+ * define a few types for the callback signatures.
+ */
+#ifndef LIBSSH2_VERSION
+typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
+typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
+typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
+#endif
+
+typedef void GIT_CALLBACK(git_credential_ssh_interactive_cb)(
+ const char *name,
+ int name_len,
+ const char *instruction, int instruction_len,
+ int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+ LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+ void **abstract);
+
+
+/**
+ * Create a new ssh keyboard-interactive based credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username Username to use to authenticate.
+ * @param prompt_callback The callback method used for prompts.
+ * @param payload Additional data to pass to the callback.
+ * @return 0 for success or an error code for failure.
+ */
+GIT_EXTERN(int) git_credential_ssh_interactive_new(
+ git_credential **out,
+ const char *username,
+ git_credential_ssh_interactive_cb prompt_callback,
+ void *payload);
+
+/**
+ * Create a new ssh key credential object used for querying an ssh-agent.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_ssh_key_from_agent(
+ git_credential **out,
+ const char *username);
+
+typedef int GIT_CALLBACK(git_credential_sign_cb)(
+ LIBSSH2_SESSION *session,
+ unsigned char **sig, size_t *sig_len,
+ const unsigned char *data, size_t data_len,
+ void **abstract);
+
+/**
+ * Create an ssh key credential with a custom signing function.
+ *
+ * This lets you use your own function to sign the challenge.
+ *
+ * This function and its credential type is provided for completeness
+ * and wraps `libssh2_userauth_publickey()`, which is undocumented.
+ *
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @param publickey The bytes of the public key.
+ * @param publickey_len The length of the public key in bytes.
+ * @param sign_callback The callback method to sign the data during the challenge.
+ * @param payload Additional data to pass to the callback.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_credential_ssh_custom_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ size_t publickey_len,
+ git_credential_sign_cb sign_callback,
+ void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/credential_helpers.h b/include/git2/credential_helpers.h
new file mode 100644
index 0000000..f0fb070
--- /dev/null
+++ b/include/git2/credential_helpers.h
@@ -0,0 +1,53 @@
+/*
+ * 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_credential_helpers_h__
+#define INCLUDE_git_credential_helpers_h__
+
+#include "transport.h"
+
+/**
+ * @file git2/credential_helpers.h
+ * @brief Utility functions for credential management
+ * @defgroup git_credential_helpers credential management helpers
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Payload for git_credential_userpass_plaintext.
+ */
+typedef struct git_credential_userpass_payload {
+ const char *username;
+ const char *password;
+} git_credential_userpass_payload;
+
+
+/**
+ * Stock callback usable as a git_credential_acquire_cb. This calls
+ * git_cred_userpass_plaintext_new unless the protocol has not specified
+ * `GIT_CREDENTIAL_USERPASS_PLAINTEXT` as an allowed type.
+ *
+ * @param out The newly created credential object.
+ * @param url The resource for which we are demanding a credential.
+ * @param user_from_url The username that was embedded in a "user\@host"
+ * remote url, or NULL if not included.
+ * @param allowed_types A bitmask stating which credential types are OK to return.
+ * @param payload The payload provided when specifying this callback. (This is
+ * interpreted as a `git_credential_userpass_payload*`.)
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_credential_userpass(
+ git_credential **out,
+ const char *url,
+ const char *user_from_url,
+ unsigned int allowed_types,
+ void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h
new file mode 100644
index 0000000..52864eb
--- /dev/null
+++ b/include/git2/deprecated.h
@@ -0,0 +1,939 @@
+/*
+ * 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_deprecated_h__
+#define INCLUDE_git_deprecated_h__
+
+#include "attr.h"
+#include "config.h"
+#include "common.h"
+#include "blame.h"
+#include "buffer.h"
+#include "checkout.h"
+#include "cherrypick.h"
+#include "clone.h"
+#include "describe.h"
+#include "diff.h"
+#include "errors.h"
+#include "filter.h"
+#include "index.h"
+#include "indexer.h"
+#include "merge.h"
+#include "object.h"
+#include "proxy.h"
+#include "refs.h"
+#include "rebase.h"
+#include "remote.h"
+#include "trace.h"
+#include "repository.h"
+#include "revert.h"
+#include "revparse.h"
+#include "stash.h"
+#include "status.h"
+#include "submodule.h"
+#include "worktree.h"
+#include "credential.h"
+#include "credential_helpers.h"
+
+/*
+ * Users can avoid deprecated functions by defining `GIT_DEPRECATE_HARD`.
+ */
+#ifndef GIT_DEPRECATE_HARD
+
+/*
+ * The credential structures are now opaque by default, and their
+ * definition has moved into the `sys/credential.h` header; include
+ * them here for backward compatibility.
+ */
+#include "sys/credential.h"
+
+/**
+ * @file git2/deprecated.h
+ * @brief libgit2 deprecated functions and values
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** @name Deprecated Attribute Constants
+ *
+ * These enumeration values are retained for backward compatibility.
+ * The newer versions of these functions should be preferred in all
+ * new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#define GIT_ATTR_UNSPECIFIED_T GIT_ATTR_VALUE_UNSPECIFIED
+#define GIT_ATTR_TRUE_T GIT_ATTR_VALUE_TRUE
+#define GIT_ATTR_FALSE_T GIT_ATTR_VALUE_FALSE
+#define GIT_ATTR_VALUE_T GIT_ATTR_VALUE_STRING
+
+#define GIT_ATTR_TRUE(attr) GIT_ATTR_IS_TRUE(attr)
+#define GIT_ATTR_FALSE(attr) GIT_ATTR_IS_FALSE(attr)
+#define GIT_ATTR_UNSPECIFIED(attr) GIT_ATTR_IS_UNSPECIFIED(attr)
+
+typedef git_attr_value_t git_attr_t;
+
+/**@}*/
+
+/** @name Deprecated Blob Functions and Constants
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these functions and values
+ * should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#define GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD
+
+GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path);
+GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path);
+GIT_EXTERN(int) git_blob_create_fromstream(
+ git_writestream **out,
+ git_repository *repo,
+ const char *hintpath);
+GIT_EXTERN(int) git_blob_create_fromstream_commit(
+ git_oid *out,
+ git_writestream *stream);
+GIT_EXTERN(int) git_blob_create_frombuffer(
+ git_oid *id, git_repository *repo, const void *buffer, size_t len);
+
+/** Deprecated in favor of `git_blob_filter`.
+ *
+ * @deprecated Use git_blob_filter
+ * @see git_blob_filter
+ */
+GIT_EXTERN(int) git_blob_filtered_content(
+ git_buf *out,
+ git_blob *blob,
+ const char *as_path,
+ int check_for_binary_data);
+
+/**@}*/
+
+/** @name Deprecated Filter Functions
+ *
+ * These functions are retained for backward compatibility. The
+ * newer versions of these functions should be preferred in all
+ * new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/** Deprecated in favor of `git_filter_list_stream_buffer`.
+ *
+ * @deprecated Use git_filter_list_stream_buffer
+ * @see Use git_filter_list_stream_buffer
+ */
+GIT_EXTERN(int) git_filter_list_stream_data(
+ git_filter_list *filters,
+ git_buf *data,
+ git_writestream *target);
+
+/** Deprecated in favor of `git_filter_list_apply_to_buffer`.
+ *
+ * @deprecated Use git_filter_list_apply_to_buffer
+ * @see Use git_filter_list_apply_to_buffer
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_data(
+ git_buf *out,
+ git_filter_list *filters,
+ git_buf *in);
+
+/**@}*/
+
+/** @name Deprecated Tree Functions
+ *
+ * These functions are retained for backward compatibility. The
+ * newer versions of these functions and values should be preferred
+ * in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Write the contents of the tree builder as a tree object.
+ * This is an alias of `git_treebuilder_write` and is preserved
+ * for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_treebuilder_write
+ * @see git_treebuilder_write
+ */
+GIT_EXTERN(int) git_treebuilder_write_with_buffer(
+ git_oid *oid, git_treebuilder *bld, git_buf *tree);
+
+/**@}*/
+
+/** @name Deprecated Buffer Functions
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these functions should be
+ * preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Static initializer for git_buf from static buffer
+ */
+#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) }
+
+/**
+ * Resize the buffer allocation to make more space.
+ *
+ * This will attempt to grow the buffer to accommodate the target size.
+ *
+ * If the buffer refers to memory that was not allocated by libgit2 (i.e.
+ * the `asize` field is zero), then `ptr` will be replaced with a newly
+ * allocated block of data. Be careful so that memory allocated by the
+ * caller is not lost. As a special variant, if you pass `target_size` as
+ * 0 and the memory is not allocated by libgit2, this will allocate a new
+ * buffer of size `size` and copy the external data into it.
+ *
+ * Currently, this will never shrink a buffer, only expand it.
+ *
+ * If the allocation fails, this will return an error and the buffer will be
+ * marked as invalid for future operations, invaliding the contents.
+ *
+ * @param buffer The buffer to be resized; may or may not be allocated yet
+ * @param target_size The desired available size
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size);
+
+/**
+ * Set buffer to a copy of some raw data.
+ *
+ * @param buffer The buffer to set
+ * @param data The data to copy into the buffer
+ * @param datalen The length of the data to copy into the buffer
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_set(
+ git_buf *buffer, const void *data, size_t datalen);
+
+/**
+* Check quickly if buffer looks like it contains binary data
+*
+* @param buf Buffer to check
+* @return 1 if buffer looks like non-text data
+*/
+GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf);
+
+/**
+* Check quickly if buffer contains a NUL byte
+*
+* @param buf Buffer to check
+* @return 1 if buffer contains a NUL byte
+*/
+GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf);
+
+/**
+ * Free the memory referred to by the git_buf. This is an alias of
+ * `git_buf_dispose` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_buf_dispose
+ * @see git_buf_dispose
+ */
+GIT_EXTERN(void) git_buf_free(git_buf *buffer);
+
+/**@}*/
+
+/** @name Deprecated Commit Definitions
+ */
+/**@{*/
+
+/**
+ * Provide a commit signature during commit creation.
+ *
+ * Callers should instead define a `git_commit_create_cb` that
+ * generates a commit buffer using `git_commit_create_buffer`, sign
+ * that buffer and call `git_commit_create_with_signature`.
+ *
+ * @deprecated use a `git_commit_create_cb` instead
+ */
+typedef int (*git_commit_signing_cb)(
+ git_buf *signature,
+ git_buf *signature_field,
+ const char *commit_content,
+ void *payload);
+
+/**@}*/
+
+/** @name Deprecated Config Functions and Constants
+ */
+/**@{*/
+
+#define GIT_CVAR_FALSE GIT_CONFIGMAP_FALSE
+#define GIT_CVAR_TRUE GIT_CONFIGMAP_TRUE
+#define GIT_CVAR_INT32 GIT_CONFIGMAP_INT32
+#define GIT_CVAR_STRING GIT_CONFIGMAP_STRING
+
+typedef git_configmap git_cvar_map;
+
+/**@}*/
+
+/** @name Deprecated Diff Functions and Constants
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these functions and values
+ * should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Formatting options for diff e-mail generation
+ */
+typedef enum {
+ /** Normal patch, the default */
+ GIT_DIFF_FORMAT_EMAIL_NONE = 0,
+
+ /** Don't insert "[PATCH]" in the subject header*/
+ GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0)
+
+} git_diff_format_email_flags_t;
+
+/**
+ * Options for controlling the formatting of the generated e-mail.
+ */
+typedef struct {
+ unsigned int version;
+
+ /** see `git_diff_format_email_flags_t` above */
+ uint32_t flags;
+
+ /** This patch number */
+ size_t patch_no;
+
+ /** Total number of patches in this series */
+ size_t total_patches;
+
+ /** id to use for the commit */
+ const git_oid *id;
+
+ /** Summary of the change */
+ const char *summary;
+
+ /** Commit message's body */
+ const char *body;
+
+ /** Author of the change */
+ const git_signature *author;
+} git_diff_format_email_options;
+
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL, NULL}
+
+/**
+ * Create an e-mail ready patch from a diff.
+ *
+ * @deprecated git_email_create_from_diff
+ * @see git_email_create_from_diff
+ */
+GIT_EXTERN(int) git_diff_format_email(
+ git_buf *out,
+ git_diff *diff,
+ const git_diff_format_email_options *opts);
+
+/**
+ * Create an e-mail ready patch for a commit.
+ *
+ * @deprecated git_email_create_from_commit
+ * @see git_email_create_from_commit
+ */
+GIT_EXTERN(int) git_diff_commit_as_email(
+ git_buf *out,
+ git_repository *repo,
+ git_commit *commit,
+ size_t patch_no,
+ size_t total_patches,
+ uint32_t flags,
+ const git_diff_options *diff_opts);
+
+/**
+ * Initialize git_diff_format_email_options structure
+ *
+ * Initializes a `git_diff_format_email_options` with default values. Equivalent
+ * to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
+ *
+ * @param opts The `git_blame_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_format_email_options_init(
+ git_diff_format_email_options *opts,
+ unsigned int version);
+
+/**@}*/
+
+/** @name Deprecated Error Functions and Constants
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these functions and values
+ * should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#define GITERR_NONE GIT_ERROR_NONE
+#define GITERR_NOMEMORY GIT_ERROR_NOMEMORY
+#define GITERR_OS GIT_ERROR_OS
+#define GITERR_INVALID GIT_ERROR_INVALID
+#define GITERR_REFERENCE GIT_ERROR_REFERENCE
+#define GITERR_ZLIB GIT_ERROR_ZLIB
+#define GITERR_REPOSITORY GIT_ERROR_REPOSITORY
+#define GITERR_CONFIG GIT_ERROR_CONFIG
+#define GITERR_REGEX GIT_ERROR_REGEX
+#define GITERR_ODB GIT_ERROR_ODB
+#define GITERR_INDEX GIT_ERROR_INDEX
+#define GITERR_OBJECT GIT_ERROR_OBJECT
+#define GITERR_NET GIT_ERROR_NET
+#define GITERR_TAG GIT_ERROR_TAG
+#define GITERR_TREE GIT_ERROR_TREE
+#define GITERR_INDEXER GIT_ERROR_INDEXER
+#define GITERR_SSL GIT_ERROR_SSL
+#define GITERR_SUBMODULE GIT_ERROR_SUBMODULE
+#define GITERR_THREAD GIT_ERROR_THREAD
+#define GITERR_STASH GIT_ERROR_STASH
+#define GITERR_CHECKOUT GIT_ERROR_CHECKOUT
+#define GITERR_FETCHHEAD GIT_ERROR_FETCHHEAD
+#define GITERR_MERGE GIT_ERROR_MERGE
+#define GITERR_SSH GIT_ERROR_SSH
+#define GITERR_FILTER GIT_ERROR_FILTER
+#define GITERR_REVERT GIT_ERROR_REVERT
+#define GITERR_CALLBACK GIT_ERROR_CALLBACK
+#define GITERR_CHERRYPICK GIT_ERROR_CHERRYPICK
+#define GITERR_DESCRIBE GIT_ERROR_DESCRIBE
+#define GITERR_REBASE GIT_ERROR_REBASE
+#define GITERR_FILESYSTEM GIT_ERROR_FILESYSTEM
+#define GITERR_PATCH GIT_ERROR_PATCH
+#define GITERR_WORKTREE GIT_ERROR_WORKTREE
+#define GITERR_SHA1 GIT_ERROR_SHA1
+
+#define GIT_ERROR_SHA1 GIT_ERROR_SHA
+
+/**
+ * Return the last `git_error` object that was generated for the
+ * current thread. This is an alias of `git_error_last` and is
+ * preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_error_last
+ * @see git_error_last
+ */
+GIT_EXTERN(const git_error *) giterr_last(void);
+
+/**
+ * Clear the last error. This is an alias of `git_error_last` and is
+ * preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_error_clear
+ * @see git_error_clear
+ */
+GIT_EXTERN(void) giterr_clear(void);
+
+/**
+ * Sets the error message to the given string. This is an alias of
+ * `git_error_set_str` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_error_set_str
+ * @see git_error_set_str
+ */
+GIT_EXTERN(void) giterr_set_str(int error_class, const char *string);
+
+/**
+ * Indicates that an out-of-memory situation occurred. This is an alias
+ * of `git_error_set_oom` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_error_set_oom
+ * @see git_error_set_oom
+ */
+GIT_EXTERN(void) giterr_set_oom(void);
+
+/**@}*/
+
+/** @name Deprecated Index Functions and Constants
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these values should be
+ * preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#define GIT_IDXENTRY_NAMEMASK GIT_INDEX_ENTRY_NAMEMASK
+#define GIT_IDXENTRY_STAGEMASK GIT_INDEX_ENTRY_STAGEMASK
+#define GIT_IDXENTRY_STAGESHIFT GIT_INDEX_ENTRY_STAGESHIFT
+
+/* The git_indxentry_flag_t enum */
+#define GIT_IDXENTRY_EXTENDED GIT_INDEX_ENTRY_EXTENDED
+#define GIT_IDXENTRY_VALID GIT_INDEX_ENTRY_VALID
+
+#define GIT_IDXENTRY_STAGE(E) GIT_INDEX_ENTRY_STAGE(E)
+#define GIT_IDXENTRY_STAGE_SET(E,S) GIT_INDEX_ENTRY_STAGE_SET(E,S)
+
+/* The git_idxentry_extended_flag_t enum */
+#define GIT_IDXENTRY_INTENT_TO_ADD GIT_INDEX_ENTRY_INTENT_TO_ADD
+#define GIT_IDXENTRY_SKIP_WORKTREE GIT_INDEX_ENTRY_SKIP_WORKTREE
+#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_INDEX_ENTRY_INTENT_TO_ADD | GIT_INDEX_ENTRY_SKIP_WORKTREE)
+#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
+#define GIT_IDXENTRY_UPDATE (1 << 0)
+#define GIT_IDXENTRY_REMOVE (1 << 1)
+#define GIT_IDXENTRY_UPTODATE (1 << 2)
+#define GIT_IDXENTRY_ADDED (1 << 3)
+#define GIT_IDXENTRY_HASHED (1 << 4)
+#define GIT_IDXENTRY_UNHASHED (1 << 5)
+#define GIT_IDXENTRY_WT_REMOVE (1 << 6)
+#define GIT_IDXENTRY_CONFLICTED (1 << 7)
+#define GIT_IDXENTRY_UNPACKED (1 << 8)
+#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
+
+/* The git_index_capability_t enum */
+#define GIT_INDEXCAP_IGNORE_CASE GIT_INDEX_CAPABILITY_IGNORE_CASE
+#define GIT_INDEXCAP_NO_FILEMODE GIT_INDEX_CAPABILITY_NO_FILEMODE
+#define GIT_INDEXCAP_NO_SYMLINKS GIT_INDEX_CAPABILITY_NO_SYMLINKS
+#define GIT_INDEXCAP_FROM_OWNER GIT_INDEX_CAPABILITY_FROM_OWNER
+
+GIT_EXTERN(int) git_index_add_frombuffer(
+ git_index *index,
+ const git_index_entry *entry,
+ const void *buffer, size_t len);
+
+/**@}*/
+
+/** @name Deprecated Object Constants
+ *
+ * These enumeration values are retained for backward compatibility. The
+ * newer versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#define git_otype git_object_t
+
+#define GIT_OBJ_ANY GIT_OBJECT_ANY
+#define GIT_OBJ_BAD GIT_OBJECT_INVALID
+#define GIT_OBJ__EXT1 0
+#define GIT_OBJ_COMMIT GIT_OBJECT_COMMIT
+#define GIT_OBJ_TREE GIT_OBJECT_TREE
+#define GIT_OBJ_BLOB GIT_OBJECT_BLOB
+#define GIT_OBJ_TAG GIT_OBJECT_TAG
+#define GIT_OBJ__EXT2 5
+#define GIT_OBJ_OFS_DELTA GIT_OBJECT_OFS_DELTA
+#define GIT_OBJ_REF_DELTA GIT_OBJECT_REF_DELTA
+
+/**
+ * Get the size in bytes for the structure which
+ * acts as an in-memory representation of any given
+ * object type.
+ *
+ * For all the core types, this would the equivalent
+ * of calling `sizeof(git_commit)` if the core types
+ * were not opaque on the external API.
+ *
+ * @param type object type to get its size
+ * @return size in bytes of the object
+ */
+GIT_EXTERN(size_t) git_object__size(git_object_t type);
+
+/**@}*/
+
+/** @name Deprecated Remote Functions
+ *
+ * These functions are retained for backward compatibility. The newer
+ * versions of these functions should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility functions at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Ensure the remote name is well-formed.
+ *
+ * @deprecated Use git_remote_name_is_valid
+ * @param remote_name name to be checked.
+ * @return 1 if the reference name is acceptable; 0 if it isn't
+ */
+GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
+
+/**@}*/
+
+/** @name Deprecated Reference Functions and Constants
+ *
+ * These functions and enumeration values are retained for backward
+ * compatibility. The newer versions of these values should be
+ * preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+ /** Basic type of any Git reference. */
+#define git_ref_t git_reference_t
+#define git_reference_normalize_t git_reference_format_t
+
+#define GIT_REF_INVALID GIT_REFERENCE_INVALID
+#define GIT_REF_OID GIT_REFERENCE_DIRECT
+#define GIT_REF_SYMBOLIC GIT_REFERENCE_SYMBOLIC
+#define GIT_REF_LISTALL GIT_REFERENCE_ALL
+
+#define GIT_REF_FORMAT_NORMAL GIT_REFERENCE_FORMAT_NORMAL
+#define GIT_REF_FORMAT_ALLOW_ONELEVEL GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL
+#define GIT_REF_FORMAT_REFSPEC_PATTERN GIT_REFERENCE_FORMAT_REFSPEC_PATTERN
+#define GIT_REF_FORMAT_REFSPEC_SHORTHAND GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND
+
+/**
+ * Ensure the reference name is well-formed.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * @deprecated Use git_reference_name_is_valid
+ * @param refname name to be checked.
+ * @return 1 if the reference name is acceptable; 0 if it isn't
+ */
+GIT_EXTERN(int) git_reference_is_valid_name(const char *refname);
+
+GIT_EXTERN(int) git_tag_create_frombuffer(
+ git_oid *oid,
+ git_repository *repo,
+ const char *buffer,
+ int force);
+
+/**@}*/
+
+/** @name Deprecated Revspec Constants
+ *
+ * These enumeration values are retained for backward compatibility.
+ * The newer versions of these values should be preferred in all new
+ * code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+typedef git_revspec_t git_revparse_mode_t;
+
+#define GIT_REVPARSE_SINGLE GIT_REVSPEC_SINGLE
+#define GIT_REVPARSE_RANGE GIT_REVSPEC_RANGE
+#define GIT_REVPARSE_MERGE_BASE GIT_REVSPEC_MERGE_BASE
+
+/**@}*/
+
+/** @name Deprecated Credential Types
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+typedef git_credential git_cred;
+typedef git_credential_userpass_plaintext git_cred_userpass_plaintext;
+typedef git_credential_username git_cred_username;
+typedef git_credential_default git_cred_default;
+typedef git_credential_ssh_key git_cred_ssh_key;
+typedef git_credential_ssh_interactive git_cred_ssh_interactive;
+typedef git_credential_ssh_custom git_cred_ssh_custom;
+
+typedef git_credential_acquire_cb git_cred_acquire_cb;
+typedef git_credential_sign_cb git_cred_sign_callback;
+typedef git_credential_sign_cb git_cred_sign_cb;
+typedef git_credential_ssh_interactive_cb git_cred_ssh_interactive_callback;
+typedef git_credential_ssh_interactive_cb git_cred_ssh_interactive_cb;
+
+#define git_credtype_t git_credential_t
+
+#define GIT_CREDTYPE_USERPASS_PLAINTEXT GIT_CREDENTIAL_USERPASS_PLAINTEXT
+#define GIT_CREDTYPE_SSH_KEY GIT_CREDENTIAL_SSH_KEY
+#define GIT_CREDTYPE_SSH_CUSTOM GIT_CREDENTIAL_SSH_CUSTOM
+#define GIT_CREDTYPE_DEFAULT GIT_CREDENTIAL_DEFAULT
+#define GIT_CREDTYPE_SSH_INTERACTIVE GIT_CREDENTIAL_SSH_INTERACTIVE
+#define GIT_CREDTYPE_USERNAME GIT_CREDENTIAL_USERNAME
+#define GIT_CREDTYPE_SSH_MEMORY GIT_CREDENTIAL_SSH_MEMORY
+
+GIT_EXTERN(void) git_cred_free(git_credential *cred);
+GIT_EXTERN(int) git_cred_has_username(git_credential *cred);
+GIT_EXTERN(const char *) git_cred_get_username(git_credential *cred);
+GIT_EXTERN(int) git_cred_userpass_plaintext_new(
+ git_credential **out,
+ const char *username,
+ const char *password);
+GIT_EXTERN(int) git_cred_default_new(git_credential **out);
+GIT_EXTERN(int) git_cred_username_new(git_credential **out, const char *username);
+GIT_EXTERN(int) git_cred_ssh_key_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ const char *privatekey,
+ const char *passphrase);
+GIT_EXTERN(int) git_cred_ssh_key_memory_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ const char *privatekey,
+ const char *passphrase);
+GIT_EXTERN(int) git_cred_ssh_interactive_new(
+ git_credential **out,
+ const char *username,
+ git_credential_ssh_interactive_cb prompt_callback,
+ void *payload);
+GIT_EXTERN(int) git_cred_ssh_key_from_agent(
+ git_credential **out,
+ const char *username);
+GIT_EXTERN(int) git_cred_ssh_custom_new(
+ git_credential **out,
+ const char *username,
+ const char *publickey,
+ size_t publickey_len,
+ git_credential_sign_cb sign_callback,
+ void *payload);
+
+/* Deprecated Credential Helper Types */
+
+typedef git_credential_userpass_payload git_cred_userpass_payload;
+
+GIT_EXTERN(int) git_cred_userpass(
+ git_credential **out,
+ const char *url,
+ const char *user_from_url,
+ unsigned int allowed_types,
+ void *payload);
+
+/**@}*/
+
+/** @name Deprecated Trace Callback Types
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+typedef git_trace_cb git_trace_callback;
+
+/**@}*/
+
+/** @name Deprecated Object ID Types
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+#ifndef GIT_EXPERIMENTAL_SHA256
+# define GIT_OID_RAWSZ GIT_OID_SHA1_SIZE
+# define GIT_OID_HEXSZ GIT_OID_SHA1_HEXSIZE
+# define GIT_OID_HEX_ZERO GIT_OID_SHA1_HEXZERO
+#endif
+
+GIT_EXTERN(int) git_oid_iszero(const git_oid *id);
+
+/**@}*/
+
+/** @name Deprecated OID Array Functions
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Free the memory referred to by the git_oidarray. This is an alias of
+ * `git_oidarray_dispose` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_oidarray_dispose
+ * @see git_oidarray_dispose
+ */
+GIT_EXTERN(void) git_oidarray_free(git_oidarray *array);
+
+/**@}*/
+
+/** @name Deprecated Transfer Progress Types
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * This structure is used to provide callers information about the
+ * progress of indexing a packfile.
+ *
+ * This type is deprecated, but there is no plan to remove this
+ * type definition at this time.
+ */
+typedef git_indexer_progress git_transfer_progress;
+
+/**
+ * Type definition for progress callbacks during indexing.
+ *
+ * This type is deprecated, but there is no plan to remove this
+ * type definition at this time.
+ */
+typedef git_indexer_progress_cb git_transfer_progress_cb;
+
+/**
+ * Type definition for push transfer progress callbacks.
+ *
+ * This type is deprecated, but there is no plan to remove this
+ * type definition at this time.
+ */
+typedef git_push_transfer_progress_cb git_push_transfer_progress;
+
+ /** The type of a remote completion event */
+#define git_remote_completion_type git_remote_completion_t
+
+/**
+ * Callback for listing the remote heads
+ */
+typedef int GIT_CALLBACK(git_headlist_cb)(git_remote_head *rhead, void *payload);
+
+/**@}*/
+
+/** @name Deprecated String Array Functions
+ *
+ * These types are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * Copy a string array object from source to target.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @param tgt target
+ * @param src source
+ * @return 0 on success, < 0 on allocation failure
+ */
+GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
+
+/**
+ * Free the memory referred to by the git_strarray. This is an alias of
+ * `git_strarray_dispose` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Use git_strarray_dispose
+ * @see git_strarray_dispose
+ */
+GIT_EXTERN(void) git_strarray_free(git_strarray *array);
+
+/**@}*/
+
+/** @name Deprecated Options Initialization Functions
+ *
+ * These functions are retained for backward compatibility. The newer
+ * versions of these functions should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility functions at
+ * this time.
+ */
+/**@{*/
+
+GIT_EXTERN(int) git_blame_init_options(git_blame_options *opts, unsigned int version);
+GIT_EXTERN(int) git_checkout_init_options(git_checkout_options *opts, unsigned int version);
+GIT_EXTERN(int) git_cherrypick_init_options(git_cherrypick_options *opts, unsigned int version);
+GIT_EXTERN(int) git_clone_init_options(git_clone_options *opts, unsigned int version);
+GIT_EXTERN(int) git_describe_init_options(git_describe_options *opts, unsigned int version);
+GIT_EXTERN(int) git_describe_init_format_options(git_describe_format_options *opts, unsigned int version);
+GIT_EXTERN(int) git_diff_init_options(git_diff_options *opts, unsigned int version);
+GIT_EXTERN(int) git_diff_find_init_options(git_diff_find_options *opts, unsigned int version);
+GIT_EXTERN(int) git_diff_format_email_init_options(git_diff_format_email_options *opts, unsigned int version);
+GIT_EXTERN(int) git_diff_patchid_init_options(git_diff_patchid_options *opts, unsigned int version);
+GIT_EXTERN(int) git_fetch_init_options(git_fetch_options *opts, unsigned int version);
+GIT_EXTERN(int) git_indexer_init_options(git_indexer_options *opts, unsigned int version);
+GIT_EXTERN(int) git_merge_init_options(git_merge_options *opts, unsigned int version);
+GIT_EXTERN(int) git_merge_file_init_input(git_merge_file_input *input, unsigned int version);
+GIT_EXTERN(int) git_merge_file_init_options(git_merge_file_options *opts, unsigned int version);
+GIT_EXTERN(int) git_proxy_init_options(git_proxy_options *opts, unsigned int version);
+GIT_EXTERN(int) git_push_init_options(git_push_options *opts, unsigned int version);
+GIT_EXTERN(int) git_rebase_init_options(git_rebase_options *opts, unsigned int version);
+GIT_EXTERN(int) git_remote_create_init_options(git_remote_create_options *opts, unsigned int version);
+GIT_EXTERN(int) git_repository_init_init_options(git_repository_init_options *opts, unsigned int version);
+GIT_EXTERN(int) git_revert_init_options(git_revert_options *opts, unsigned int version);
+GIT_EXTERN(int) git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int version);
+GIT_EXTERN(int) git_status_init_options(git_status_options *opts, unsigned int version);
+GIT_EXTERN(int) git_submodule_update_init_options(git_submodule_update_options *opts, unsigned int version);
+GIT_EXTERN(int) git_worktree_add_init_options(git_worktree_add_options *opts, unsigned int version);
+GIT_EXTERN(int) git_worktree_prune_init_options(git_worktree_prune_options *opts, unsigned int version);
+
+/**@}*/
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
+#endif
diff --git a/include/git2/describe.h b/include/git2/describe.h
new file mode 100644
index 0000000..7a796f1
--- /dev/null
+++ b/include/git2/describe.h
@@ -0,0 +1,194 @@
+/*
+ * 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_describe_h__
+#define INCLUDE_git_describe_h__
+
+#include "common.h"
+#include "types.h"
+#include "buffer.h"
+
+/**
+ * @file git2/describe.h
+ * @brief Git describing routines
+ * @defgroup git_describe Git describing routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Reference lookup strategy
+ *
+ * These behave like the --tags and --all options to git-describe,
+ * namely they say to look for any reference in either refs/tags/ or
+ * refs/ respectively.
+ */
+typedef enum {
+ GIT_DESCRIBE_DEFAULT,
+ GIT_DESCRIBE_TAGS,
+ GIT_DESCRIBE_ALL
+} git_describe_strategy_t;
+
+/**
+ * Describe options structure
+ *
+ * Initialize with `GIT_DESCRIBE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_describe_options_init`.
+ *
+ */
+typedef struct git_describe_options {
+ unsigned int version;
+
+ unsigned int max_candidates_tags; /**< default: 10 */
+ unsigned int describe_strategy; /**< default: GIT_DESCRIBE_DEFAULT */
+ const char *pattern;
+ /**
+ * When calculating the distance from the matching tag or
+ * reference, only walk down the first-parent ancestry.
+ */
+ int only_follow_first_parent;
+ /**
+ * If no matching tag or reference is found, the describe
+ * operation would normally fail. If this option is set, it
+ * will instead fall back to showing the full id of the
+ * commit.
+ */
+ int show_commit_oid_as_fallback;
+} git_describe_options;
+
+#define GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS 10
+#define GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE 7
+
+#define GIT_DESCRIBE_OPTIONS_VERSION 1
+#define GIT_DESCRIBE_OPTIONS_INIT { \
+ GIT_DESCRIBE_OPTIONS_VERSION, \
+ GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS, \
+}
+
+/**
+ * Initialize git_describe_options structure
+ *
+ * Initializes a `git_describe_options` with default values. Equivalent to creating
+ * an instance with GIT_DESCRIBE_OPTIONS_INIT.
+ *
+ * @param opts The `git_describe_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DESCRIBE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_describe_options_init(git_describe_options *opts, unsigned int version);
+
+/**
+ * Describe format options structure
+ *
+ * Initialize with `GIT_DESCRIBE_FORMAT_OPTIONS_INIT`. Alternatively, you can
+ * use `git_describe_format_options_init`.
+ *
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Size of the abbreviated commit id to use. This value is the
+ * lower bound for the length of the abbreviated string. The
+ * default is 7.
+ */
+ unsigned int abbreviated_size;
+
+ /**
+ * Set to use the long format even when a shorter name could be used.
+ */
+ int always_use_long_format;
+
+ /**
+ * If the workdir is dirty and this is set, this string will
+ * be appended to the description string.
+ */
+ const char *dirty_suffix;
+} git_describe_format_options;
+
+#define GIT_DESCRIBE_FORMAT_OPTIONS_VERSION 1
+#define GIT_DESCRIBE_FORMAT_OPTIONS_INIT { \
+ GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, \
+ GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE, \
+ }
+
+/**
+ * Initialize git_describe_format_options structure
+ *
+ * Initializes a `git_describe_format_options` with default values. Equivalent to creating
+ * an instance with GIT_DESCRIBE_FORMAT_OPTIONS_INIT.
+ *
+ * @param opts The `git_describe_format_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DESCRIBE_FORMAT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_describe_format_options_init(git_describe_format_options *opts, unsigned int version);
+
+/**
+ * A struct that stores the result of a describe operation.
+ */
+typedef struct git_describe_result git_describe_result;
+
+/**
+ * Describe a commit
+ *
+ * Perform the describe operation on the given committish object.
+ *
+ * @param result pointer to store the result. You must free this once
+ * you're done with it.
+ * @param committish a committish to describe
+ * @param opts the lookup options (or NULL for defaults)
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_describe_commit(
+ git_describe_result **result,
+ git_object *committish,
+ git_describe_options *opts);
+
+/**
+ * Describe a commit
+ *
+ * Perform the describe operation on the current commit and the
+ * worktree. After performing describe on HEAD, a status is run and the
+ * description is considered to be dirty if there are.
+ *
+ * @param out pointer to store the result. You must free this once
+ * you're done with it.
+ * @param repo the repository in which to perform the describe
+ * @param opts the lookup options (or NULL for defaults)
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_describe_workdir(
+ git_describe_result **out,
+ git_repository *repo,
+ git_describe_options *opts);
+
+/**
+ * Print the describe result to a buffer
+ *
+ * @param out The buffer to store the result
+ * @param result the result from `git_describe_commit()` or
+ * `git_describe_workdir()`.
+ * @param opts the formatting options (or NULL for defaults)
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_describe_format(
+ git_buf *out,
+ const git_describe_result *result,
+ const git_describe_format_options *opts);
+
+/**
+ * Free the describe result.
+ *
+ * @param result The result to free.
+ */
+GIT_EXTERN(void) git_describe_result_free(git_describe_result *result);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/diff.h b/include/git2/diff.h
new file mode 100644
index 0000000..384b6e7
--- /dev/null
+++ b/include/git2/diff.h
@@ -0,0 +1,1477 @@
+/*
+ * 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_diff_h__
+#define INCLUDE_git_diff_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "tree.h"
+#include "refs.h"
+
+/**
+ * @file git2/diff.h
+ * @brief Git tree and file differencing routines.
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags for diff options. A combination of these flags can be passed
+ * in via the `flags` value in the `git_diff_options`.
+ */
+typedef enum {
+ /** Normal diff, the default */
+ GIT_DIFF_NORMAL = 0,
+
+ /*
+ * Options controlling which files will be in the diff
+ */
+
+ /** Reverse the sides of the diff */
+ GIT_DIFF_REVERSE = (1u << 0),
+
+ /** Include ignored files in the diff */
+ GIT_DIFF_INCLUDE_IGNORED = (1u << 1),
+
+ /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
+ * will be marked with only a single entry in the diff; this flag
+ * adds all files under the directory as IGNORED entries, too.
+ */
+ GIT_DIFF_RECURSE_IGNORED_DIRS = (1u << 2),
+
+ /** Include untracked files in the diff */
+ GIT_DIFF_INCLUDE_UNTRACKED = (1u << 3),
+
+ /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
+ * directory will be marked with only a single entry in the diff
+ * (a la what core Git does in `git status`); this flag adds *all*
+ * files under untracked directories as UNTRACKED entries, too.
+ */
+ GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1u << 4),
+
+ /** Include unmodified files in the diff */
+ GIT_DIFF_INCLUDE_UNMODIFIED = (1u << 5),
+
+ /** Normally, a type change between files will be converted into a
+ * DELETED record for the old and an ADDED record for the new; this
+ * options enabled the generation of TYPECHANGE delta records.
+ */
+ GIT_DIFF_INCLUDE_TYPECHANGE = (1u << 6),
+
+ /** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still
+ * generally show as a DELETED blob. This flag tries to correctly
+ * label blob->tree transitions as TYPECHANGE records with new_file's
+ * mode set to tree. Note: the tree SHA will not be available.
+ */
+ GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1u << 7),
+
+ /** Ignore file mode changes */
+ GIT_DIFF_IGNORE_FILEMODE = (1u << 8),
+
+ /** Treat all submodules as unmodified */
+ GIT_DIFF_IGNORE_SUBMODULES = (1u << 9),
+
+ /** Use case insensitive filename comparisons */
+ GIT_DIFF_IGNORE_CASE = (1u << 10),
+
+ /** May be combined with `GIT_DIFF_IGNORE_CASE` to specify that a file
+ * that has changed case will be returned as an add/delete pair.
+ */
+ GIT_DIFF_INCLUDE_CASECHANGE = (1u << 11),
+
+ /** If the pathspec is set in the diff options, this flags indicates
+ * that the paths will be treated as literal paths instead of
+ * fnmatch patterns. Each path in the list must either be a full
+ * path to a file or a directory. (A trailing slash indicates that
+ * the path will _only_ match a directory). If a directory is
+ * specified, all children will be included.
+ */
+ GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1u << 12),
+
+ /** Disable updating of the `binary` flag in delta records. This is
+ * useful when iterating over a diff if you don't need hunk and data
+ * callbacks and want to avoid having to load file completely.
+ */
+ GIT_DIFF_SKIP_BINARY_CHECK = (1u << 13),
+
+ /** When diff finds an untracked directory, to match the behavior of
+ * core Git, it scans the contents for IGNORED and UNTRACKED files.
+ * If *all* contents are IGNORED, then the directory is IGNORED; if
+ * any contents are not IGNORED, then the directory is UNTRACKED.
+ * This is extra work that may not matter in many cases. This flag
+ * turns off that scan and immediately labels an untracked directory
+ * as UNTRACKED (changing the behavior to not match core Git).
+ */
+ GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
+
+ /** When diff finds a file in the working directory with stat
+ * information different from the index, but the OID ends up being the
+ * same, write the correct stat information into the index. Note:
+ * without this flag, diff will always leave the index untouched.
+ */
+ GIT_DIFF_UPDATE_INDEX = (1u << 15),
+
+ /** Include unreadable files in the diff */
+ GIT_DIFF_INCLUDE_UNREADABLE = (1u << 16),
+
+ /** Include unreadable files in the diff */
+ GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 17),
+
+ /*
+ * Options controlling how output will be generated
+ */
+
+ /** Use a heuristic that takes indentation and whitespace into account
+ * which generally can produce better diffs when dealing with ambiguous
+ * diff hunks.
+ */
+ GIT_DIFF_INDENT_HEURISTIC = (1u << 18),
+
+ /** Ignore blank lines */
+ GIT_DIFF_IGNORE_BLANK_LINES = (1u << 19),
+
+ /** Treat all files as text, disabling binary attributes & detection */
+ GIT_DIFF_FORCE_TEXT = (1u << 20),
+ /** Treat all files as binary, disabling text diffs */
+ GIT_DIFF_FORCE_BINARY = (1u << 21),
+
+ /** Ignore all whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE = (1u << 22),
+ /** Ignore changes in amount of whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1u << 23),
+ /** Ignore whitespace at end of line */
+ GIT_DIFF_IGNORE_WHITESPACE_EOL = (1u << 24),
+
+ /** When generating patch text, include the content of untracked
+ * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
+ * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that
+ * flag if you want the content of every single UNTRACKED file.
+ */
+ GIT_DIFF_SHOW_UNTRACKED_CONTENT = (1u << 25),
+
+ /** When generating output, include the names of unmodified files if
+ * they are included in the git_diff. Normally these are skipped in
+ * the formats that list files (e.g. name-only, name-status, raw).
+ * Even with this, these will not be included in patch format.
+ */
+ GIT_DIFF_SHOW_UNMODIFIED = (1u << 26),
+
+ /** Use the "patience diff" algorithm */
+ GIT_DIFF_PATIENCE = (1u << 28),
+ /** Take extra time to find minimal diff */
+ GIT_DIFF_MINIMAL = (1u << 29),
+
+ /** Include the necessary deflate / delta information so that `git-apply`
+ * can apply given diff information to binary files.
+ */
+ GIT_DIFF_SHOW_BINARY = (1u << 30)
+} git_diff_option_t;
+
+/**
+ * The diff object that contains all individual file deltas.
+ *
+ * A `diff` represents the cumulative list of differences between two
+ * snapshots of a repository (possibly filtered by a set of file name
+ * patterns).
+ *
+ * Calculating diffs is generally done in two phases: building a list of
+ * diffs then traversing it. This makes is easier to share logic across
+ * the various types of diffs (tree vs tree, workdir vs index, etc.), and
+ * also allows you to insert optional diff post-processing phases,
+ * such as rename detection, in between the steps. When you are done with
+ * a diff object, it must be freed.
+ *
+ * This is an opaque structure which will be allocated by one of the diff
+ * generator functions below (such as `git_diff_tree_to_tree`). You are
+ * responsible for releasing the object memory when done, using the
+ * `git_diff_free()` function.
+ *
+ */
+typedef struct git_diff git_diff;
+
+/**
+ * Flags for the delta object and the file objects on each side.
+ *
+ * These flags are used for both the `flags` value of the `git_diff_delta`
+ * and the flags for the `git_diff_file` objects representing the old and
+ * new sides of the delta. Values outside of this public range should be
+ * considered reserved for internal or future use.
+ */
+typedef enum {
+ GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */
+ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */
+ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */
+ GIT_DIFF_FLAG_EXISTS = (1u << 3), /**< file exists at this side of the delta */
+ GIT_DIFF_FLAG_VALID_SIZE = (1u << 4) /**< file size value is known correct */
+} git_diff_flag_t;
+
+/**
+ * What type of change is described by a git_diff_delta?
+ *
+ * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
+ * `git_diff_find_similar()` on the diff object.
+ *
+ * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
+ * in the option flags (otherwise type changes will be split into ADDED /
+ * DELETED pairs).
+ */
+typedef enum {
+ GIT_DELTA_UNMODIFIED = 0, /**< no changes */
+ GIT_DELTA_ADDED = 1, /**< entry does not exist in old version */
+ GIT_DELTA_DELETED = 2, /**< entry does not exist in new version */
+ GIT_DELTA_MODIFIED = 3, /**< entry content changed between old and new */
+ GIT_DELTA_RENAMED = 4, /**< entry was renamed between old and new */
+ GIT_DELTA_COPIED = 5, /**< entry was copied from another old entry */
+ GIT_DELTA_IGNORED = 6, /**< entry is ignored item in workdir */
+ GIT_DELTA_UNTRACKED = 7, /**< entry is untracked item in workdir */
+ GIT_DELTA_TYPECHANGE = 8, /**< type of entry changed between old and new */
+ GIT_DELTA_UNREADABLE = 9, /**< entry is unreadable */
+ GIT_DELTA_CONFLICTED = 10 /**< entry in the index is conflicted */
+} git_delta_t;
+
+/**
+ * Description of one side of a delta.
+ *
+ * Although this is called a "file", it could represent a file, a symbolic
+ * link, a submodule commit id, or even a tree (although that only if you
+ * are tracking type changes or ignored/untracked directories).
+ */
+typedef struct {
+ /**
+ * The `git_oid` of the item. If the entry represents an
+ * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta),
+ * then the oid will be zeroes.
+ */
+ git_oid id;
+
+ /**
+ * The NUL-terminated path to the entry relative to the working
+ * directory of the repository.
+ */
+ const char *path;
+
+ /**
+ * The size of the entry in bytes.
+ */
+ git_object_size_t size;
+
+ /**
+ * A combination of the `git_diff_flag_t` types
+ */
+ uint32_t flags;
+
+ /**
+ * Roughly, the stat() `st_mode` value for the item. This will
+ * be restricted to one of the `git_filemode_t` values.
+ */
+ uint16_t mode;
+
+ /**
+ * Represents the known length of the `id` field, when
+ * converted to a hex string. It is generally `GIT_OID_SHA1_HEXSIZE`, unless this
+ * delta was created from reading a patch file, in which case it may be
+ * abbreviated to something reasonable, like 7 characters.
+ */
+ uint16_t id_abbrev;
+} git_diff_file;
+
+/**
+ * Description of changes to one entry.
+ *
+ * A `delta` is a file pair with an old and new revision. The old version
+ * may be absent if the file was just created and the new version may be
+ * absent if the file was deleted. A diff is mostly just a list of deltas.
+ *
+ * When iterating over a diff, this will be passed to most callbacks and
+ * you can use the contents to understand exactly what has changed.
+ *
+ * The `old_file` represents the "from" side of the diff and the `new_file`
+ * represents to "to" side of the diff. What those means depend on the
+ * function that was used to generate the diff and will be documented below.
+ * You can also use the `GIT_DIFF_REVERSE` flag to flip it around.
+ *
+ * Although the two sides of the delta are named "old_file" and "new_file",
+ * they actually may correspond to entries that represent a file, a symbolic
+ * link, a submodule commit id, or even a tree (if you are tracking type
+ * changes or ignored/untracked directories).
+ *
+ * Under some circumstances, in the name of efficiency, not all fields will
+ * be filled in, but we generally try to fill in as much as possible. One
+ * example is that the "flags" field may not have either the `BINARY` or the
+ * `NOT_BINARY` flag set to avoid examining file contents if you do not pass
+ * in hunk and/or line callbacks to the diff foreach iteration function. It
+ * will just use the git attributes for those files.
+ *
+ * The similarity score is zero unless you call `git_diff_find_similar()`
+ * which does a similarity analysis of files in the diff. Use that
+ * function to do rename and copy detection, and to split heavily modified
+ * files in add/delete pairs. After that call, deltas with a status of
+ * GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score
+ * between 0 and 100 indicating how similar the old and new sides are.
+ *
+ * If you ask `git_diff_find_similar` to find heavily modified files to
+ * break, but to not *actually* break the records, then GIT_DELTA_MODIFIED
+ * records may have a non-zero similarity score if the self-similarity is
+ * below the split threshold. To display this value like core Git, invert
+ * the score (a la `printf("M%03d", 100 - delta->similarity)`).
+ */
+typedef struct {
+ git_delta_t status;
+ uint32_t flags; /**< git_diff_flag_t values */
+ uint16_t similarity; /**< for RENAMED and COPIED, value 0-100 */
+ uint16_t nfiles; /**< number of files in this delta */
+ git_diff_file old_file;
+ git_diff_file new_file;
+} git_diff_delta;
+
+/**
+ * Diff notification callback function.
+ *
+ * The callback will be called for each file, just before the `git_diff_delta`
+ * gets inserted into the diff.
+ *
+ * When the callback:
+ * - returns < 0, the diff process will be aborted.
+ * - returns > 0, the delta will not be inserted into the diff, but the
+ * diff process continues.
+ * - returns 0, the delta is inserted into the diff, and the diff process
+ * continues.
+ */
+typedef int GIT_CALLBACK(git_diff_notify_cb)(
+ const git_diff *diff_so_far,
+ const git_diff_delta *delta_to_add,
+ const char *matched_pathspec,
+ void *payload);
+
+/**
+ * Diff progress callback.
+ *
+ * Called before each file comparison.
+ *
+ * @param diff_so_far The diff being generated.
+ * @param old_path The path to the old file or NULL.
+ * @param new_path The path to the new file or NULL.
+ * @return Non-zero to abort the diff.
+ */
+typedef int GIT_CALLBACK(git_diff_progress_cb)(
+ const git_diff *diff_so_far,
+ const char *old_path,
+ const char *new_path,
+ void *payload);
+
+/**
+ * Structure describing options about how the diff should be executed.
+ *
+ * Setting all values of the structure to zero will yield the default
+ * values. Similarly, passing NULL for the options structure will
+ * give the defaults. The default values are marked below.
+ *
+ */
+typedef struct {
+ unsigned int version; /**< version for the struct */
+
+ /**
+ * A combination of `git_diff_option_t` values above.
+ * Defaults to GIT_DIFF_NORMAL
+ */
+ uint32_t flags;
+
+ /* options controlling which files are in the diff */
+
+ /** Overrides the submodule ignore setting for all submodules in the diff. */
+ git_submodule_ignore_t ignore_submodules;
+
+ /**
+ * An array of paths / fnmatch patterns to constrain diff.
+ * All paths are included by default.
+ */
+ git_strarray pathspec;
+
+ /**
+ * An optional callback function, notifying the consumer of changes to
+ * the diff as new deltas are added.
+ */
+ git_diff_notify_cb notify_cb;
+
+ /**
+ * An optional callback function, notifying the consumer of which files
+ * are being examined as the diff is generated.
+ */
+ git_diff_progress_cb progress_cb;
+
+ /** The payload to pass to the callback functions. */
+ void *payload;
+
+ /* options controlling how to diff text is generated */
+
+ /**
+ * The number of unchanged lines that define the boundary of a hunk
+ * (and to display before and after). Defaults to 3.
+ */
+ uint32_t context_lines;
+ /**
+ * The maximum number of unchanged lines between hunk boundaries before
+ * the hunks will be merged into one. Defaults to 0.
+ */
+ uint32_t interhunk_lines;
+
+ /**
+ * The object ID type to emit in diffs; this is used by functions
+ * that operate without a repository - namely `git_diff_buffers`,
+ * or `git_diff_blobs` and `git_diff_blob_to_buffer` when one blob
+ * is `NULL`.
+ *
+ * This may be omitted (set to `0`). If a repository is available,
+ * the object ID format of the repository will be used. If no
+ * repository is available then the default is `GIT_OID_SHA`.
+ *
+ * If this is specified and a repository is available, then the
+ * specified `oid_type` must match the repository's object ID
+ * format.
+ */
+ git_oid_t oid_type;
+
+ /**
+ * The abbreviation length to use when formatting object ids.
+ * Defaults to the value of 'core.abbrev' from the config, or 7 if unset.
+ */
+ uint16_t id_abbrev;
+
+ /**
+ * A size (in bytes) above which a blob will be marked as binary
+ * automatically; pass a negative value to disable.
+ * Defaults to 512MB.
+ */
+ git_off_t max_size;
+
+ /**
+ * The virtual "directory" prefix for old file names in hunk headers.
+ * Default is "a".
+ */
+ const char *old_prefix;
+
+ /**
+ * The virtual "directory" prefix for new file names in hunk headers.
+ * Defaults to "b".
+ */
+ const char *new_prefix;
+} git_diff_options;
+
+/* The current version of the diff options structure */
+#define GIT_DIFF_OPTIONS_VERSION 1
+
+/* Stack initializer for diff options. Alternatively use
+ * `git_diff_options_init` programmatic initialization.
+ */
+#define GIT_DIFF_OPTIONS_INIT \
+ {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3}
+
+/**
+ * Initialize git_diff_options structure
+ *
+ * Initializes a `git_diff_options` with default values. Equivalent to creating
+ * an instance with GIT_DIFF_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DIFF_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_options_init(
+ git_diff_options *opts,
+ unsigned int version);
+
+/**
+ * When iterating over a diff, callback that will be made per file.
+ *
+ * @param delta A pointer to the delta data for the file
+ * @param progress Goes from 0 to 1 over the diff
+ * @param payload User-specified pointer from foreach function
+ */
+typedef int GIT_CALLBACK(git_diff_file_cb)(
+ const git_diff_delta *delta,
+ float progress,
+ void *payload);
+
+#define GIT_DIFF_HUNK_HEADER_SIZE 128
+
+/**
+ * When producing a binary diff, the binary data returned will be
+ * either the deflated full ("literal") contents of the file, or
+ * the deflated binary delta between the two sides (whichever is
+ * smaller).
+ */
+typedef enum {
+ /** There is no binary delta. */
+ GIT_DIFF_BINARY_NONE,
+
+ /** The binary data is the literal contents of the file. */
+ GIT_DIFF_BINARY_LITERAL,
+
+ /** The binary data is the delta from one side to the other. */
+ GIT_DIFF_BINARY_DELTA
+} git_diff_binary_t;
+
+/** The contents of one of the files in a binary diff. */
+typedef struct {
+ /** The type of binary data for this file. */
+ git_diff_binary_t type;
+
+ /** The binary data, deflated. */
+ const char *data;
+
+ /** The length of the binary data. */
+ size_t datalen;
+
+ /** The length of the binary data after inflation. */
+ size_t inflatedlen;
+} git_diff_binary_file;
+
+/**
+ * Structure describing the binary contents of a diff.
+ *
+ * A `binary` file / delta is a file (or pair) for which no text diffs
+ * should be generated. A diff can contain delta entries that are
+ * binary, but no diff content will be output for those files. There is
+ * a base heuristic for binary detection and you can further tune the
+ * behavior with git attributes or diff flags and option settings.
+ */
+typedef struct {
+ /**
+ * Whether there is data in this binary structure or not.
+ *
+ * If this is `1`, then this was produced and included binary content.
+ * If this is `0` then this was generated knowing only that a binary
+ * file changed but without providing the data, probably from a patch
+ * that said `Binary files a/file.txt and b/file.txt differ`.
+ */
+ unsigned int contains_data;
+ git_diff_binary_file old_file; /**< The contents of the old file. */
+ git_diff_binary_file new_file; /**< The contents of the new file. */
+} git_diff_binary;
+
+/**
+ * When iterating over a diff, callback that will be made for
+ * binary content within the diff.
+ */
+typedef int GIT_CALLBACK(git_diff_binary_cb)(
+ const git_diff_delta *delta,
+ const git_diff_binary *binary,
+ void *payload);
+
+/**
+ * Structure describing a hunk of a diff.
+ *
+ * A `hunk` is a span of modified lines in a delta along with some stable
+ * surrounding context. You can configure the amount of context and other
+ * properties of how hunks are generated. Each hunk also comes with a
+ * header that described where it starts and ends in both the old and new
+ * versions in the delta.
+ */
+typedef struct {
+ int old_start; /**< Starting line number in old_file */
+ int old_lines; /**< Number of lines in old_file */
+ int new_start; /**< Starting line number in new_file */
+ int new_lines; /**< Number of lines in new_file */
+ size_t header_len; /**< Number of bytes in header text */
+ char header[GIT_DIFF_HUNK_HEADER_SIZE]; /**< Header text, NUL-byte terminated */
+} git_diff_hunk;
+
+/**
+ * When iterating over a diff, callback that will be made per hunk.
+ */
+typedef int GIT_CALLBACK(git_diff_hunk_cb)(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ void *payload);
+
+/**
+ * Line origin constants.
+ *
+ * These values describe where a line came from and will be passed to
+ * the git_diff_line_cb when iterating over a diff. There are some
+ * special origin constants at the end that are used for the text
+ * output callbacks to demarcate lines that are actually part of
+ * the file or hunk headers.
+ */
+typedef enum {
+ /* These values will be sent to `git_diff_line_cb` along with the line */
+ GIT_DIFF_LINE_CONTEXT = ' ',
+ GIT_DIFF_LINE_ADDITION = '+',
+ GIT_DIFF_LINE_DELETION = '-',
+
+ GIT_DIFF_LINE_CONTEXT_EOFNL = '=', /**< Both files have no LF at end */
+ GIT_DIFF_LINE_ADD_EOFNL = '>', /**< Old has no LF at end, new does */
+ GIT_DIFF_LINE_DEL_EOFNL = '<', /**< Old has LF at end, new does not */
+
+ /* The following values will only be sent to a `git_diff_line_cb` when
+ * the content of a diff is being formatted through `git_diff_print`.
+ */
+ GIT_DIFF_LINE_FILE_HDR = 'F',
+ GIT_DIFF_LINE_HUNK_HDR = 'H',
+ GIT_DIFF_LINE_BINARY = 'B' /**< For "Binary files x and y differ" */
+} git_diff_line_t;
+
+/**
+ * Structure describing a line (or data span) of a diff.
+ *
+ * A `line` is a range of characters inside a hunk. It could be a context
+ * line (i.e. in both old and new versions), an added line (i.e. only in
+ * the new version), or a removed line (i.e. only in the old version).
+ * Unfortunately, we don't know anything about the encoding of data in the
+ * file being diffed, so we cannot tell you much about the line content.
+ * Line data will not be NUL-byte terminated, however, because it will be
+ * just a span of bytes inside the larger file.
+ */
+typedef struct {
+ char origin; /**< A git_diff_line_t value */
+ int old_lineno; /**< Line number in old file or -1 for added line */
+ int new_lineno; /**< Line number in new file or -1 for deleted line */
+ int num_lines; /**< Number of newline characters in content */
+ size_t content_len; /**< Number of bytes of data */
+ git_off_t content_offset; /**< Offset in the original file to the content */
+ const char *content; /**< Pointer to diff text, not NUL-byte terminated */
+} git_diff_line;
+
+/**
+ * When iterating over a diff, callback that will be made per text diff
+ * line. In this context, the provided range will be NULL.
+ *
+ * When printing a diff, callback that will be made to output each line
+ * of text. This uses some extra GIT_DIFF_LINE_... constants for output
+ * of lines of file and hunk headers.
+ */
+typedef int GIT_CALLBACK(git_diff_line_cb)(
+ const git_diff_delta *delta, /**< delta that contains this data */
+ const git_diff_hunk *hunk, /**< hunk containing this data */
+ const git_diff_line *line, /**< line data */
+ void *payload); /**< user reference data */
+
+/**
+ * Flags to control the behavior of diff rename/copy detection.
+ */
+typedef enum {
+ /** Obey `diff.renames`. Overridden by any other GIT_DIFF_FIND_... flag. */
+ GIT_DIFF_FIND_BY_CONFIG = 0,
+
+ /** Look for renames? (`--find-renames`) */
+ GIT_DIFF_FIND_RENAMES = (1u << 0),
+
+ /** Consider old side of MODIFIED for renames? (`--break-rewrites=N`) */
+ GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1u << 1),
+
+ /** Look for copies? (a la `--find-copies`). */
+ GIT_DIFF_FIND_COPIES = (1u << 2),
+
+ /** Consider UNMODIFIED as copy sources? (`--find-copies-harder`).
+ *
+ * For this to work correctly, use GIT_DIFF_INCLUDE_UNMODIFIED when
+ * the initial `git_diff` is being generated.
+ */
+ GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1u << 3),
+
+ /** Mark significant rewrites for split (`--break-rewrites=/M`) */
+ GIT_DIFF_FIND_REWRITES = (1u << 4),
+ /** Actually split large rewrites into delete/add pairs */
+ GIT_DIFF_BREAK_REWRITES = (1u << 5),
+ /** Mark rewrites for split and break into delete/add pairs */
+ GIT_DIFF_FIND_AND_BREAK_REWRITES =
+ (GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES),
+
+ /** Find renames/copies for UNTRACKED items in working directory.
+ *
+ * For this to work correctly, use GIT_DIFF_INCLUDE_UNTRACKED when the
+ * initial `git_diff` is being generated (and obviously the diff must
+ * be against the working directory for this to make sense).
+ */
+ GIT_DIFF_FIND_FOR_UNTRACKED = (1u << 6),
+
+ /** Turn on all finding features. */
+ GIT_DIFF_FIND_ALL = (0x0ff),
+
+ /** Measure similarity ignoring leading whitespace (default) */
+ GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
+ /** Measure similarity ignoring all whitespace */
+ GIT_DIFF_FIND_IGNORE_WHITESPACE = (1u << 12),
+ /** Measure similarity including all data */
+ GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1u << 13),
+ /** Measure similarity only by comparing SHAs (fast and cheap) */
+ GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1u << 14),
+
+ /** Do not break rewrites unless they contribute to a rename.
+ *
+ * Normally, GIT_DIFF_FIND_AND_BREAK_REWRITES will measure the self-
+ * similarity of modified files and split the ones that have changed a
+ * lot into a DELETE / ADD pair. Then the sides of that pair will be
+ * considered candidates for rename and copy detection.
+ *
+ * If you add this flag in and the split pair is *not* used for an
+ * actual rename or copy, then the modified record will be restored to
+ * a regular MODIFIED record instead of being split.
+ */
+ GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1u << 15),
+
+ /** Remove any UNMODIFIED deltas after find_similar is done.
+ *
+ * Using GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED to emulate the
+ * --find-copies-harder behavior requires building a diff with the
+ * GIT_DIFF_INCLUDE_UNMODIFIED flag. If you do not want UNMODIFIED
+ * records in the final result, pass this flag to have them removed.
+ */
+ GIT_DIFF_FIND_REMOVE_UNMODIFIED = (1u << 16)
+} git_diff_find_t;
+
+/**
+ * Pluggable similarity metric
+ */
+typedef struct {
+ int GIT_CALLBACK(file_signature)(
+ void **out, const git_diff_file *file,
+ const char *fullpath, void *payload);
+ int GIT_CALLBACK(buffer_signature)(
+ void **out, const git_diff_file *file,
+ const char *buf, size_t buflen, void *payload);
+ void GIT_CALLBACK(free_signature)(void *sig, void *payload);
+ int GIT_CALLBACK(similarity)(int *score, void *siga, void *sigb, void *payload);
+ void *payload;
+} git_diff_similarity_metric;
+
+/**
+ * Control behavior of rename and copy detection
+ *
+ * These options mostly mimic parameters that can be passed to git-diff.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Combination of git_diff_find_t values (default GIT_DIFF_FIND_BY_CONFIG).
+ * NOTE: if you don't explicitly set this, `diff.renames` could be set
+ * to false, resulting in `git_diff_find_similar` doing nothing.
+ */
+ uint32_t flags;
+
+ /**
+ * Threshold above which similar files will be considered renames.
+ * This is equivalent to the -M option. Defaults to 50.
+ */
+ uint16_t rename_threshold;
+
+ /**
+ * Threshold below which similar files will be eligible to be a rename source.
+ * This is equivalent to the first part of the -B option. Defaults to 50.
+ */
+ uint16_t rename_from_rewrite_threshold;
+
+ /**
+ * Threshold above which similar files will be considered copies.
+ * This is equivalent to the -C option. Defaults to 50.
+ */
+ uint16_t copy_threshold;
+
+ /**
+ * Threshold below which similar files will be split into a delete/add pair.
+ * This is equivalent to the last part of the -B option. Defaults to 60.
+ */
+ uint16_t break_rewrite_threshold;
+
+ /**
+ * Maximum number of matches to consider for a particular file.
+ *
+ * This is a little different from the `-l` option from Git because we
+ * will still process up to this many matches before abandoning the search.
+ * Defaults to 1000.
+ */
+ size_t rename_limit;
+
+ /**
+ * The `metric` option allows you to plug in a custom similarity metric.
+ *
+ * Set it to NULL to use the default internal metric.
+ *
+ * The default metric is based on sampling hashes of ranges of data in
+ * the file, which is a pretty good similarity approximation that should
+ * work fairly well for both text and binary data while still being
+ * pretty fast with a fixed memory overhead.
+ */
+ git_diff_similarity_metric *metric;
+} git_diff_find_options;
+
+#define GIT_DIFF_FIND_OPTIONS_VERSION 1
+#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
+
+/**
+ * Initialize git_diff_find_options structure
+ *
+ * Initializes a `git_diff_find_options` with default values. Equivalent to creating
+ * an instance with GIT_DIFF_FIND_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_find_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DIFF_FIND_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_find_options_init(
+ git_diff_find_options *opts,
+ unsigned int version);
+
+/** @name Diff Generator Functions
+ *
+ * These are the functions you would use to create (or destroy) a
+ * git_diff from various objects in a repository.
+ */
+/**@{*/
+
+/**
+ * Deallocate a diff.
+ *
+ * @param diff The previously created diff; cannot be used after free.
+ */
+GIT_EXTERN(void) git_diff_free(git_diff *diff);
+
+/**
+ * Create a diff with the difference between two tree objects.
+ *
+ * This is equivalent to `git diff <old-tree> <new-tree>`
+ *
+ * The first tree will be used for the "old_file" side of the delta and the
+ * second tree will be used for the "new_file" side of the delta. You can
+ * pass NULL to indicate an empty tree, although it is an error to pass
+ * NULL for both the `old_tree` and `new_tree`.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the trees.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param new_tree A git_tree object to diff to, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_tree_to_tree(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ git_tree *new_tree,
+ const git_diff_options *opts);
+
+/**
+ * Create a diff between a tree and repository index.
+ *
+ * This is equivalent to `git diff --cached <treeish>` or if you pass
+ * the HEAD tree, then like `git diff --cached`.
+ *
+ * The tree you pass will be used for the "old_file" side of the delta, and
+ * the index will be used for the "new_file" side of the delta.
+ *
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used. In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the tree and index.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param index The index to diff with; repo index used if NULL.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_tree_to_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ git_index *index,
+ const git_diff_options *opts);
+
+/**
+ * Create a diff between the repository index and the workdir directory.
+ *
+ * This matches the `git diff` command. See the note below on
+ * `git_diff_tree_to_workdir` for a discussion of the difference between
+ * `git diff` and `git diff HEAD` and how to emulate a `git diff <treeish>`
+ * using libgit2.
+ *
+ * The index will be used for the "old_file" side of the delta, and the
+ * working directory will be used for the "new_file" side of the delta.
+ *
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used. In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository.
+ * @param index The index to diff from; repo index used if NULL.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_index_to_workdir(
+ git_diff **diff,
+ git_repository *repo,
+ git_index *index,
+ const git_diff_options *opts);
+
+/**
+ * Create a diff between a tree and the working directory.
+ *
+ * The tree you provide will be used for the "old_file" side of the delta,
+ * and the working directory will be used for the "new_file" side.
+ *
+ * This is not the same as `git diff <treeish>` or `git diff-index
+ * <treeish>`. Those commands use information from the index, whereas this
+ * function strictly returns the differences between the tree and the files
+ * in the working directory, regardless of the state of the index. Use
+ * `git_diff_tree_to_workdir_with_index` to emulate those commands.
+ *
+ * To see difference between this and `git_diff_tree_to_workdir_with_index`,
+ * consider the example of a staged file deletion where the file has then
+ * been put back into the working dir and further modified. The
+ * tree-to-workdir diff for that file is 'modified', but `git diff` would
+ * show status 'deleted' since there is a staged delete.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ const git_diff_options *opts);
+
+/**
+ * Create a diff between a tree and the working directory using index data
+ * to account for staged deletes, tracked files, etc.
+ *
+ * This emulates `git diff <tree>` by diffing the tree to the index and
+ * the index to the working directory and blending the results into a
+ * single diff that includes staged deleted, etc.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir_with_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ const git_diff_options *opts);
+
+/**
+ * Create a diff with the difference between two index objects.
+ *
+ * The first index will be used for the "old_file" side of the delta and the
+ * second index will be used for the "new_file" side of the delta.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the indexes.
+ * @param old_index A git_index object to diff from.
+ * @param new_index A git_index object to diff to.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_index_to_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_index *old_index,
+ git_index *new_index,
+ const git_diff_options *opts);
+
+/**
+ * Merge one diff into another.
+ *
+ * This merges items from the "from" list into the "onto" list. The
+ * resulting diff will have all items that appear in either list.
+ * If an item appears in both lists, then it will be "merged" to appear
+ * as if the old version was from the "onto" list and the new version
+ * is from the "from" list (with the exception that if the item has a
+ * pending DELETE in the middle, then it will show as deleted).
+ *
+ * @param onto Diff to merge into.
+ * @param from Diff to merge.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_diff_merge(
+ git_diff *onto,
+ const git_diff *from);
+
+/**
+ * Transform a diff marking file renames, copies, etc.
+ *
+ * This modifies a diff in place, replacing old entries that look
+ * like renames or copies with new entries reflecting those changes.
+ * This also will, if requested, break modified files into add/remove
+ * pairs if the amount of change is above a threshold.
+ *
+ * @param diff diff to run detection algorithms on
+ * @param options Control how detection should be run, NULL for defaults
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_diff_find_similar(
+ git_diff *diff,
+ const git_diff_find_options *options);
+
+/**@}*/
+
+
+/** @name Diff Processor Functions
+ *
+ * These are the functions you apply to a diff to process it
+ * or read it in some way.
+ */
+/**@{*/
+
+/**
+ * Query how many diff records are there in a diff.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @return Count of number of deltas in the list
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas(const git_diff *diff);
+
+/**
+ * Query how many diff deltas are there in a diff filtered by type.
+ *
+ * This works just like `git_diff_num_deltas()` with an extra parameter
+ * that is a `git_delta_t` and returns just the count of how many deltas
+ * match that particular type.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @param type A git_delta_t value to filter the count
+ * @return Count of number of deltas matching delta_t type
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
+ const git_diff *diff, git_delta_t type);
+
+/**
+ * Return the diff delta for an entry in the diff list.
+ *
+ * The `git_diff_delta` pointer points to internal data and you do not
+ * have to release it when you are done with it. It will go away when
+ * the * `git_diff` (or any associated `git_patch`) goes away.
+ *
+ * Note that the flags on the delta related to whether it has binary
+ * content or not may not be set if there are no attributes set for the
+ * file and there has been no reason to load the file data at this point.
+ * For now, if you need those flags to be up to date, your only option is
+ * to either use `git_diff_foreach` or create a `git_patch`.
+ *
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return Pointer to git_diff_delta (or NULL if `idx` out of range)
+ */
+GIT_EXTERN(const git_diff_delta *) git_diff_get_delta(
+ const git_diff *diff, size_t idx);
+
+/**
+ * Check if deltas are sorted case sensitively or insensitively.
+ *
+ * @param diff diff to check
+ * @return 0 if case sensitive, 1 if case is ignored
+ */
+GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
+
+/**
+ * Loop over all deltas in a diff issuing callbacks.
+ *
+ * This will iterate through all of the files described in a diff. You
+ * should provide a file callback to learn about each file.
+ *
+ * The "hunk" and "line" callbacks are optional, and the text diff of the
+ * files will only be calculated if they are not NULL. Of course, these
+ * callbacks will not be invoked for binary files on the diff or for
+ * files whose only changed is a file mode change.
+ *
+ * Returning a non-zero value from any of the callbacks will terminate
+ * the iteration and return the value to the user.
+ *
+ * @param diff A git_diff generated by one of the above functions.
+ * @param file_cb Callback function to make per file in the diff.
+ * @param binary_cb Optional callback to make for binary files.
+ * @param hunk_cb Optional callback to make per hunk of text diff. This
+ * callback is called to describe a range of lines in the
+ * diff. It will not be issued for binary files.
+ * @param line_cb Optional callback to make per line of diff text. This
+ * same callback will be made for context lines, added, and
+ * removed lines, and even for a deleted trailing newline.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_foreach(
+ git_diff *diff,
+ git_diff_file_cb file_cb,
+ git_diff_binary_cb binary_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
+
+/**
+ * Look up the single character abbreviation for a delta status code.
+ *
+ * When you run `git diff --name-status` it uses single letter codes in
+ * the output such as 'A' for added, 'D' for deleted, 'M' for modified,
+ * etc. This function converts a git_delta_t value into these letters for
+ * your own purposes. GIT_DELTA_UNTRACKED will return a space (i.e. ' ').
+ *
+ * @param status The git_delta_t value to look up
+ * @return The single character label for that code
+ */
+GIT_EXTERN(char) git_diff_status_char(git_delta_t status);
+
+/**
+ * Possible output formats for diff data
+ */
+typedef enum {
+ GIT_DIFF_FORMAT_PATCH = 1u, /**< full git diff */
+ GIT_DIFF_FORMAT_PATCH_HEADER = 2u, /**< just the file headers of patch */
+ GIT_DIFF_FORMAT_RAW = 3u, /**< like git diff --raw */
+ GIT_DIFF_FORMAT_NAME_ONLY = 4u, /**< like git diff --name-only */
+ GIT_DIFF_FORMAT_NAME_STATUS = 5u, /**< like git diff --name-status */
+ GIT_DIFF_FORMAT_PATCH_ID = 6u /**< git diff as used by git patch-id */
+} git_diff_format_t;
+
+/**
+ * Iterate over a diff generating formatted text output.
+ *
+ * Returning a non-zero value from the callbacks will terminate the
+ * iteration and return the non-zero value to the caller.
+ *
+ * @param diff A git_diff generated by one of the above functions.
+ * @param format A git_diff_format_t value to pick the text format.
+ * @param print_cb Callback to make per line of diff text.
+ * @param payload Reference pointer that will be passed to your callback.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_print(
+ git_diff *diff,
+ git_diff_format_t format,
+ git_diff_line_cb print_cb,
+ void *payload);
+
+/**
+ * Produce the complete formatted text output from a diff into a
+ * buffer.
+ *
+ * @param out A pointer to a user-allocated git_buf that will
+ * contain the diff text
+ * @param diff A git_diff generated by one of the above functions.
+ * @param format A git_diff_format_t value to pick the text format.
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_diff_to_buf(
+ git_buf *out,
+ git_diff *diff,
+ git_diff_format_t format);
+
+/**@}*/
+
+/*
+ * Low-level file comparison, invoking callbacks per difference.
+ */
+
+/**
+ * Directly run a diff on two blobs.
+ *
+ * Compared to a file, a blob lacks some contextual information. As such,
+ * the `git_diff_file` given to the callback will have some fake data; i.e.
+ * `mode` will be 0 and `path` will be NULL.
+ *
+ * NULL is allowed for either `old_blob` or `new_blob` and will be treated
+ * as an empty blob, with the `oid` set to NULL in the `git_diff_file` data.
+ * Passing NULL for both blobs is a noop; no callbacks will be made at all.
+ *
+ * We do run a binary content check on the blob content and if either blob
+ * looks like binary data, the `git_diff_delta` binary attribute will be set
+ * to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass
+ * `GIT_DIFF_FORCE_TEXT` of course).
+ *
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param new_as_path Treat new blob as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_blobs(
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const git_blob *new_blob,
+ const char *new_as_path,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_binary_cb binary_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
+
+/**
+ * Directly run a diff between a blob and a buffer.
+ *
+ * As with `git_diff_blobs`, comparing a blob and buffer lacks some context,
+ * so the `git_diff_file` parameters to the callbacks will be faked a la the
+ * rules for `git_diff_blobs()`.
+ *
+ * Passing NULL for `old_blob` will be treated as an empty blob (i.e. the
+ * `file_cb` will be invoked with GIT_DELTA_ADDED and the diff will be the
+ * entire content of the buffer added). Passing NULL to the buffer will do
+ * the reverse, with GIT_DELTA_REMOVED and blob content removed.
+ *
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param buffer Raw data for new side of diff, or NULL for empty
+ * @param buffer_len Length of raw data for new side of diff
+ * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_blob_to_buffer(
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const char *buffer,
+ size_t buffer_len,
+ const char *buffer_as_path,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_binary_cb binary_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
+
+/**
+ * Directly run a diff between two buffers.
+ *
+ * Even more than with `git_diff_blobs`, comparing two buffer lacks
+ * context, so the `git_diff_file` parameters to the callbacks will be
+ * faked a la the rules for `git_diff_blobs()`.
+ *
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_buffers(
+ const void *old_buffer,
+ size_t old_len,
+ const char *old_as_path,
+ const void *new_buffer,
+ size_t new_len,
+ const char *new_as_path,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_binary_cb binary_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
+
+/* Patch file parsing. */
+
+/**
+ * Options for parsing a diff / patch file.
+ */
+typedef struct {
+ unsigned int version;
+ git_oid_t oid_type;
+} git_diff_parse_options;
+
+/* The current version of the diff parse options structure */
+#define GIT_DIFF_PARSE_OPTIONS_VERSION 1
+
+/* Stack initializer for diff parse options. Alternatively use
+ * `git_diff_parse_options_init` programmatic initialization.
+ */
+#define GIT_DIFF_PARSE_OPTIONS_INIT \
+ { GIT_DIFF_PARSE_OPTIONS_VERSION, GIT_OID_DEFAULT }
+
+/**
+ * Read the contents of a git patch file into a `git_diff` object.
+ *
+ * The diff object produced is similar to the one that would be
+ * produced if you actually produced it computationally by comparing
+ * two trees, however there may be subtle differences. For example,
+ * a patch file likely contains abbreviated object IDs, so the
+ * object IDs in a `git_diff_delta` produced by this function will
+ * also be abbreviated.
+ *
+ * This function will only read patch files created by a git
+ * implementation, it will not read unified diffs produced by
+ * the `diff` program, nor any other types of patch files.
+ *
+ * @param out A pointer to a git_diff pointer that will be allocated.
+ * @param content The contents of a patch file
+ * @param content_len The length of the patch file contents
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_diff_from_buffer(
+ git_diff **out,
+ const char *content,
+ size_t content_len
+#ifdef GIT_EXPERIMENTAL_SHA256
+ , git_diff_parse_options *opts
+#endif
+ );
+
+/**
+ * This is an opaque structure which is allocated by `git_diff_get_stats`.
+ * You are responsible for releasing the object memory when done, using the
+ * `git_diff_stats_free()` function.
+ */
+typedef struct git_diff_stats git_diff_stats;
+
+/**
+ * Formatting options for diff stats
+ */
+typedef enum {
+ /** No stats*/
+ GIT_DIFF_STATS_NONE = 0,
+
+ /** Full statistics, equivalent of `--stat` */
+ GIT_DIFF_STATS_FULL = (1u << 0),
+
+ /** Short statistics, equivalent of `--shortstat` */
+ GIT_DIFF_STATS_SHORT = (1u << 1),
+
+ /** Number statistics, equivalent of `--numstat` */
+ GIT_DIFF_STATS_NUMBER = (1u << 2),
+
+ /** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */
+ GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3)
+} git_diff_stats_format_t;
+
+/**
+ * Accumulate diff statistics for all patches.
+ *
+ * @param out Structure containing the diff statistics.
+ * @param diff A git_diff generated by one of the above functions.
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_get_stats(
+ git_diff_stats **out,
+ git_diff *diff);
+
+/**
+ * Get the total number of files changed in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of files changed in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_files_changed(
+ const git_diff_stats *stats);
+
+/**
+ * Get the total number of insertions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of insertions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_insertions(
+ const git_diff_stats *stats);
+
+/**
+ * Get the total number of deletions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of deletions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_deletions(
+ const git_diff_stats *stats);
+
+/**
+ * Print diff statistics to a `git_buf`.
+ *
+ * @param out buffer to store the formatted diff statistics in.
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @param format Formatting option.
+ * @param width Target width for output (only affects GIT_DIFF_STATS_FULL)
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_stats_to_buf(
+ git_buf *out,
+ const git_diff_stats *stats,
+ git_diff_stats_format_t format,
+ size_t width);
+
+/**
+ * Deallocate a `git_diff_stats`.
+ *
+ * @param stats The previously created statistics object;
+ * cannot be used after free.
+ */
+GIT_EXTERN(void) git_diff_stats_free(git_diff_stats *stats);
+
+/**
+ * Patch ID options structure
+ *
+ * Initialize with `GIT_PATCHID_OPTIONS_INIT`. Alternatively, you can
+ * use `git_diff_patchid_options_init`.
+ *
+ */
+typedef struct git_diff_patchid_options {
+ unsigned int version;
+} git_diff_patchid_options;
+
+#define GIT_DIFF_PATCHID_OPTIONS_VERSION 1
+#define GIT_DIFF_PATCHID_OPTIONS_INIT { GIT_DIFF_PATCHID_OPTIONS_VERSION }
+
+/**
+ * Initialize git_diff_patchid_options structure
+ *
+ * Initializes a `git_diff_patchid_options` with default values. Equivalent to
+ * creating an instance with `GIT_DIFF_PATCHID_OPTIONS_INIT`.
+ *
+ * @param opts The `git_diff_patchid_options` struct to initialize.
+ * @param version The struct version; pass `GIT_DIFF_PATCHID_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_patchid_options_init(
+ git_diff_patchid_options *opts,
+ unsigned int version);
+
+/**
+ * Calculate the patch ID for the given patch.
+ *
+ * Calculate a stable patch ID for the given patch by summing the
+ * hash of the file diffs, ignoring whitespace and line numbers.
+ * This can be used to derive whether two diffs are the same with
+ * a high probability.
+ *
+ * Currently, this function only calculates stable patch IDs, as
+ * defined in git-patch-id(1), and should in fact generate the
+ * same IDs as the upstream git project does.
+ *
+ * @param out Pointer where the calculated patch ID should be stored
+ * @param diff The diff to calculate the ID for
+ * @param opts Options for how to calculate the patch ID. This is
+ * intended for future changes, as currently no options are
+ * available.
+ * @return 0 on success, an error code otherwise.
+ */
+GIT_EXTERN(int) git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opts);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/email.h b/include/git2/email.h
new file mode 100644
index 0000000..2039365
--- /dev/null
+++ b/include/git2/email.h
@@ -0,0 +1,127 @@
+/*
+ * 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_email_h__
+#define INCLUDE_git_email_h__
+
+#include "common.h"
+
+/**
+ * @file git2/email.h
+ * @brief Git email formatting and application routines.
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Formatting options for diff e-mail generation
+ */
+typedef enum {
+ /** Normal patch, the default */
+ GIT_EMAIL_CREATE_DEFAULT = 0,
+
+ /** Do not include patch numbers in the subject prefix. */
+ GIT_EMAIL_CREATE_OMIT_NUMBERS = (1u << 0),
+
+ /**
+ * Include numbers in the subject prefix even when the
+ * patch is for a single commit (1/1).
+ */
+ GIT_EMAIL_CREATE_ALWAYS_NUMBER = (1u << 1),
+
+ /** Do not perform rename or similarity detection. */
+ GIT_EMAIL_CREATE_NO_RENAMES = (1u << 2)
+} git_email_create_flags_t;
+
+/**
+ * Options for controlling the formatting of the generated e-mail.
+ */
+typedef struct {
+ unsigned int version;
+
+ /** see `git_email_create_flags_t` above */
+ uint32_t flags;
+
+ /** Options to use when creating diffs */
+ git_diff_options diff_opts;
+
+ /** Options for finding similarities within diffs */
+ git_diff_find_options diff_find_opts;
+
+ /**
+ * The subject prefix, by default "PATCH". If set to an empty
+ * string ("") then only the patch numbers will be shown in the
+ * prefix. If the subject_prefix is empty and patch numbers
+ * are not being shown, the prefix will be omitted entirely.
+ */
+ const char *subject_prefix;
+
+ /**
+ * The starting patch number; this cannot be 0. By default,
+ * this is 1.
+ */
+ size_t start_number;
+
+ /** The "re-roll" number. By default, there is no re-roll. */
+ size_t reroll_number;
+} git_email_create_options;
+
+/*
+ * By default, our options include rename detection and binary
+ * diffs to match `git format-patch`.
+ */
+#define GIT_EMAIL_CREATE_OPTIONS_VERSION 1
+#define GIT_EMAIL_CREATE_OPTIONS_INIT \
+{ \
+ GIT_EMAIL_CREATE_OPTIONS_VERSION, \
+ GIT_EMAIL_CREATE_DEFAULT, \
+ { GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_SHOW_BINARY, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3 }, \
+ GIT_DIFF_FIND_OPTIONS_INIT \
+}
+
+/**
+ * Create a diff for a commit in mbox format for sending via email.
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param diff the changes to include in the email
+ * @param patch_idx the patch index
+ * @param patch_count the total number of patches that will be included
+ * @param commit_id the commit id for this change
+ * @param summary the commit message for this change
+ * @param body optional text to include above the diffstat
+ * @param author the person who authored this commit
+ * @param opts email creation options
+ */
+GIT_EXTERN(int) git_email_create_from_diff(
+ git_buf *out,
+ git_diff *diff,
+ size_t patch_idx,
+ size_t patch_count,
+ const git_oid *commit_id,
+ const char *summary,
+ const char *body,
+ const git_signature *author,
+ const git_email_create_options *opts);
+
+/**
+ * Create a diff for a commit in mbox format for sending via email.
+ * The commit must not be a merge commit.
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param commit commit to create a patch for
+ * @param opts email creation options
+ */
+GIT_EXTERN(int) git_email_create_from_commit(
+ git_buf *out,
+ git_commit *commit,
+ const git_email_create_options *opts);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/errors.h b/include/git2/errors.h
new file mode 100644
index 0000000..7180852
--- /dev/null
+++ b/include/git2/errors.h
@@ -0,0 +1,181 @@
+/*
+ * 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_errors_h__
+#define INCLUDE_git_errors_h__
+
+#include "common.h"
+
+/**
+ * @file git2/errors.h
+ * @brief Git error handling routines and variables
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Generic return codes */
+typedef enum {
+ GIT_OK = 0, /**< No error */
+
+ GIT_ERROR = -1, /**< Generic error */
+ GIT_ENOTFOUND = -3, /**< Requested object could not be found */
+ GIT_EEXISTS = -4, /**< Object exists preventing operation */
+ GIT_EAMBIGUOUS = -5, /**< More than one object matches */
+ GIT_EBUFS = -6, /**< Output buffer too short to hold data */
+
+ /**
+ * GIT_EUSER is a special error that is never generated by libgit2
+ * code. You can return it from a callback (e.g to stop an iteration)
+ * to know that it was generated by the callback and not by libgit2.
+ */
+ GIT_EUSER = -7,
+
+ GIT_EBAREREPO = -8, /**< Operation not allowed on bare repository */
+ GIT_EUNBORNBRANCH = -9, /**< HEAD refers to branch with no commits */
+ GIT_EUNMERGED = -10, /**< Merge in progress prevented operation */
+ GIT_ENONFASTFORWARD = -11, /**< Reference was not fast-forwardable */
+ GIT_EINVALIDSPEC = -12, /**< Name/ref spec was not in a valid format */
+ GIT_ECONFLICT = -13, /**< Checkout conflicts prevented operation */
+ GIT_ELOCKED = -14, /**< Lock file prevented operation */
+ GIT_EMODIFIED = -15, /**< Reference value does not match expected */
+ GIT_EAUTH = -16, /**< Authentication error */
+ GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */
+ GIT_EAPPLIED = -18, /**< Patch/merge has already been applied */
+ GIT_EPEEL = -19, /**< The requested peel operation is not possible */
+ GIT_EEOF = -20, /**< Unexpected EOF */
+ GIT_EINVALID = -21, /**< Invalid operation or input */
+ GIT_EUNCOMMITTED = -22, /**< Uncommitted changes in index prevented operation */
+ GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */
+ GIT_EMERGECONFLICT = -24, /**< A merge conflict exists and cannot continue */
+
+ GIT_PASSTHROUGH = -30, /**< A user-configured callback refused to act */
+ GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
+ GIT_RETRY = -32, /**< Internal only */
+ GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
+ GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */
+ GIT_EAPPLYFAIL = -35, /**< Patch application failed */
+ GIT_EOWNER = -36, /**< The object is not owned by the current user */
+ GIT_TIMEOUT = -37 /**< The operation timed out */
+} git_error_code;
+
+/**
+ * Structure to store extra details of the last error that occurred.
+ *
+ * This is kept on a per-thread basis if GIT_THREADS was defined when the
+ * library was build, otherwise one is kept globally for the library
+ */
+typedef struct {
+ char *message;
+ int klass;
+} git_error;
+
+/** Error classes */
+typedef enum {
+ GIT_ERROR_NONE = 0,
+ GIT_ERROR_NOMEMORY,
+ GIT_ERROR_OS,
+ GIT_ERROR_INVALID,
+ GIT_ERROR_REFERENCE,
+ GIT_ERROR_ZLIB,
+ GIT_ERROR_REPOSITORY,
+ GIT_ERROR_CONFIG,
+ GIT_ERROR_REGEX,
+ GIT_ERROR_ODB,
+ GIT_ERROR_INDEX,
+ GIT_ERROR_OBJECT,
+ GIT_ERROR_NET,
+ GIT_ERROR_TAG,
+ GIT_ERROR_TREE,
+ GIT_ERROR_INDEXER,
+ GIT_ERROR_SSL,
+ GIT_ERROR_SUBMODULE,
+ GIT_ERROR_THREAD,
+ GIT_ERROR_STASH,
+ GIT_ERROR_CHECKOUT,
+ GIT_ERROR_FETCHHEAD,
+ GIT_ERROR_MERGE,
+ GIT_ERROR_SSH,
+ GIT_ERROR_FILTER,
+ GIT_ERROR_REVERT,
+ GIT_ERROR_CALLBACK,
+ GIT_ERROR_CHERRYPICK,
+ GIT_ERROR_DESCRIBE,
+ GIT_ERROR_REBASE,
+ GIT_ERROR_FILESYSTEM,
+ GIT_ERROR_PATCH,
+ GIT_ERROR_WORKTREE,
+ GIT_ERROR_SHA,
+ GIT_ERROR_HTTP,
+ GIT_ERROR_INTERNAL,
+ GIT_ERROR_GRAFTS
+} git_error_t;
+
+/**
+ * Return the last `git_error` object that was generated for the
+ * current thread.
+ *
+ * The default behaviour of this function is to return NULL if no previous error has occurred.
+ * However, libgit2's error strings are not cleared aggressively, so a prior
+ * (unrelated) error may be returned. This can be avoided by only calling
+ * this function if the prior call to a libgit2 API returned an error.
+ *
+ * @return A git_error object.
+ */
+GIT_EXTERN(const git_error *) git_error_last(void);
+
+/**
+ * Clear the last library error that occurred for this thread.
+ */
+GIT_EXTERN(void) git_error_clear(void);
+
+/**
+ * Set the error message string for this thread, using `printf`-style
+ * formatting.
+ *
+ * This function is public so that custom ODB backends and the like can
+ * relay an error message through libgit2. Most regular users of libgit2
+ * will never need to call this function -- actually, calling it in most
+ * circumstances (for example, calling from within a callback function)
+ * will just end up having the value overwritten by libgit2 internals.
+ *
+ * This error message is stored in thread-local storage and only applies
+ * to the particular thread that this libgit2 call is made from.
+ *
+ * @param error_class One of the `git_error_t` enum above describing the
+ * general subsystem that is responsible for the error.
+ * @param fmt The `printf`-style format string; subsequent arguments must
+ * be the arguments for the format string.
+ */
+GIT_EXTERN(void) git_error_set(int error_class, const char *fmt, ...)
+ GIT_FORMAT_PRINTF(2, 3);
+
+/**
+ * Set the error message string for this thread. This function is like
+ * `git_error_set` but takes a static string instead of a `printf`-style
+ * format.
+ *
+ * @param error_class One of the `git_error_t` enum above describing the
+ * general subsystem that is responsible for the error.
+ * @param string The error message to keep
+ * @return 0 on success or -1 on failure
+ */
+GIT_EXTERN(int) git_error_set_str(int error_class, const char *string);
+
+/**
+ * Set the error message to a special value for memory allocation failure.
+ *
+ * The normal `git_error_set_str()` function attempts to `strdup()` the
+ * string that is passed in. This is not a good idea when the error in
+ * question is a memory allocation failure. That circumstance has a
+ * special setter function that sets the error string to a known and
+ * statically allocated internal value.
+ */
+GIT_EXTERN(void) git_error_set_oom(void);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/experimental.h b/include/git2/experimental.h
new file mode 100644
index 0000000..06435f9
--- /dev/null
+++ b/include/git2/experimental.h
@@ -0,0 +1,20 @@
+/*
+ * 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_experimental_h__
+#define INCLUDE_experimental_h__
+
+/*
+ * This file exists to support users who build libgit2 with a bespoke
+ * build system and do not use our cmake configuration. Normally, cmake
+ * will create `experimental.h` from the `experimental.h.in` file and
+ * will include the generated file instead of this one. For non-cmake
+ * users, we bundle this `experimental.h` file which will be used
+ * instead.
+ */
+
+#endif
diff --git a/include/git2/filter.h b/include/git2/filter.h
new file mode 100644
index 0000000..79bf14c
--- /dev/null
+++ b/include/git2/filter.h
@@ -0,0 +1,276 @@
+/*
+ * 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_filter_h__
+#define INCLUDE_git_filter_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/filter.h
+ * @brief Git filter APIs
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Filters are applied in one of two directions: smudging - which is
+ * exporting a file from the Git object database to the working directory,
+ * and cleaning - which is importing a file from the working directory to
+ * the Git object database. These values control which direction of
+ * change is being applied.
+ */
+typedef enum {
+ GIT_FILTER_TO_WORKTREE = 0,
+ GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE,
+ GIT_FILTER_TO_ODB = 1,
+ GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB
+} git_filter_mode_t;
+
+/**
+ * Filter option flags.
+ */
+typedef enum {
+ GIT_FILTER_DEFAULT = 0u,
+
+ /** Don't error for `safecrlf` violations, allow them to continue. */
+ GIT_FILTER_ALLOW_UNSAFE = (1u << 0),
+
+ /** Don't load `/etc/gitattributes` (or the system equivalent) */
+ GIT_FILTER_NO_SYSTEM_ATTRIBUTES = (1u << 1),
+
+ /** Load attributes from `.gitattributes` in the root of HEAD */
+ GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2),
+
+ /**
+ * Load attributes from `.gitattributes` in a given commit.
+ * This can only be specified in a `git_filter_options`.
+ */
+ GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3)
+} git_filter_flag_t;
+
+/**
+ * Filtering options
+ */
+typedef struct {
+ unsigned int version;
+
+ /** See `git_filter_flag_t` above */
+ uint32_t flags;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ git_oid *commit_id;
+#endif
+
+ /**
+ * The commit to load attributes from, when
+ * `GIT_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
+ */
+ git_oid attr_commit_id;
+} git_filter_options;
+
+ #define GIT_FILTER_OPTIONS_VERSION 1
+ #define GIT_FILTER_OPTIONS_INIT {GIT_FILTER_OPTIONS_VERSION}
+
+/**
+ * A filter that can transform file data
+ *
+ * This represents a filter that can be used to transform or even replace
+ * file data. Libgit2 includes one built in filter and it is possible to
+ * write your own (see git2/sys/filter.h for information on that).
+ *
+ * The two builtin filters are:
+ *
+ * * "crlf" which uses the complex rules with the "text", "eol", and
+ * "crlf" file attributes to decide how to convert between LF and CRLF
+ * line endings
+ * * "ident" which replaces "$Id$" in a blob with "$Id: <blob OID>$" upon
+ * checkout and replaced "$Id: <anything>$" with "$Id$" on checkin.
+ */
+typedef struct git_filter git_filter;
+
+/**
+ * List of filters to be applied
+ *
+ * This represents a list of filters to be applied to a file / blob. You
+ * can build the list with one call, apply it with another, and dispose it
+ * with a third. In typical usage, there are not many occasions where a
+ * git_filter_list is needed directly since the library will generally
+ * handle conversions for you, but it can be convenient to be able to
+ * build and apply the list sometimes.
+ */
+typedef struct git_filter_list git_filter_list;
+
+/**
+ * Load the filter list for a given path.
+ *
+ * This will return 0 (success) but set the output git_filter_list to NULL
+ * if no filters are requested for the given file.
+ *
+ * @param filters Output newly created git_filter_list (or NULL)
+ * @param repo Repository object that contains `path`
+ * @param blob The blob to which the filter will be applied (if known)
+ * @param path Relative path of the file to be filtered
+ * @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @param flags Combination of `git_filter_flag_t` flags
+ * @return 0 on success (which could still return NULL if no filters are
+ * needed for the requested file), <0 on error
+ */
+GIT_EXTERN(int) git_filter_list_load(
+ git_filter_list **filters,
+ git_repository *repo,
+ git_blob *blob, /* can be NULL */
+ const char *path,
+ git_filter_mode_t mode,
+ uint32_t flags);
+
+/**
+ * Load the filter list for a given path.
+ *
+ * This will return 0 (success) but set the output git_filter_list to NULL
+ * if no filters are requested for the given file.
+ *
+ * @param filters Output newly created git_filter_list (or NULL)
+ * @param repo Repository object that contains `path`
+ * @param blob The blob to which the filter will be applied (if known)
+ * @param path Relative path of the file to be filtered
+ * @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @param opts The `git_filter_options` to use when loading filters
+ * @return 0 on success (which could still return NULL if no filters are
+ * needed for the requested file), <0 on error
+ */
+GIT_EXTERN(int) git_filter_list_load_ext(
+ git_filter_list **filters,
+ git_repository *repo,
+ git_blob *blob,
+ const char *path,
+ git_filter_mode_t mode,
+ git_filter_options *opts);
+
+/**
+ * Query the filter list to see if a given filter (by name) will run.
+ * The built-in filters "crlf" and "ident" can be queried, otherwise this
+ * is the name of the filter specified by the filter attribute.
+ *
+ * This will return 0 if the given filter is not in the list, or 1 if
+ * the filter will be applied.
+ *
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param name The name of the filter to query
+ * @return 1 if the filter is in the list, 0 otherwise
+ */
+GIT_EXTERN(int) git_filter_list_contains(
+ git_filter_list *filters,
+ const char *name);
+
+/**
+ * Apply filter list to a data buffer.
+ *
+ * @param out Buffer to store the result of the filtering
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param in Buffer containing the data to filter
+ * @param in_len The length of the input buffer
+ * @return 0 on success, an error code otherwise
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_buffer(
+ git_buf *out,
+ git_filter_list *filters,
+ const char *in,
+ size_t in_len);
+
+/**
+ * Apply a filter list to the contents of a file on disk
+ *
+ * @param out buffer into which to store the filtered file
+ * @param filters the list of filters to apply
+ * @param repo the repository in which to perform the filtering
+ * @param path the path of the file to filter, a relative path will be
+ * taken as relative to the workdir
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_file(
+ git_buf *out,
+ git_filter_list *filters,
+ git_repository *repo,
+ const char *path);
+
+/**
+ * Apply a filter list to the contents of a blob
+ *
+ * @param out buffer into which to store the filtered file
+ * @param filters the list of filters to apply
+ * @param blob the blob to filter
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_blob(
+ git_buf *out,
+ git_filter_list *filters,
+ git_blob *blob);
+
+/**
+ * Apply a filter list to an arbitrary buffer as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param buffer the buffer to filter
+ * @param len the size of the buffer
+ * @param target the stream into which the data will be written
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_filter_list_stream_buffer(
+ git_filter_list *filters,
+ const char *buffer,
+ size_t len,
+ git_writestream *target);
+
+/**
+ * Apply a filter list to a file as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param repo the repository in which to perform the filtering
+ * @param path the path of the file to filter, a relative path will be
+ * taken as relative to the workdir
+ * @param target the stream into which the data will be written
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_filter_list_stream_file(
+ git_filter_list *filters,
+ git_repository *repo,
+ const char *path,
+ git_writestream *target);
+
+/**
+ * Apply a filter list to a blob as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param blob the blob to filter
+ * @param target the stream into which the data will be written
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_filter_list_stream_blob(
+ git_filter_list *filters,
+ git_blob *blob,
+ git_writestream *target);
+
+/**
+ * Free a git_filter_list
+ *
+ * @param filters A git_filter_list created by `git_filter_list_load`
+ */
+GIT_EXTERN(void) git_filter_list_free(git_filter_list *filters);
+
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/global.h b/include/git2/global.h
new file mode 100644
index 0000000..2a87e10
--- /dev/null
+++ b/include/git2/global.h
@@ -0,0 +1,44 @@
+/*
+ * 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_global_h__
+#define INCLUDE_git_global_h__
+
+#include "common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Init the global state
+ *
+ * This function must be called before any other libgit2 function in
+ * order to set up global state and threading.
+ *
+ * This function may be called multiple times - it will return the number
+ * of times the initialization has been called (including this one) that have
+ * not subsequently been shutdown.
+ *
+ * @return the number of initializations of the library, or an error code.
+ */
+GIT_EXTERN(int) git_libgit2_init(void);
+
+/**
+ * Shutdown the global state
+ *
+ * Clean up the global state and threading context after calling it as
+ * many times as `git_libgit2_init()` was called - it will return the
+ * number of remainining initializations that have not been shutdown
+ * (after this one).
+ *
+ * @return the number of remaining initializations of the library, or an
+ * error code.
+ */
+GIT_EXTERN(int) git_libgit2_shutdown(void);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/graph.h b/include/git2/graph.h
new file mode 100644
index 0000000..56edb2f
--- /dev/null
+++ b/include/git2/graph.h
@@ -0,0 +1,77 @@
+/*
+ * 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_graph_h__
+#define INCLUDE_git_graph_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/graph.h
+ * @brief Git graph traversal routines
+ * @defgroup git_revwalk Git graph traversal routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Count the number of unique commits between two commit objects
+ *
+ * There is no need for branches containing the commits to have any
+ * upstream relationship, but it helps to think of one as a branch and
+ * the other as its upstream, the `ahead` and `behind` values will be
+ * what git would report for the branches.
+ *
+ * @param ahead number of unique from commits in `upstream`
+ * @param behind number of unique from commits in `local`
+ * @param repo the repository where the commits exist
+ * @param local the commit for local
+ * @param upstream the commit for upstream
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
+
+
+/**
+ * Determine if a commit is the descendant of another commit.
+ *
+ * Note that a commit is not considered a descendant of itself, in contrast
+ * to `git merge-base --is-ancestor`.
+ *
+ * @param repo the repository where the commits exist
+ * @param commit a previously loaded commit
+ * @param ancestor a potential ancestor commit
+ * @return 1 if the given commit is a descendant of the potential ancestor,
+ * 0 if not, error code otherwise.
+ */
+GIT_EXTERN(int) git_graph_descendant_of(
+ git_repository *repo,
+ const git_oid *commit,
+ const git_oid *ancestor);
+
+/**
+ * Determine if a commit is reachable from any of a list of commits by
+ * following parent edges.
+ *
+ * @param repo the repository where the commits exist
+ * @param commit a previously loaded commit
+ * @param length the number of commits in the provided `descendant_array`
+ * @param descendant_array oids of the commits
+ * @return 1 if the given commit is an ancestor of any of the given potential
+ * descendants, 0 if not, error code otherwise.
+ */
+GIT_EXTERN(int) git_graph_reachable_from_any(
+ git_repository *repo,
+ const git_oid *commit,
+ const git_oid descendant_array[],
+ size_t length);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/ignore.h b/include/git2/ignore.h
new file mode 100644
index 0000000..4c441c6
--- /dev/null
+++ b/include/git2/ignore.h
@@ -0,0 +1,78 @@
+/*
+ * 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_ignore_h__
+#define INCLUDE_git_ignore_h__
+
+#include "common.h"
+#include "types.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Add ignore rules for a repository.
+ *
+ * Excludesfile rules (i.e. .gitignore rules) are generally read from
+ * .gitignore files in the repository tree or from a shared system file
+ * only if a "core.excludesfile" config value is set. The library also
+ * keeps a set of per-repository internal ignores that can be configured
+ * in-memory and will not persist. This function allows you to add to
+ * that internal rules list.
+ *
+ * Example usage:
+ *
+ * error = git_ignore_add_rule(myrepo, "*.c\ndir/\nFile with space\n");
+ *
+ * This would add three rules to the ignores.
+ *
+ * @param repo The repository to add ignore rules to.
+ * @param rules Text of rules, the contents to add on a .gitignore file.
+ * It is okay to have multiple rules in the text; if so,
+ * each rule should be terminated with a newline.
+ * @return 0 on success
+ */
+GIT_EXTERN(int) git_ignore_add_rule(
+ git_repository *repo,
+ const char *rules);
+
+/**
+ * Clear ignore rules that were explicitly added.
+ *
+ * Resets to the default internal ignore rules. This will not turn off
+ * rules in .gitignore files that actually exist in the filesystem.
+ *
+ * The default internal ignores ignore ".", ".." and ".git" entries.
+ *
+ * @param repo The repository to remove ignore rules from.
+ * @return 0 on success
+ */
+GIT_EXTERN(int) git_ignore_clear_internal_rules(
+ git_repository *repo);
+
+/**
+ * Test if the ignore rules apply to a given path.
+ *
+ * This function checks the ignore rules to see if they would apply to the
+ * given file. This indicates if the file would be ignored regardless of
+ * whether the file is already in the index or committed to the repository.
+ *
+ * One way to think of this is if you were to do "git check-ignore --no-index"
+ * on the given file, would it be shown or not?
+ *
+ * @param ignored boolean returning 0 if the file is not ignored, 1 if it is
+ * @param repo a repository object
+ * @param path the file to check ignores for, relative to the repo's workdir.
+ * @return 0 if ignore rules could be processed for the file (regardless
+ * of whether it exists or not), or an error < 0 if they could not.
+ */
+GIT_EXTERN(int) git_ignore_path_is_ignored(
+ int *ignored,
+ git_repository *repo,
+ const char *path);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/index.h b/include/git2/index.h
new file mode 100644
index 0000000..6e80637
--- /dev/null
+++ b/include/git2/index.h
@@ -0,0 +1,848 @@
+/*
+ * 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_index_h__
+#define INCLUDE_git_index_h__
+
+#include "common.h"
+#include "indexer.h"
+#include "types.h"
+#include "oid.h"
+#include "strarray.h"
+
+/**
+ * @file git2/index.h
+ * @brief Git index parsing and manipulation routines
+ * @defgroup git_index Git index parsing and manipulation routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Time structure used in a git index entry */
+typedef struct {
+ int32_t seconds;
+ /* nsec should not be stored as time_t compatible */
+ uint32_t nanoseconds;
+} git_index_time;
+
+/**
+ * In-memory representation of a file entry in the index.
+ *
+ * This is a public structure that represents a file entry in the index.
+ * The meaning of the fields corresponds to core Git's documentation (in
+ * "Documentation/technical/index-format.txt").
+ *
+ * The `flags` field consists of a number of bit fields which can be
+ * accessed via the first set of `GIT_INDEX_ENTRY_...` bitmasks below.
+ * These flags are all read from and persisted to disk.
+ *
+ * The `flags_extended` field also has a number of bit fields which can be
+ * accessed via the later `GIT_INDEX_ENTRY_...` bitmasks below. Some of
+ * these flags are read from and written to disk, but some are set aside
+ * for in-memory only reference.
+ *
+ * Note that the time and size fields are truncated to 32 bits. This
+ * is enough to detect changes, which is enough for the index to
+ * function as a cache, but it should not be taken as an authoritative
+ * source for that data.
+ */
+typedef struct git_index_entry {
+ git_index_time ctime;
+ git_index_time mtime;
+
+ uint32_t dev;
+ uint32_t ino;
+ uint32_t mode;
+ uint32_t uid;
+ uint32_t gid;
+ uint32_t file_size;
+
+ git_oid id;
+
+ uint16_t flags;
+ uint16_t flags_extended;
+
+ const char *path;
+} git_index_entry;
+
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags`
+ *
+ * These bitmasks match the four fields in the `git_index_entry` `flags`
+ * value both in memory and on disk. You can use them to interpret the
+ * data in the `flags`.
+ */
+
+#define GIT_INDEX_ENTRY_NAMEMASK (0x0fff)
+#define GIT_INDEX_ENTRY_STAGEMASK (0x3000)
+#define GIT_INDEX_ENTRY_STAGESHIFT 12
+
+/**
+ * Flags for index entries
+ */
+typedef enum {
+ GIT_INDEX_ENTRY_EXTENDED = (0x4000),
+ GIT_INDEX_ENTRY_VALID = (0x8000)
+} git_index_entry_flag_t;
+
+#define GIT_INDEX_ENTRY_STAGE(E) \
+ (((E)->flags & GIT_INDEX_ENTRY_STAGEMASK) >> GIT_INDEX_ENTRY_STAGESHIFT)
+
+#define GIT_INDEX_ENTRY_STAGE_SET(E,S) do { \
+ (E)->flags = ((E)->flags & ~GIT_INDEX_ENTRY_STAGEMASK) | \
+ (((S) & 0x03) << GIT_INDEX_ENTRY_STAGESHIFT); } while (0)
+
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`
+ *
+ * In memory, the `flags_extended` fields are divided into two parts: the
+ * fields that are read from and written to disk, and other fields that
+ * in-memory only and used by libgit2. Only the flags in
+ * `GIT_INDEX_ENTRY_EXTENDED_FLAGS` will get saved on-disk.
+ *
+ * Thee first three bitmasks match the three fields in the
+ * `git_index_entry` `flags_extended` value that belong on disk. You
+ * can use them to interpret the data in the `flags_extended`.
+ *
+ * The rest of the bitmasks match the other fields in the `git_index_entry`
+ * `flags_extended` value that are only used in-memory by libgit2.
+ * You can use them to interpret the data in the `flags_extended`.
+ *
+ */
+typedef enum {
+ GIT_INDEX_ENTRY_INTENT_TO_ADD = (1 << 13),
+ GIT_INDEX_ENTRY_SKIP_WORKTREE = (1 << 14),
+
+ GIT_INDEX_ENTRY_EXTENDED_FLAGS = (GIT_INDEX_ENTRY_INTENT_TO_ADD | GIT_INDEX_ENTRY_SKIP_WORKTREE),
+
+ GIT_INDEX_ENTRY_UPTODATE = (1 << 2)
+} git_index_entry_extended_flag_t;
+
+/** Capabilities of system that affect index actions. */
+typedef enum {
+ GIT_INDEX_CAPABILITY_IGNORE_CASE = 1,
+ GIT_INDEX_CAPABILITY_NO_FILEMODE = 2,
+ GIT_INDEX_CAPABILITY_NO_SYMLINKS = 4,
+ GIT_INDEX_CAPABILITY_FROM_OWNER = -1
+} git_index_capability_t;
+
+
+/** Callback for APIs that add/remove/update files matching pathspec */
+typedef int GIT_CALLBACK(git_index_matched_path_cb)(
+ const char *path, const char *matched_pathspec, void *payload);
+
+/** Flags for APIs that add files matching pathspec */
+typedef enum {
+ GIT_INDEX_ADD_DEFAULT = 0,
+ GIT_INDEX_ADD_FORCE = (1u << 0),
+ GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1),
+ GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2)
+} git_index_add_option_t;
+
+/** Git index stage states */
+typedef enum {
+ /**
+ * Match any index stage.
+ *
+ * Some index APIs take a stage to match; pass this value to match
+ * any entry matching the path regardless of stage.
+ */
+ GIT_INDEX_STAGE_ANY = -1,
+
+ /** A normal staged file in the index. */
+ GIT_INDEX_STAGE_NORMAL = 0,
+
+ /** The ancestor side of a conflict. */
+ GIT_INDEX_STAGE_ANCESTOR = 1,
+
+ /** The "ours" side of a conflict. */
+ GIT_INDEX_STAGE_OURS = 2,
+
+ /** The "theirs" side of a conflict. */
+ GIT_INDEX_STAGE_THEIRS = 3
+} git_index_stage_t;
+
+/**
+ * Create a new bare Git index object as a memory representation
+ * of the Git index file in 'index_path', without a repository
+ * to back it.
+ *
+ * Since there is no ODB or working directory behind this index,
+ * any Index methods which rely on these (e.g. index_add_bypath)
+ * will fail with the GIT_ERROR error code.
+ *
+ * If you need to access the index of an actual repository,
+ * use the `git_repository_index` wrapper.
+ *
+ * The index must be freed once it's no longer in use.
+ *
+ * @param out the pointer for the new index
+ * @param index_path the path to the index file in disk
+ * @return 0 or an error code
+ */
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path, git_oid_t oid_type);
+#else
+GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
+#endif
+
+/**
+ * Create an in-memory index object.
+ *
+ * This index object cannot be read/written to the filesystem,
+ * but may be used to perform in-memory index operations.
+ *
+ * The index must be freed once it's no longer in use.
+ *
+ * @param out the pointer for the new index
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_index_new(git_index **out, git_oid_t oid_type);
+#else
+GIT_EXTERN(int) git_index_new(git_index **out);
+#endif
+
+/**
+ * Free an existing index object.
+ *
+ * @param index an existing index object
+ */
+GIT_EXTERN(void) git_index_free(git_index *index);
+
+/**
+ * Get the repository this index relates to
+ *
+ * @param index The index
+ * @return A pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_index_owner(const git_index *index);
+
+/**
+ * Read index capabilities flags.
+ *
+ * @param index An existing index object
+ * @return A combination of GIT_INDEX_CAPABILITY values
+ */
+GIT_EXTERN(int) git_index_caps(const git_index *index);
+
+/**
+ * Set index capabilities flags.
+ *
+ * If you pass `GIT_INDEX_CAPABILITY_FROM_OWNER` for the caps, then
+ * capabilities will be read from the config of the owner object,
+ * looking at `core.ignorecase`, `core.filemode`, `core.symlinks`.
+ *
+ * @param index An existing index object
+ * @param caps A combination of GIT_INDEX_CAPABILITY values
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_index_set_caps(git_index *index, int caps);
+
+/**
+ * Get index on-disk version.
+ *
+ * Valid return values are 2, 3, or 4. If 3 is returned, an index
+ * with version 2 may be written instead, if the extension data in
+ * version 3 is not necessary.
+ *
+ * @param index An existing index object
+ * @return the index version
+ */
+GIT_EXTERN(unsigned int) git_index_version(git_index *index);
+
+/**
+ * Set index on-disk version.
+ *
+ * Valid values are 2, 3, or 4. If 2 is given, git_index_write may
+ * write an index with version 3 instead, if necessary to accurately
+ * represent the index.
+ *
+ * @param index An existing index object
+ * @param version The new version number
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_index_set_version(git_index *index, unsigned int version);
+
+/**
+ * Update the contents of an existing index object in memory by reading
+ * from the hard disk.
+ *
+ * If `force` is true, this performs a "hard" read that discards in-memory
+ * changes and always reloads the on-disk index data. If there is no
+ * on-disk version, the index will be cleared.
+ *
+ * If `force` is false, this does a "soft" read that reloads the index
+ * data from disk only if it has changed since the last time it was
+ * loaded. Purely in-memory index data will be untouched. Be aware: if
+ * there are changes on disk, unwritten in-memory changes are discarded.
+ *
+ * @param index an existing index object
+ * @param force if true, always reload, vs. only read if file has changed
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_read(git_index *index, int force);
+
+/**
+ * Write an existing index object from memory back to disk
+ * using an atomic file lock.
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_write(git_index *index);
+
+/**
+ * Get the full path to the index file on disk.
+ *
+ * @param index an existing index object
+ * @return path to index file or NULL for in-memory index
+ */
+GIT_EXTERN(const char *) git_index_path(const git_index *index);
+
+#ifndef GIT_DEPRECATE_HARD
+/**
+ * Get the checksum of the index
+ *
+ * This checksum is the SHA-1 hash over the index file (except the
+ * last 20 bytes which are the checksum itself). In cases where the
+ * index does not exist on-disk, it will be zeroed out.
+ *
+ * @deprecated this function is deprecated with no replacement
+ * @param index an existing index object
+ * @return a pointer to the checksum of the index
+ */
+GIT_EXTERN(const git_oid *) git_index_checksum(git_index *index);
+#endif
+
+/**
+ * Read a tree into the index file with stats
+ *
+ * The current index contents will be replaced by the specified tree.
+ *
+ * @param index an existing index object
+ * @param tree tree to read
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_read_tree(git_index *index, const git_tree *tree);
+
+/**
+ * Write the index as a tree
+ *
+ * This method will scan the index and write a representation
+ * of its current state back to disk; it recursively creates
+ * tree objects for each of the subtrees stored in the index,
+ * but only returns the OID of the root tree. This is the OID
+ * that can be used e.g. to create a commit.
+ *
+ * The index instance cannot be bare, and needs to be associated
+ * to an existing repository.
+ *
+ * The index must not contain any file in conflict.
+ *
+ * @param out Pointer where to store the OID of the written tree
+ * @param index Index to write
+ * @return 0 on success, GIT_EUNMERGED when the index is not clean
+ * or an error code
+ */
+GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index);
+
+/**
+ * Write the index as a tree to the given repository
+ *
+ * This method will do the same as `git_index_write_tree`, but
+ * letting the user choose the repository where the tree will
+ * be written.
+ *
+ * The index must not contain any file in conflict.
+ *
+ * @param out Pointer where to store OID of the written tree
+ * @param index Index to write
+ * @param repo Repository where to write the tree
+ * @return 0 on success, GIT_EUNMERGED when the index is not clean
+ * or an error code
+ */
+GIT_EXTERN(int) git_index_write_tree_to(git_oid *out, git_index *index, git_repository *repo);
+
+/**@}*/
+
+/** @name Raw Index Entry Functions
+ *
+ * These functions work on index entries, and allow for raw manipulation
+ * of the entries.
+ */
+/**@{*/
+
+/* Index entry manipulation */
+
+/**
+ * Get the count of entries currently in the index
+ *
+ * @param index an existing index object
+ * @return integer of count of current entries
+ */
+GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
+
+/**
+ * Clear the contents (all the entries) of an index object.
+ *
+ * This clears the index object in memory; changes must be explicitly
+ * written to disk for them to take effect persistently.
+ *
+ * @param index an existing index object
+ * @return 0 on success, error code < 0 on failure
+ */
+GIT_EXTERN(int) git_index_clear(git_index *index);
+
+/**
+ * Get a pointer to one of the entries in the index
+ *
+ * The entry is not modifiable and should not be freed. Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_entry *) git_index_get_byindex(
+ git_index *index, size_t n);
+
+/**
+ * Get a pointer to one of the entries in the index
+ *
+ * The entry is not modifiable and should not be freed. Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @param stage stage to search
+ * @return a pointer to the entry; NULL if it was not found
+ */
+GIT_EXTERN(const git_index_entry *) git_index_get_bypath(
+ git_index *index, const char *path, int stage);
+
+/**
+ * Remove an entry from the index
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @param stage stage to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage);
+
+/**
+ * Remove all entries from the index under a given directory
+ *
+ * @param index an existing index object
+ * @param dir container directory path
+ * @param stage stage to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove_directory(
+ git_index *index, const char *dir, int stage);
+
+/**
+ * Add or update an index entry from an in-memory struct
+ *
+ * If a previous index entry exists that has the same path and stage
+ * as the given 'source_entry', it will be replaced. Otherwise, the
+ * 'source_entry' will be added.
+ *
+ * A full copy (including the 'path' string) of the given
+ * 'source_entry' will be inserted on the index.
+ *
+ * @param index an existing index object
+ * @param source_entry new entry object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry);
+
+/**
+ * Return the stage number from a git index entry
+ *
+ * This entry is calculated from the entry's flag attribute like this:
+ *
+ * (entry->flags & GIT_INDEX_ENTRY_STAGEMASK) >> GIT_INDEX_ENTRY_STAGESHIFT
+ *
+ * @param entry The entry
+ * @return the stage number
+ */
+GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
+
+/**
+ * Return whether the given index entry is a conflict (has a high stage
+ * entry). This is simply shorthand for `git_index_entry_stage > 0`.
+ *
+ * @param entry The entry
+ * @return 1 if the entry is a conflict entry, 0 otherwise
+ */
+GIT_EXTERN(int) git_index_entry_is_conflict(const git_index_entry *entry);
+
+/**@}*/
+
+/** @name Index Entry Iteration Functions
+ *
+ * These functions provide an iterator for index entries.
+ */
+/**@{*/
+
+/**
+ * Create an iterator that will return every entry contained in the
+ * index at the time of creation. Entries are returned in order,
+ * sorted by path. This iterator is backed by a snapshot that allows
+ * callers to modify the index while iterating without affecting the
+ * iterator.
+ *
+ * @param iterator_out The newly created iterator
+ * @param index The index to iterate
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_index_iterator_new(
+ git_index_iterator **iterator_out,
+ git_index *index);
+
+/**
+ * Return the next index entry in-order from the iterator.
+ *
+ * @param out Pointer to store the index entry in
+ * @param iterator The iterator
+ * @return 0, GIT_ITEROVER on iteration completion or an error code
+ */
+GIT_EXTERN(int) git_index_iterator_next(
+ const git_index_entry **out,
+ git_index_iterator *iterator);
+
+/**
+ * Free the index iterator
+ *
+ * @param iterator The iterator to free
+ */
+GIT_EXTERN(void) git_index_iterator_free(git_index_iterator *iterator);
+
+/**@}*/
+
+/** @name Workdir Index Entry Functions
+ *
+ * These functions work on index entries specifically in the working
+ * directory (ie, stage 0).
+ */
+/**@{*/
+
+/**
+ * Add or update an index entry from a file on disk
+ *
+ * The file `path` must be relative to the repository's
+ * working folder and must be readable.
+ *
+ * This method will fail in bare index instances.
+ *
+ * This forces the file to be added to the index, not looking
+ * at gitignore rules. Those rules can be evaluated through
+ * the git_status APIs (in status.h) before calling this.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting. The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param path filename to add
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add_bypath(git_index *index, const char *path);
+
+/**
+ * Add or update an index entry from a buffer in memory
+ *
+ * This method will create a blob in the repository that owns the
+ * index and then add the index entry to the index. The `path` of the
+ * entry represents the position of the blob relative to the
+ * repository's root folder.
+ *
+ * If a previous index entry exists that has the same path as the
+ * given 'entry', it will be replaced. Otherwise, the 'entry' will be
+ * added.
+ *
+ * This forces the file to be added to the index, not looking
+ * at gitignore rules. Those rules can be evaluated through
+ * the git_status APIs (in status.h) before calling this.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting. The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param entry filename to add
+ * @param buffer data to be written into the blob
+ * @param len length of the data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add_from_buffer(
+ git_index *index,
+ const git_index_entry *entry,
+ const void *buffer, size_t len);
+
+/**
+ * Remove an index entry corresponding to a file on disk
+ *
+ * The file `path` must be relative to the repository's
+ * working folder. It may exist.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting. The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param path filename to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
+
+/**
+ * Add or update index entries matching files in the working directory.
+ *
+ * This method will fail in bare index instances.
+ *
+ * The `pathspec` is a list of file names or shell glob patterns that will
+ * be matched against files in the repository's working directory. Each
+ * file that matches will be added to the index (either updating an
+ * existing entry or adding a new entry). You can disable glob expansion
+ * and force exact matching with the `GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH`
+ * flag.
+ *
+ * Files that are ignored will be skipped (unlike `git_index_add_bypath`).
+ * If a file is already tracked in the index, then it *will* be updated
+ * even if it is ignored. Pass the `GIT_INDEX_ADD_FORCE` flag to skip
+ * the checking of ignore rules.
+ *
+ * To emulate `git add -A` and generate an error if the pathspec contains
+ * the exact path of an ignored file (when not using FORCE), add the
+ * `GIT_INDEX_ADD_CHECK_PATHSPEC` flag. This checks that each entry
+ * in the `pathspec` that is an exact match to a filename on disk is
+ * either not ignored or already in the index. If this check fails, the
+ * function will return GIT_EINVALIDSPEC.
+ *
+ * To emulate `git add -A` with the "dry-run" option, just use a callback
+ * function that always returns a positive value. See below for details.
+ *
+ * If any files are currently the result of a merge conflict, those files
+ * will no longer be marked as conflicting. The data about the conflicts
+ * will be moved to the "resolve undo" (REUC) section.
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the working directory immediately *before* it is added to /
+ * updated in the index. Returning zero will add the item to the index,
+ * greater than zero will skip the item, and less than zero will abort the
+ * scan and return that value to the caller.
+ *
+ * @param index an existing index object
+ * @param pathspec array of path patterns
+ * @param flags combination of git_index_add_option_t flags
+ * @param callback notification callback for each added/updated path (also
+ * gets index of matching pathspec entry); can be NULL;
+ * return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_add_all(
+ git_index *index,
+ const git_strarray *pathspec,
+ unsigned int flags,
+ git_index_matched_path_cb callback,
+ void *payload);
+
+/**
+ * Remove all matching index entries.
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the index immediately *before* it is removed. Return 0 to
+ * remove the item, > 0 to skip the item, and < 0 to abort the scan.
+ *
+ * @param index An existing index object
+ * @param pathspec array of path patterns
+ * @param callback notification callback for each removed path (also
+ * gets index of matching pathspec entry); can be NULL;
+ * return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_remove_all(
+ git_index *index,
+ const git_strarray *pathspec,
+ git_index_matched_path_cb callback,
+ void *payload);
+
+/**
+ * Update all index entries to match the working directory
+ *
+ * This method will fail in bare index instances.
+ *
+ * This scans the existing index entries and synchronizes them with the
+ * working directory, deleting them if the corresponding working directory
+ * file no longer exists otherwise updating the information (including
+ * adding the latest version of file to the ODB if needed).
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the index immediately *before* it is updated (either refreshed
+ * or removed depending on working directory state). Return 0 to proceed
+ * with updating the item, > 0 to skip the item, and < 0 to abort the scan.
+ *
+ * @param index An existing index object
+ * @param pathspec array of path patterns
+ * @param callback notification callback for each updated path (also
+ * gets index of matching pathspec entry); can be NULL;
+ * return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_update_all(
+ git_index *index,
+ const git_strarray *pathspec,
+ git_index_matched_path_cb callback,
+ void *payload);
+
+/**
+ * Find the first position of any entries which point to given
+ * path in the Git index.
+ *
+ * @param at_pos the address to which the position of the index entry is written (optional)
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
+
+/**
+ * Find the first position of any entries matching a prefix. To find the first position
+ * of a path inside a given folder, suffix the prefix with a '/'.
+ *
+ * @param at_pos the address to which the position of the index entry is written (optional)
+ * @param index an existing index object
+ * @param prefix the prefix to search for
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_find_prefix(size_t *at_pos, git_index *index, const char *prefix);
+
+/**@}*/
+
+/** @name Conflict Index Entry Functions
+ *
+ * These functions work on conflict index entries specifically (ie, stages 1-3)
+ */
+/**@{*/
+
+/**
+ * Add or update index entries to represent a conflict. Any staged
+ * entries that exist at the given paths will be removed.
+ *
+ * The entries are the entries from the tree included in the merge. Any
+ * entry may be null to indicate that that file was not present in the
+ * trees during the merge. For example, ancestor_entry may be NULL to
+ * indicate that a file was added in both branches and must be resolved.
+ *
+ * @param index an existing index object
+ * @param ancestor_entry the entry data for the ancestor of the conflict
+ * @param our_entry the entry data for our side of the merge conflict
+ * @param their_entry the entry data for their side of the merge conflict
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_add(
+ git_index *index,
+ const git_index_entry *ancestor_entry,
+ const git_index_entry *our_entry,
+ const git_index_entry *their_entry);
+
+/**
+ * Get the index entries that represent a conflict of a single file.
+ *
+ * The entries are not modifiable and should not be freed. Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param ancestor_out Pointer to store the ancestor entry
+ * @param our_out Pointer to store the our entry
+ * @param their_out Pointer to store the their entry
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_get(
+ const git_index_entry **ancestor_out,
+ const git_index_entry **our_out,
+ const git_index_entry **their_out,
+ git_index *index,
+ const char *path);
+
+/**
+ * Removes the index entries that represent a conflict of a single file.
+ *
+ * @param index an existing index object
+ * @param path path to remove conflicts for
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path);
+
+/**
+ * Remove all conflicts in the index (entries with a stage greater than 0).
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_cleanup(git_index *index);
+
+/**
+ * Determine if the index contains entries representing file conflicts.
+ *
+ * @param index An existing index object.
+ * @return 1 if at least one conflict is found, 0 otherwise.
+ */
+GIT_EXTERN(int) git_index_has_conflicts(const git_index *index);
+
+/**
+ * Create an iterator for the conflicts in the index.
+ *
+ * The index must not be modified while iterating; the results are undefined.
+ *
+ * @param iterator_out The newly created conflict iterator
+ * @param index The index to scan
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_iterator_new(
+ git_index_conflict_iterator **iterator_out,
+ git_index *index);
+
+/**
+ * Returns the current conflict (ancestor, ours and theirs entry) and
+ * advance the iterator internally to the next value.
+ *
+ * @param ancestor_out Pointer to store the ancestor side of the conflict
+ * @param our_out Pointer to store our side of the conflict
+ * @param their_out Pointer to store their side of the conflict
+ * @param iterator The conflict iterator.
+ * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code
+ * (negative value)
+ */
+GIT_EXTERN(int) git_index_conflict_next(
+ const git_index_entry **ancestor_out,
+ const git_index_entry **our_out,
+ const git_index_entry **their_out,
+ git_index_conflict_iterator *iterator);
+
+/**
+ * Frees a `git_index_conflict_iterator`.
+ *
+ * @param iterator pointer to the iterator
+ */
+GIT_EXTERN(void) git_index_conflict_iterator_free(
+ git_index_conflict_iterator *iterator);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
new file mode 100644
index 0000000..630eef9
--- /dev/null
+++ b/include/git2/indexer.h
@@ -0,0 +1,195 @@
+/*
+ * 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_indexer_h__
+#define _INCLUDE_git_indexer_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+GIT_BEGIN_DECL
+
+/** A git indexer object */
+typedef struct git_indexer git_indexer;
+
+/**
+ * This structure is used to provide callers information about the
+ * progress of indexing a packfile, either directly or part of a
+ * fetch or clone that downloads a packfile.
+ */
+typedef struct git_indexer_progress {
+ /** number of objects in the packfile being indexed */
+ unsigned int total_objects;
+
+ /** received objects that have been hashed */
+ unsigned int indexed_objects;
+
+ /** received_objects: objects which have been downloaded */
+ unsigned int received_objects;
+
+ /**
+ * locally-available objects that have been injected in order
+ * to fix a thin pack
+ */
+ unsigned int local_objects;
+
+ /** number of deltas in the packfile being indexed */
+ unsigned int total_deltas;
+
+ /** received deltas that have been indexed */
+ unsigned int indexed_deltas;
+
+ /** size of the packfile received up to now */
+ size_t received_bytes;
+} git_indexer_progress;
+
+/**
+ * Type for progress callbacks during indexing. Return a value less
+ * than zero to cancel the indexing or download.
+ *
+ * @param stats Structure containing information about the state of the transfer
+ * @param payload Payload provided by caller
+ */
+typedef int GIT_CALLBACK(git_indexer_progress_cb)(const git_indexer_progress *stats, void *payload);
+
+/**
+ * Options for indexer configuration
+ */
+typedef struct git_indexer_options {
+ unsigned int version;
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ /** permissions to use creating packfile or 0 for defaults */
+ unsigned int mode;
+
+ /**
+ * object database from which to read base objects when
+ * fixing thin packs. This can be NULL if there are no thin
+ * packs; if a thin pack is encountered, an error will be
+ * returned if there are bases missing.
+ */
+ git_odb *odb;
+#endif
+
+ /** progress_cb function to call with progress information */
+ git_indexer_progress_cb progress_cb;
+
+ /** progress_cb_payload payload for the progress callback */
+ void *progress_cb_payload;
+
+ /** Do connectivity checks for the received pack */
+ unsigned char verify;
+} git_indexer_options;
+
+#define GIT_INDEXER_OPTIONS_VERSION 1
+#define GIT_INDEXER_OPTIONS_INIT { GIT_INDEXER_OPTIONS_VERSION }
+
+/**
+ * Initializes a `git_indexer_options` with default values. Equivalent to
+ * creating an instance with GIT_INDEXER_OPTIONS_INIT.
+ *
+ * @param opts the `git_indexer_options` struct to initialize.
+ * @param version Version of struct; pass `GIT_INDEXER_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_indexer_options_init(
+ git_indexer_options *opts,
+ unsigned int version);
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+/**
+ * Create a new indexer instance
+ *
+ * @param out where to store the indexer instance
+ * @param path to the directory where the packfile should be stored
+ * @param oid_type the oid type to use for objects
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_indexer_new(
+ git_indexer **out,
+ const char *path,
+ git_oid_t oid_type,
+ git_indexer_options *opts);
+#else
+/**
+ * Create a new indexer instance
+ *
+ * @param out where to store the indexer instance
+ * @param path to the directory where the packfile should be stored
+ * @param mode permissions to use creating packfile or 0 for defaults
+ * @param odb object database from which to read base objects when
+ * fixing thin packs. Pass NULL if no thin pack is expected (an error
+ * will be returned if there are bases missing)
+ * @param opts Optional structure containing additional options. See
+ * `git_indexer_options` above.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_indexer_new(
+ git_indexer **out,
+ const char *path,
+ unsigned int mode,
+ git_odb *odb,
+ git_indexer_options *opts);
+#endif
+
+/**
+ * Add data to the indexer
+ *
+ * @param idx the indexer
+ * @param data the data to add
+ * @param size the size of the data in bytes
+ * @param stats stat storage
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t size, git_indexer_progress *stats);
+
+/**
+ * Finalize the pack and index
+ *
+ * Resolve any pending deltas and write out the index file
+ *
+ * @param idx the indexer
+ * @param stats Stat storage.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats);
+
+#ifndef GIT_DEPRECATE_HARD
+/**
+ * Get the packfile's hash
+ *
+ * A packfile's name is derived from the sorted hashing of all object
+ * names. This is only correct after the index has been finalized.
+ *
+ * @deprecated use git_indexer_name
+ * @param idx the indexer instance
+ * @return the packfile's hash
+ */
+GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx);
+#endif
+
+/**
+ * Get the unique name for the resulting packfile.
+ *
+ * The packfile's name is derived from the packfile's content.
+ * This is only correct after the index has been finalized.
+ *
+ * @param idx the indexer instance
+ * @return a NUL terminated string for the packfile name
+ */
+GIT_EXTERN(const char *) git_indexer_name(const git_indexer *idx);
+
+/**
+ * Free the indexer and its resources
+ *
+ * @param idx the indexer to free
+ */
+GIT_EXTERN(void) git_indexer_free(git_indexer *idx);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/mailmap.h b/include/git2/mailmap.h
new file mode 100644
index 0000000..7c3f60f
--- /dev/null
+++ b/include/git2/mailmap.h
@@ -0,0 +1,115 @@
+/*
+ * 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_mailmap_h__
+#define INCLUDE_git_mailmap_h__
+
+#include "common.h"
+#include "types.h"
+#include "buffer.h"
+
+/**
+ * @file git2/mailmap.h
+ * @brief Mailmap parsing routines
+ * @defgroup git_mailmap Git mailmap routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Allocate a new mailmap object.
+ *
+ * This object is empty, so you'll have to add a mailmap file before you can do
+ * anything with it. The mailmap must be freed with 'git_mailmap_free'.
+ *
+ * @param out pointer to store the new mailmap
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_mailmap_new(git_mailmap **out);
+
+/**
+ * Free the mailmap and its associated memory.
+ *
+ * @param mm the mailmap to free
+ */
+GIT_EXTERN(void) git_mailmap_free(git_mailmap *mm);
+
+/**
+ * Add a single entry to the given mailmap object. If the entry already exists,
+ * it will be replaced with the new entry.
+ *
+ * @param mm mailmap to add the entry to
+ * @param real_name the real name to use, or NULL
+ * @param real_email the real email to use, or NULL
+ * @param replace_name the name to replace, or NULL
+ * @param replace_email the email to replace
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_mailmap_add_entry(
+ git_mailmap *mm, const char *real_name, const char *real_email,
+ const char *replace_name, const char *replace_email);
+
+/**
+ * Create a new mailmap instance containing a single mailmap file
+ *
+ * @param out pointer to store the new mailmap
+ * @param buf buffer to parse the mailmap from
+ * @param len the length of the input buffer
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_mailmap_from_buffer(
+ git_mailmap **out, const char *buf, size_t len);
+
+/**
+ * Create a new mailmap instance from a repository, loading mailmap files based
+ * on the repository's configuration.
+ *
+ * Mailmaps are loaded in the following order:
+ * 1. '.mailmap' in the root of the repository's working directory, if present.
+ * 2. The blob object identified by the 'mailmap.blob' config entry, if set.
+ * [NOTE: 'mailmap.blob' defaults to 'HEAD:.mailmap' in bare repositories]
+ * 3. The path in the 'mailmap.file' config entry, if set.
+ *
+ * @param out pointer to store the new mailmap
+ * @param repo repository to load mailmap information from
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_mailmap_from_repository(
+ git_mailmap **out, git_repository *repo);
+
+/**
+ * Resolve a name and email to the corresponding real name and email.
+ *
+ * The lifetime of the strings are tied to `mm`, `name`, and `email` parameters.
+ *
+ * @param real_name pointer to store the real name
+ * @param real_email pointer to store the real email
+ * @param mm the mailmap to perform a lookup with (may be NULL)
+ * @param name the name to look up
+ * @param email the email to look up
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_mailmap_resolve(
+ const char **real_name, const char **real_email,
+ const git_mailmap *mm, const char *name, const char *email);
+
+/**
+ * Resolve a signature to use real names and emails with a mailmap.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * @param out new signature
+ * @param mm mailmap to resolve with
+ * @param sig signature to resolve
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_mailmap_resolve_signature(
+ git_signature **out, const git_mailmap *mm, const git_signature *sig);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/merge.h b/include/git2/merge.h
new file mode 100644
index 0000000..fcce559
--- /dev/null
+++ b/include/git2/merge.h
@@ -0,0 +1,626 @@
+/*
+ * 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_merge_h__
+#define INCLUDE_git_merge_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "oidarray.h"
+#include "checkout.h"
+#include "index.h"
+#include "annotated_commit.h"
+
+/**
+ * @file git2/merge.h
+ * @brief Git merge routines
+ * @defgroup git_merge Git merge routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The file inputs to `git_merge_file`. Callers should populate the
+ * `git_merge_file_input` structure with descriptions of the files in
+ * each side of the conflict for use in producing the merge file.
+ */
+typedef struct {
+ unsigned int version;
+
+ /** Pointer to the contents of the file. */
+ const char *ptr;
+
+ /** Size of the contents pointed to in `ptr`. */
+ size_t size;
+
+ /** File name of the conflicted file, or `NULL` to not merge the path. */
+ const char *path;
+
+ /** File mode of the conflicted file, or `0` to not merge the mode. */
+ unsigned int mode;
+} git_merge_file_input;
+
+#define GIT_MERGE_FILE_INPUT_VERSION 1
+#define GIT_MERGE_FILE_INPUT_INIT {GIT_MERGE_FILE_INPUT_VERSION}
+
+/**
+ * Initializes a `git_merge_file_input` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_FILE_INPUT_INIT.
+ *
+ * @param opts the `git_merge_file_input` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_MERGE_FILE_INPUT_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_input_init(
+ git_merge_file_input *opts,
+ unsigned int version);
+
+/**
+ * Flags for `git_merge` options. A combination of these flags can be
+ * passed in via the `flags` value in the `git_merge_options`.
+ */
+typedef enum {
+ /**
+ * Detect renames that occur between the common ancestor and the "ours"
+ * side or the common ancestor and the "theirs" side. This will enable
+ * the ability to merge between a modified and renamed file.
+ */
+ GIT_MERGE_FIND_RENAMES = (1 << 0),
+
+ /**
+ * If a conflict occurs, exit immediately instead of attempting to
+ * continue resolving conflicts. The merge operation will fail with
+ * GIT_EMERGECONFLICT and no index will be returned.
+ */
+ GIT_MERGE_FAIL_ON_CONFLICT = (1 << 1),
+
+ /**
+ * Do not write the REUC extension on the generated index
+ */
+ GIT_MERGE_SKIP_REUC = (1 << 2),
+
+ /**
+ * If the commits being merged have multiple merge bases, do not build
+ * a recursive merge base (by merging the multiple merge bases),
+ * instead simply use the first base. This flag provides a similar
+ * merge base to `git-merge-resolve`.
+ */
+ GIT_MERGE_NO_RECURSIVE = (1 << 3),
+
+ /**
+ * Treat this merge as if it is to produce the virtual base
+ * of a recursive merge. This will ensure that there are
+ * no conflicts, any conflicting regions will keep conflict
+ * markers in the merge result.
+ */
+ GIT_MERGE_VIRTUAL_BASE = (1 << 4)
+} git_merge_flag_t;
+
+/**
+ * Merge file favor options for `git_merge_options` instruct the file-level
+ * merging functionality how to deal with conflicting regions of the files.
+ */
+typedef enum {
+ /**
+ * When a region of a file is changed in both branches, a conflict
+ * will be recorded in the index so that `git_checkout` can produce
+ * a merge file with conflict markers in the working directory.
+ * This is the default.
+ */
+ GIT_MERGE_FILE_FAVOR_NORMAL = 0,
+
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain the "ours" side of any conflicting
+ * region. The index will not record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_OURS = 1,
+
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain the "theirs" side of any conflicting
+ * region. The index will not record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_THEIRS = 2,
+
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain each unique line from each side,
+ * which has the result of combining both files. The index will not
+ * record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_UNION = 3
+} git_merge_file_favor_t;
+
+/**
+ * File merging flags
+ */
+typedef enum {
+ /** Defaults */
+ GIT_MERGE_FILE_DEFAULT = 0,
+
+ /** Create standard conflicted merge files */
+ GIT_MERGE_FILE_STYLE_MERGE = (1 << 0),
+
+ /** Create diff3-style files */
+ GIT_MERGE_FILE_STYLE_DIFF3 = (1 << 1),
+
+ /** Condense non-alphanumeric regions for simplified diff file */
+ GIT_MERGE_FILE_SIMPLIFY_ALNUM = (1 << 2),
+
+ /** Ignore all whitespace */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE = (1 << 3),
+
+ /** Ignore changes in amount of whitespace */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = (1 << 4),
+
+ /** Ignore whitespace at end of line */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = (1 << 5),
+
+ /** Use the "patience diff" algorithm */
+ GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6),
+
+ /** Take extra time to find minimal diff */
+ GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
+
+ /** Create zdiff3 ("zealous diff3")-style files */
+ GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8),
+
+ /**
+ * Do not produce file conflicts when common regions have
+ * changed; keep the conflict markers in the file and accept
+ * that as the merge result.
+ */
+ GIT_MERGE_FILE_ACCEPT_CONFLICTS = (1 << 9)
+} git_merge_file_flag_t;
+
+#define GIT_MERGE_CONFLICT_MARKER_SIZE 7
+
+/**
+ * Options for merging a file
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Label for the ancestor file side of the conflict which will be prepended
+ * to labels in diff3-format merge files.
+ */
+ const char *ancestor_label;
+
+ /**
+ * Label for our file side of the conflict which will be prepended
+ * to labels in merge files.
+ */
+ const char *our_label;
+
+ /**
+ * Label for their file side of the conflict which will be prepended
+ * to labels in merge files.
+ */
+ const char *their_label;
+
+ /** The file to favor in region conflicts. */
+ git_merge_file_favor_t favor;
+
+ /** see `git_merge_file_flag_t` above */
+ uint32_t flags;
+
+ /** The size of conflict markers (eg, "<<<<<<<"). Default is
+ * GIT_MERGE_CONFLICT_MARKER_SIZE. */
+ unsigned short marker_size;
+} git_merge_file_options;
+
+#define GIT_MERGE_FILE_OPTIONS_VERSION 1
+#define GIT_MERGE_FILE_OPTIONS_INIT {GIT_MERGE_FILE_OPTIONS_VERSION}
+
+/**
+ * Initialize git_merge_file_options structure
+ *
+ * Initializes a `git_merge_file_options` with default values. Equivalent to
+ * creating an instance with `GIT_MERGE_FILE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_merge_file_options` struct to initialize.
+ * @param version The struct version; pass `GIT_MERGE_FILE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_options_init(git_merge_file_options *opts, unsigned int version);
+
+/**
+ * Information about file-level merging
+ */
+typedef struct {
+ /**
+ * True if the output was automerged, false if the output contains
+ * conflict markers.
+ */
+ unsigned int automergeable;
+
+ /**
+ * The path that the resultant merge file should use, or NULL if a
+ * filename conflict would occur.
+ */
+ const char *path;
+
+ /** The mode that the resultant merge file should use. */
+ unsigned int mode;
+
+ /** The contents of the merge. */
+ const char *ptr;
+
+ /** The length of the merge contents. */
+ size_t len;
+} git_merge_file_result;
+
+/**
+ * Merging options
+ */
+typedef struct {
+ unsigned int version;
+
+ /** See `git_merge_flag_t` above */
+ uint32_t flags;
+
+ /**
+ * Similarity to consider a file renamed (default 50). If
+ * `GIT_MERGE_FIND_RENAMES` is enabled, added files will be compared
+ * with deleted files to determine their similarity. Files that are
+ * more similar than the rename threshold (percentage-wise) will be
+ * treated as a rename.
+ */
+ unsigned int rename_threshold;
+
+ /**
+ * Maximum similarity sources to examine for renames (default 200).
+ * If the number of rename candidates (add / delete pairs) is greater
+ * than this value, inexact rename detection is aborted.
+ *
+ * This setting overrides the `merge.renameLimit` configuration value.
+ */
+ unsigned int target_limit;
+
+ /** Pluggable similarity metric; pass NULL to use internal metric */
+ git_diff_similarity_metric *metric;
+
+ /**
+ * Maximum number of times to merge common ancestors to build a
+ * virtual merge base when faced with criss-cross merges. When this
+ * limit is reached, the next ancestor will simply be used instead of
+ * attempting to merge it. The default is unlimited.
+ */
+ unsigned int recursion_limit;
+
+ /**
+ * Default merge driver to be used when both sides of a merge have
+ * changed. The default is the `text` driver.
+ */
+ const char *default_driver;
+
+ /**
+ * Flags for handling conflicting content, to be used with the standard
+ * (`text`) merge driver.
+ */
+ git_merge_file_favor_t file_favor;
+
+ /** see `git_merge_file_flag_t` above */
+ uint32_t file_flags;
+} git_merge_options;
+
+#define GIT_MERGE_OPTIONS_VERSION 1
+#define GIT_MERGE_OPTIONS_INIT { \
+ GIT_MERGE_OPTIONS_VERSION, GIT_MERGE_FIND_RENAMES }
+
+/**
+ * Initialize git_merge_options structure
+ *
+ * Initializes a `git_merge_options` with default values. Equivalent to
+ * creating an instance with `GIT_MERGE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_merge_options` struct to initialize.
+ * @param version The struct version; pass `GIT_MERGE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_options_init(git_merge_options *opts, unsigned int version);
+
+/**
+ * The results of `git_merge_analysis` indicate the merge opportunities.
+ */
+typedef enum {
+ /** No merge is possible. (Unused.) */
+ GIT_MERGE_ANALYSIS_NONE = 0,
+
+ /**
+ * A "normal" merge; both HEAD and the given merge input have diverged
+ * from their common ancestor. The divergent commits must be merged.
+ */
+ GIT_MERGE_ANALYSIS_NORMAL = (1 << 0),
+
+ /**
+ * All given merge inputs are reachable from HEAD, meaning the
+ * repository is up-to-date and no merge needs to be performed.
+ */
+ GIT_MERGE_ANALYSIS_UP_TO_DATE = (1 << 1),
+
+ /**
+ * The given merge input is a fast-forward from HEAD and no merge
+ * needs to be performed. Instead, the client can check out the
+ * given merge input.
+ */
+ GIT_MERGE_ANALYSIS_FASTFORWARD = (1 << 2),
+
+ /**
+ * The HEAD of the current repository is "unborn" and does not point to
+ * a valid commit. No merge can be performed, but the caller may wish
+ * to simply set HEAD to the target commit(s).
+ */
+ GIT_MERGE_ANALYSIS_UNBORN = (1 << 3)
+} git_merge_analysis_t;
+
+/**
+ * The user's stated preference for merges.
+ */
+typedef enum {
+ /**
+ * No configuration was found that suggests a preferred behavior for
+ * merge.
+ */
+ GIT_MERGE_PREFERENCE_NONE = 0,
+
+ /**
+ * There is a `merge.ff=false` configuration setting, suggesting that
+ * the user does not want to allow a fast-forward merge.
+ */
+ GIT_MERGE_PREFERENCE_NO_FASTFORWARD = (1 << 0),
+
+ /**
+ * There is a `merge.ff=only` configuration setting, suggesting that
+ * the user only wants fast-forward merges.
+ */
+ GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1)
+} git_merge_preference_t;
+
+/**
+ * Analyzes the given branch(es) and determines the opportunities for
+ * merging them into the HEAD of the repository.
+ *
+ * @param analysis_out analysis enumeration that the result is written into
+ * @param preference_out One of the `git_merge_preference_t` flag.
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_analysis(
+ git_merge_analysis_t *analysis_out,
+ git_merge_preference_t *preference_out,
+ git_repository *repo,
+ const git_annotated_commit **their_heads,
+ size_t their_heads_len);
+
+/**
+ * Analyzes the given branch(es) and determines the opportunities for
+ * merging them into a reference.
+ *
+ * @param analysis_out analysis enumeration that the result is written into
+ * @param preference_out One of the `git_merge_preference_t` flag.
+ * @param repo the repository to merge
+ * @param our_ref the reference to perform the analysis from
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_analysis_for_ref(
+ git_merge_analysis_t *analysis_out,
+ git_merge_preference_t *preference_out,
+ git_repository *repo,
+ git_reference *our_ref,
+ const git_annotated_commit **their_heads,
+ size_t their_heads_len);
+
+/**
+ * Find a merge base between two commits
+ *
+ * @param out the OID of a merge base between 'one' and 'two'
+ * @param repo the repository where the commits exist
+ * @param one one of the commits
+ * @param two the other commit
+ * @return 0 on success, GIT_ENOTFOUND if not found or error code
+ */
+GIT_EXTERN(int) git_merge_base(
+ git_oid *out,
+ git_repository *repo,
+ const git_oid *one,
+ const git_oid *two);
+
+/**
+ * Find merge bases between two commits
+ *
+ * @param out array in which to store the resulting ids
+ * @param repo the repository where the commits exist
+ * @param one one of the commits
+ * @param two the other commit
+ * @return 0 on success, GIT_ENOTFOUND if not found or error code
+ */
+GIT_EXTERN(int) git_merge_bases(
+ git_oidarray *out,
+ git_repository *repo,
+ const git_oid *one,
+ const git_oid *two);
+
+/**
+ * Find a merge base given a list of commits
+ *
+ * @param out the OID of a merge base considering all the commits
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_many(
+ git_oid *out,
+ git_repository *repo,
+ size_t length,
+ const git_oid input_array[]);
+
+/**
+ * Find all merge bases given a list of commits
+ *
+ * @param out array in which to store the resulting ids
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_bases_many(
+ git_oidarray *out,
+ git_repository *repo,
+ size_t length,
+ const git_oid input_array[]);
+
+/**
+ * Find a merge base in preparation for an octopus merge
+ *
+ * @param out the OID of a merge base considering all the commits
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_octopus(
+ git_oid *out,
+ git_repository *repo,
+ size_t length,
+ const git_oid input_array[]);
+
+/**
+ * Merge two files as they exist in the in-memory data structures, using
+ * the given common ancestor as the baseline, producing a
+ * `git_merge_file_result` that reflects the merge result. The
+ * `git_merge_file_result` must be freed with `git_merge_file_result_free`.
+ *
+ * Note that this function does not reference a repository and any
+ * configuration must be passed as `git_merge_file_options`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param ancestor The contents of the ancestor file
+ * @param ours The contents of the file in "our" side
+ * @param theirs The contents of the file in "their" side
+ * @param opts The merge file options or `NULL` for defaults
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file(
+ git_merge_file_result *out,
+ const git_merge_file_input *ancestor,
+ const git_merge_file_input *ours,
+ const git_merge_file_input *theirs,
+ const git_merge_file_options *opts);
+
+/**
+ * Merge two files as they exist in the index, using the given common
+ * ancestor as the baseline, producing a `git_merge_file_result` that
+ * reflects the merge result. The `git_merge_file_result` must be freed with
+ * `git_merge_file_result_free`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param repo The repository
+ * @param ancestor The index entry for the ancestor file (stage level 1)
+ * @param ours The index entry for our file (stage level 2)
+ * @param theirs The index entry for their file (stage level 3)
+ * @param opts The merge file options or NULL
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file_from_index(
+ git_merge_file_result *out,
+ git_repository *repo,
+ const git_index_entry *ancestor,
+ const git_index_entry *ours,
+ const git_index_entry *theirs,
+ const git_merge_file_options *opts);
+
+/**
+ * Frees a `git_merge_file_result`.
+ *
+ * @param result The result to free or `NULL`
+ */
+GIT_EXTERN(void) git_merge_file_result_free(git_merge_file_result *result);
+
+/**
+ * Merge two trees, producing a `git_index` that reflects the result of
+ * the merge. The index may be written as-is to the working directory
+ * or checked out. If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo repository that contains the given trees
+ * @param ancestor_tree the common ancestor between the trees (or null if none)
+ * @param our_tree the tree that reflects the destination tree
+ * @param their_tree the tree to merge in to `our_tree`
+ * @param opts the merge tree options (or null for defaults)
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_trees(
+ git_index **out,
+ git_repository *repo,
+ const git_tree *ancestor_tree,
+ const git_tree *our_tree,
+ const git_tree *their_tree,
+ const git_merge_options *opts);
+
+/**
+ * Merge two commits, producing a `git_index` that reflects the result of
+ * the merge. The index may be written as-is to the working directory
+ * or checked out. If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo repository that contains the given trees
+ * @param our_commit the commit that reflects the destination tree
+ * @param their_commit the commit to merge in to `our_commit`
+ * @param opts the merge tree options (or null for defaults)
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_commits(
+ git_index **out,
+ git_repository *repo,
+ const git_commit *our_commit,
+ const git_commit *their_commit,
+ const git_merge_options *opts);
+
+/**
+ * Merges the given commit(s) into HEAD, writing the results into the working
+ * directory. Any changes are staged for commit and any conflicts are written
+ * to the index. Callers should inspect the repository's index after this
+ * completes, resolve any conflicts and prepare a commit.
+ *
+ * For compatibility with git, the repository is put into a merging
+ * state. Once the commit is done (or if the user wishes to abort),
+ * you should clear this state by calling
+ * `git_repository_state_cleanup()`.
+ *
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @param merge_opts merge options
+ * @param checkout_opts checkout options
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge(
+ git_repository *repo,
+ const git_annotated_commit **their_heads,
+ size_t their_heads_len,
+ const git_merge_options *merge_opts,
+ const git_checkout_options *checkout_opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/message.h b/include/git2/message.h
new file mode 100644
index 0000000..cd3ddf7
--- /dev/null
+++ b/include/git2/message.h
@@ -0,0 +1,86 @@
+/*
+ * 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_message_h__
+#define INCLUDE_git_message_h__
+
+#include "common.h"
+#include "buffer.h"
+
+/**
+ * @file git2/message.h
+ * @brief Git message management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Clean up excess whitespace and make sure there is a trailing newline in the message.
+ *
+ * Optionally, it can remove lines which start with the comment character.
+ *
+ * @param out The user-allocated git_buf which will be filled with the
+ * cleaned up message.
+ *
+ * @param message The message to be prettified.
+ *
+ * @param strip_comments Non-zero to remove comment lines, 0 to leave them in.
+ *
+ * @param comment_char Comment character. Lines starting with this character
+ * are considered to be comments and removed if `strip_comments` is non-zero.
+ *
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
+
+/**
+ * Represents a single git message trailer.
+ */
+typedef struct {
+ const char *key;
+ const char *value;
+} git_message_trailer;
+
+/**
+ * Represents an array of git message trailers.
+ *
+ * Struct members under the private comment are private, subject to change
+ * and should not be used by callers.
+ */
+typedef struct {
+ git_message_trailer *trailers;
+ size_t count;
+
+ /* private */
+ char *_trailer_block;
+} git_message_trailer_array;
+
+/**
+ * Parse trailers out of a message, filling the array pointed to by +arr+.
+ *
+ * Trailers are key/value pairs in the last paragraph of a message, not
+ * including any patches or conflicts that may be present.
+ *
+ * @param arr A pre-allocated git_message_trailer_array struct to be filled in
+ * with any trailers found during parsing.
+ * @param message The message to be parsed
+ * @return 0 on success, or non-zero on error.
+ */
+GIT_EXTERN(int) git_message_trailers(git_message_trailer_array *arr, const char *message);
+
+/**
+ * Clean's up any allocated memory in the git_message_trailer_array filled by
+ * a call to git_message_trailers.
+ *
+ * @param arr The trailer to free.
+ */
+GIT_EXTERN(void) git_message_trailer_array_free(git_message_trailer_array *arr);
+
+/** @} */
+GIT_END_DECL
+
+#endif /* INCLUDE_git_message_h__ */
diff --git a/include/git2/net.h b/include/git2/net.h
new file mode 100644
index 0000000..8103eaf
--- /dev/null
+++ b/include/git2/net.h
@@ -0,0 +1,54 @@
+/*
+ * 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_net_h__
+#define INCLUDE_git_net_h__
+
+#include "common.h"
+#include "oid.h"
+#include "types.h"
+
+/**
+ * @file git2/net.h
+ * @brief Git networking declarations
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+#define GIT_DEFAULT_PORT "9418"
+
+/**
+ * Direction of the connection.
+ *
+ * We need this because we need to know whether we should call
+ * git-upload-pack or git-receive-pack on the remote end when get_refs
+ * gets called.
+ */
+typedef enum {
+ GIT_DIRECTION_FETCH = 0,
+ GIT_DIRECTION_PUSH = 1
+} git_direction;
+
+/**
+ * Description of a reference advertised by a remote server, given out
+ * on `ls` calls.
+ */
+struct git_remote_head {
+ int local; /* available locally */
+ git_oid oid;
+ git_oid loid;
+ char *name;
+ /**
+ * If the server send a symref mapping for this ref, this will
+ * point to the target.
+ */
+ char *symref_target;
+};
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/notes.h b/include/git2/notes.h
new file mode 100644
index 0000000..c135881
--- /dev/null
+++ b/include/git2/notes.h
@@ -0,0 +1,306 @@
+/*
+ * 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_note_h__
+#define INCLUDE_git_note_h__
+
+#include "oid.h"
+
+/**
+ * @file git2/notes.h
+ * @brief Git notes management routines
+ * @defgroup git_note Git notes management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Callback for git_note_foreach.
+ *
+ * Receives:
+ * - blob_id: Oid of the blob containing the message
+ * - annotated_object_id: Oid of the git object being annotated
+ * - payload: Payload data passed to `git_note_foreach`
+ */
+typedef int GIT_CALLBACK(git_note_foreach_cb)(
+ const git_oid *blob_id, const git_oid *annotated_object_id, void *payload);
+
+/**
+ * note iterator
+ */
+typedef struct git_iterator git_note_iterator;
+
+/**
+ * Creates a new iterator for notes
+ *
+ * The iterator must be freed manually by the user.
+ *
+ * @param out pointer to the iterator
+ * @param repo repository where to look up the note
+ * @param notes_ref canonical name of the reference to use (optional); defaults to
+ * "refs/notes/commits"
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_iterator_new(
+ git_note_iterator **out,
+ git_repository *repo,
+ const char *notes_ref);
+
+/**
+ * Creates a new iterator for notes from a commit
+ *
+ * The iterator must be freed manually by the user.
+ *
+ * @param out pointer to the iterator
+ * @param notes_commit a pointer to the notes commit object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_commit_iterator_new(
+ git_note_iterator **out,
+ git_commit *notes_commit);
+
+/**
+ * Frees an git_note_iterator
+ *
+ * @param it pointer to the iterator
+ */
+GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it);
+
+/**
+ * Return the current item (note_id and annotated_id) and advance the iterator
+ * internally to the next value
+ *
+ * @param note_id id of blob containing the message
+ * @param annotated_id id of the git object being annotated
+ * @param it pointer to the iterator
+ *
+ * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code
+ * (negative value)
+ */
+GIT_EXTERN(int) git_note_next(
+ git_oid *note_id,
+ git_oid *annotated_id,
+ git_note_iterator *it);
+
+
+/**
+ * Read the note for an object
+ *
+ * The note must be freed manually by the user.
+ *
+ * @param out pointer to the read note; NULL in case of error
+ * @param repo repository where to look up the note
+ * @param notes_ref canonical name of the reference to use (optional); defaults to
+ * "refs/notes/commits"
+ * @param oid OID of the git object to read the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_read(
+ git_note **out,
+ git_repository *repo,
+ const char *notes_ref,
+ const git_oid *oid);
+
+
+/**
+ * Read the note for an object from a note commit
+ *
+ * The note must be freed manually by the user.
+ *
+ * @param out pointer to the read note; NULL in case of error
+ * @param repo repository where to look up the note
+ * @param notes_commit a pointer to the notes commit object
+ * @param oid OID of the git object to read the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_commit_read(
+ git_note **out,
+ git_repository *repo,
+ git_commit *notes_commit,
+ const git_oid *oid);
+
+/**
+ * Get the note author
+ *
+ * @param note the note
+ * @return the author
+ */
+GIT_EXTERN(const git_signature *) git_note_author(const git_note *note);
+
+/**
+ * Get the note committer
+ *
+ * @param note the note
+ * @return the committer
+ */
+GIT_EXTERN(const git_signature *) git_note_committer(const git_note *note);
+
+
+/**
+ * Get the note message
+ *
+ * @param note the note
+ * @return the note message
+ */
+GIT_EXTERN(const char *) git_note_message(const git_note *note);
+
+
+/**
+ * Get the note object's id
+ *
+ * @param note the note
+ * @return the note object's id
+ */
+GIT_EXTERN(const git_oid *) git_note_id(const git_note *note);
+
+/**
+ * Add a note for an object
+ *
+ * @param out pointer to store the OID (optional); NULL in case of error
+ * @param repo repository where to store the note
+ * @param notes_ref canonical name of the reference to use (optional);
+ * defaults to "refs/notes/commits"
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to decorate
+ * @param note Content of the note to add for object oid
+ * @param force Overwrite existing note
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_create(
+ git_oid *out,
+ git_repository *repo,
+ const char *notes_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const git_oid *oid,
+ const char *note,
+ int force);
+
+/**
+ * Add a note for an object from a commit
+ *
+ * This function will create a notes commit for a given object,
+ * the commit is a dangling commit, no reference is created.
+ *
+ * @param notes_commit_out pointer to store the commit (optional);
+ * NULL in case of error
+ * @param notes_blob_out a point to the id of a note blob (optional)
+ * @param repo repository where the note will live
+ * @param parent Pointer to parent note
+ * or NULL if this shall start a new notes tree
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to decorate
+ * @param note Content of the note to add for object oid
+ * @param allow_note_overwrite Overwrite existing note
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_commit_create(
+ git_oid *notes_commit_out,
+ git_oid *notes_blob_out,
+ git_repository *repo,
+ git_commit *parent,
+ const git_signature *author,
+ const git_signature *committer,
+ const git_oid *oid,
+ const char *note,
+ int allow_note_overwrite);
+
+/**
+ * Remove the note for an object
+ *
+ * @param repo repository where the note lives
+ * @param notes_ref canonical name of the reference to use (optional);
+ * defaults to "refs/notes/commits"
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to remove the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_remove(
+ git_repository *repo,
+ const char *notes_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const git_oid *oid);
+
+/**
+ * Remove the note for an object
+ *
+ * @param notes_commit_out pointer to store the new notes commit (optional);
+ * NULL in case of error.
+ * When removing a note a new tree containing all notes
+ * sans the note to be removed is created and a new commit
+ * pointing to that tree is also created.
+ * In the case where the resulting tree is an empty tree
+ * a new commit pointing to this empty tree will be returned.
+ * @param repo repository where the note lives
+ * @param notes_commit a pointer to the notes commit object
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to remove the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_commit_remove(
+ git_oid *notes_commit_out,
+ git_repository *repo,
+ git_commit *notes_commit,
+ const git_signature *author,
+ const git_signature *committer,
+ const git_oid *oid);
+
+/**
+ * Free a git_note object
+ *
+ * @param note git_note object
+ */
+GIT_EXTERN(void) git_note_free(git_note *note);
+
+/**
+ * Get the default notes reference for a repository
+ *
+ * @param out buffer in which to store the name of the default notes reference
+ * @param repo The Git repository
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_default_ref(git_buf *out, git_repository *repo);
+
+/**
+ * Loop over all the notes within a specified namespace
+ * and issue a callback for each one.
+ *
+ * @param repo Repository where to find the notes.
+ *
+ * @param notes_ref Reference to read from (optional); defaults to
+ * "refs/notes/commits".
+ *
+ * @param note_cb Callback to invoke per found annotation. Return non-zero
+ * to stop looping.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_note_foreach(
+ git_repository *repo,
+ const char *notes_ref,
+ git_note_foreach_cb note_cb,
+ void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/object.h b/include/git2/object.h
new file mode 100644
index 0000000..6384aaa
--- /dev/null
+++ b/include/git2/object.h
@@ -0,0 +1,279 @@
+/*
+ * 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_object_h__
+#define INCLUDE_git_object_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/object.h
+ * @brief Git revision object management routines
+ * @defgroup git_object Git revision object management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+#define GIT_OBJECT_SIZE_MAX UINT64_MAX
+
+/**
+ * Lookup a reference to one of the objects in a repository.
+ *
+ * The generated reference is owned by the repository and
+ * should be closed with the `git_object_free` method
+ * instead of free'd manually.
+ *
+ * The 'type' parameter must match the type of the object
+ * in the odb; the method will fail otherwise.
+ * The special value 'GIT_OBJECT_ANY' may be passed to let
+ * the method guess the object's type.
+ *
+ * @param object pointer to the looked-up object
+ * @param repo the repository to look up the object
+ * @param id the unique identifier for the object
+ * @param type the type of the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_object_lookup(
+ git_object **object,
+ git_repository *repo,
+ const git_oid *id,
+ git_object_t type);
+
+/**
+ * Lookup a reference to one of the objects in a repository,
+ * given a prefix of its identifier (short id).
+ *
+ * The object obtained will be so that its identifier
+ * matches the first 'len' hexadecimal characters
+ * (packets of 4 bits) of the given 'id'.
+ * 'len' must be at least GIT_OID_MINPREFIXLEN, and
+ * long enough to identify a unique object matching
+ * the prefix; otherwise the method will fail.
+ *
+ * The generated reference is owned by the repository and
+ * should be closed with the `git_object_free` method
+ * instead of free'd manually.
+ *
+ * The 'type' parameter must match the type of the object
+ * in the odb; the method will fail otherwise.
+ * The special value 'GIT_OBJECT_ANY' may be passed to let
+ * the method guess the object's type.
+ *
+ * @param object_out pointer where to store the looked-up object
+ * @param repo the repository to look up the object
+ * @param id a short identifier for the object
+ * @param len the length of the short identifier
+ * @param type the type of the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_object_lookup_prefix(
+ git_object **object_out,
+ git_repository *repo,
+ const git_oid *id,
+ size_t len,
+ git_object_t type);
+
+
+/**
+ * Lookup an object that represents a tree entry.
+ *
+ * @param out buffer that receives a pointer to the object (which must be freed
+ * by the caller)
+ * @param treeish root object that can be peeled to a tree
+ * @param path relative path from the root object to the desired object
+ * @param type type of object desired
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_object_lookup_bypath(
+ git_object **out,
+ const git_object *treeish,
+ const char *path,
+ git_object_t type);
+
+/**
+ * Get the id (SHA1) of a repository object
+ *
+ * @param obj the repository object
+ * @return the SHA1 id
+ */
+GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj);
+
+/**
+ * Get a short abbreviated OID string for the object
+ *
+ * This starts at the "core.abbrev" length (default 7 characters) and
+ * iteratively extends to a longer string if that length is ambiguous.
+ * The result will be unambiguous (at least until new objects are added to
+ * the repository).
+ *
+ * @param out Buffer to write string into
+ * @param obj The object to get an ID for
+ * @return 0 on success, <0 for error
+ */
+GIT_EXTERN(int) git_object_short_id(git_buf *out, const git_object *obj);
+
+/**
+ * Get the object type of an object
+ *
+ * @param obj the repository object
+ * @return the object's type
+ */
+GIT_EXTERN(git_object_t) git_object_type(const git_object *obj);
+
+/**
+ * Get the repository that owns this object
+ *
+ * Freeing or calling `git_repository_close` on the
+ * returned pointer will invalidate the actual object.
+ *
+ * Any other operation may be run on the repository without
+ * affecting the object.
+ *
+ * @param obj the object
+ * @return the repository who owns this object
+ */
+GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
+
+/**
+ * Close an open object
+ *
+ * This method instructs the library to close an existing
+ * object; note that git_objects are owned and cached by the repository
+ * so the object may or may not be freed after this library call,
+ * depending on how aggressive is the caching mechanism used
+ * by the repository.
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop using
+ * an object. Failure to do so will cause a memory leak.
+ *
+ * @param object the object to close
+ */
+GIT_EXTERN(void) git_object_free(git_object *object);
+
+/**
+ * Convert an object type to its string representation.
+ *
+ * The result is a pointer to a string in static memory and
+ * should not be free()'ed.
+ *
+ * @param type object type to convert.
+ * @return the corresponding string representation.
+ */
+GIT_EXTERN(const char *) git_object_type2string(git_object_t type);
+
+/**
+ * Convert a string object type representation to it's git_object_t.
+ *
+ * @param str the string to convert.
+ * @return the corresponding git_object_t.
+ */
+GIT_EXTERN(git_object_t) git_object_string2type(const char *str);
+
+/**
+ * Determine if the given git_object_t is a valid loose object type.
+ *
+ * @param type object type to test.
+ * @return true if the type represents a valid loose object type,
+ * false otherwise.
+ */
+GIT_EXTERN(int) git_object_typeisloose(git_object_t type);
+
+/**
+ * Recursively peel an object until an object of the specified type is met.
+ *
+ * If the query cannot be satisfied due to the object model,
+ * GIT_EINVALIDSPEC will be returned (e.g. trying to peel a blob to a
+ * tree).
+ *
+ * If you pass `GIT_OBJECT_ANY` as the target type, then the object will
+ * be peeled until the type changes. A tag will be peeled until the
+ * referenced object is no longer a tag, and a commit will be peeled
+ * to a tree. Any other object type will return GIT_EINVALIDSPEC.
+ *
+ * If peeling a tag we discover an object which cannot be peeled to
+ * the target type due to the object model, GIT_EPEEL will be
+ * returned.
+ *
+ * You must free the returned object.
+ *
+ * @param peeled Pointer to the peeled git_object
+ * @param object The object to be processed
+ * @param target_type The type of the requested object (a GIT_OBJECT_ value)
+ * @return 0 on success, GIT_EINVALIDSPEC, GIT_EPEEL, or an error code
+ */
+GIT_EXTERN(int) git_object_peel(
+ git_object **peeled,
+ const git_object *object,
+ git_object_t target_type);
+
+/**
+ * Create an in-memory copy of a Git object. The copy must be
+ * explicitly free'd or it will leak.
+ *
+ * @param dest Pointer to store the copy of the object
+ * @param source Original object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+/**
+ * Analyzes a buffer of raw object content and determines its validity.
+ * Tree, commit, and tag objects will be parsed and ensured that they
+ * are valid, parseable content. (Blobs are always valid by definition.)
+ * An error message will be set with an informative message if the object
+ * is not valid.
+ *
+ * @warning This function is experimental and its signature may change in
+ * the future.
+ *
+ * @param valid Output pointer to set with validity of the object content
+ * @param buf The contents to validate
+ * @param len The length of the buffer
+ * @param object_type The type of the object in the buffer
+ * @param oid_type The object ID type for the OIDs in the given buffer
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_object_rawcontent_is_valid(
+ int *valid,
+ const char *buf,
+ size_t len,
+ git_object_t object_type,
+ git_oid_t oid_type);
+#else
+/**
+ * Analyzes a buffer of raw object content and determines its validity.
+ * Tree, commit, and tag objects will be parsed and ensured that they
+ * are valid, parseable content. (Blobs are always valid by definition.)
+ * An error message will be set with an informative message if the object
+ * is not valid.
+ *
+ * @warning This function is experimental and its signature may change in
+ * the future.
+ *
+ * @param valid Output pointer to set with validity of the object content
+ * @param buf The contents to validate
+ * @param len The length of the buffer
+ * @param object_type The type of the object in the buffer
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_object_rawcontent_is_valid(
+ int *valid,
+ const char *buf,
+ size_t len,
+ git_object_t object_type);
+#endif
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/odb.h b/include/git2/odb.h
new file mode 100644
index 0000000..c7d6a89
--- /dev/null
+++ b/include/git2/odb.h
@@ -0,0 +1,654 @@
+/*
+ * 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_odb_h__
+#define INCLUDE_git_odb_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "oidarray.h"
+#include "indexer.h"
+
+/**
+ * @file git2/odb.h
+ * @brief Git object database routines
+ * @defgroup git_odb Git object database routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Flags controlling the behavior of ODB lookup operations */
+typedef enum {
+ /**
+ * Don't call `git_odb_refresh` if the lookup fails. Useful when doing
+ * a batch of lookup operations for objects that may legitimately not
+ * exist. When using this flag, you may wish to manually call
+ * `git_odb_refresh` before processing a batch of objects.
+ */
+ GIT_ODB_LOOKUP_NO_REFRESH = (1 << 0)
+} git_odb_lookup_flags_t;
+
+/**
+ * Function type for callbacks from git_odb_foreach.
+ */
+typedef int GIT_CALLBACK(git_odb_foreach_cb)(const git_oid *id, void *payload);
+
+/** Options for configuring a loose object backend. */
+typedef struct {
+ unsigned int version; /**< version for the struct */
+
+ /**
+ * Type of object IDs to use for this object database, or
+ * 0 for default (currently SHA1).
+ */
+ git_oid_t oid_type;
+} git_odb_options;
+
+/* The current version of the diff options structure */
+#define GIT_ODB_OPTIONS_VERSION 1
+
+/* Stack initializer for odb options. Alternatively use
+ * `git_odb_options_init` programmatic initialization.
+ */
+#define GIT_ODB_OPTIONS_INIT { GIT_ODB_OPTIONS_VERSION }
+
+/**
+ * Create a new object database with no backends.
+ *
+ * Before the ODB can be used for read/writing, a custom database
+ * backend must be manually added using `git_odb_add_backend()`
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param opts the options for this object database or NULL for defaults
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_new(git_odb **out, const git_odb_options *opts);
+#else
+GIT_EXTERN(int) git_odb_new(git_odb **out);
+#endif
+
+/**
+ * Create a new object database and automatically add
+ * the two default backends:
+ *
+ * - git_odb_backend_loose: read and write loose object files
+ * from disk, assuming `objects_dir` as the Objects folder
+ *
+ * - git_odb_backend_pack: read objects from packfiles,
+ * assuming `objects_dir` as the Objects folder which
+ * contains a 'pack/' folder with the corresponding data
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param objects_dir path of the backends' "objects" directory.
+ * @param opts the options for this object database or NULL for defaults
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_open(
+ git_odb **out,
+ const char *objects_dir,
+ const git_odb_options *opts);
+#else
+GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
+#endif
+
+/**
+ * Add an on-disk alternate to an existing Object DB.
+ *
+ * Note that the added path must point to an `objects`, not
+ * to a full repository, to use it as an alternate store.
+ *
+ * Alternate backends are always checked for objects *after*
+ * all the main backends have been exhausted.
+ *
+ * Writing is disabled on alternate backends.
+ *
+ * @param odb database to add the backend to
+ * @param path path to the objects folder for the alternate
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path);
+
+/**
+ * Close an open object database.
+ *
+ * @param db database pointer to close. If NULL no action is taken.
+ */
+GIT_EXTERN(void) git_odb_free(git_odb *db);
+
+/**
+ * Read an object from the database.
+ *
+ * This method queries all available ODB backends
+ * trying to read the given OID.
+ *
+ * The returned object is reference counted and
+ * internally cached, so it should be closed
+ * by the user once it's no longer in use.
+ *
+ * @param out pointer where to store the read object
+ * @param db database to search for the object in.
+ * @param id identity of the object to read.
+ * @return 0 if the object was read, GIT_ENOTFOUND if the object is
+ * not in the database.
+ */
+GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id);
+
+/**
+ * Read an object from the database, given a prefix
+ * of its identifier.
+ *
+ * This method queries all available ODB backends
+ * trying to match the 'len' first hexadecimal
+ * characters of the 'short_id'.
+ * The remaining (GIT_OID_SHA1_HEXSIZE-len)*4 bits of
+ * 'short_id' must be 0s.
+ * 'len' must be at least GIT_OID_MINPREFIXLEN,
+ * and the prefix must be long enough to identify
+ * a unique object in all the backends; the
+ * method will fail otherwise.
+ *
+ * The returned object is reference counted and
+ * internally cached, so it should be closed
+ * by the user once it's no longer in use.
+ *
+ * @param out pointer where to store the read object
+ * @param db database to search for the object in.
+ * @param short_id a prefix of the id of the object to read.
+ * @param len the length of the prefix
+ * @return 0 if the object was read, GIT_ENOTFOUND if the object is not in the
+ * database. GIT_EAMBIGUOUS if the prefix is ambiguous
+ * (several objects match the prefix)
+ */
+GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len);
+
+/**
+ * Read the header of an object from the database, without
+ * reading its full contents.
+ *
+ * The header includes the length and the type of an object.
+ *
+ * Note that most backends do not support reading only the header
+ * of an object, so the whole object will be read and then the
+ * header will be returned.
+ *
+ * @param len_out pointer where to store the length
+ * @param type_out pointer where to store the type
+ * @param db database to search for the object in.
+ * @param id identity of the object to read.
+ * @return 0 if the object was read, GIT_ENOTFOUND if the object is not
+ * in the database.
+ */
+GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_object_t *type_out, git_odb *db, const git_oid *id);
+
+/**
+ * Determine if the given object can be found in the object database.
+ *
+ * @param db database to be searched for the given object.
+ * @param id the object to search for.
+ * @return 1 if the object was found, 0 otherwise
+ */
+GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
+
+/**
+ * Determine if the given object can be found in the object database, with
+ * extended options.
+ *
+ * @param db database to be searched for the given object.
+ * @param id the object to search for.
+ * @param flags flags affecting the lookup (see `git_odb_lookup_flags_t`)
+ * @return 1 if the object was found, 0 otherwise
+ */
+GIT_EXTERN(int) git_odb_exists_ext(git_odb *db, const git_oid *id, unsigned int flags);
+
+/**
+ * Determine if an object can be found in the object database by an
+ * abbreviated object ID.
+ *
+ * @param out The full OID of the found object if just one is found.
+ * @param db The database to be searched for the given object.
+ * @param short_id A prefix of the id of the object to read.
+ * @param len The length of the prefix.
+ * @return 0 if found, GIT_ENOTFOUND if not found, GIT_EAMBIGUOUS if multiple
+ * matches were found, other value < 0 if there was a read error.
+ */
+GIT_EXTERN(int) git_odb_exists_prefix(
+ git_oid *out, git_odb *db, const git_oid *short_id, size_t len);
+
+/**
+ * The information about object IDs to query in `git_odb_expand_ids`,
+ * which will be populated upon return.
+ */
+typedef struct git_odb_expand_id {
+ /** The object ID to expand */
+ git_oid id;
+
+ /**
+ * The length of the object ID (in nibbles, or packets of 4 bits; the
+ * number of hex characters)
+ * */
+ unsigned short length;
+
+ /**
+ * The (optional) type of the object to search for; leave as `0` or set
+ * to `GIT_OBJECT_ANY` to query for any object matching the ID.
+ */
+ git_object_t type;
+} git_odb_expand_id;
+
+/**
+ * Determine if one or more objects can be found in the object database
+ * by their abbreviated object ID and type.
+ *
+ * The given array will be updated in place: for each abbreviated ID that is
+ * unique in the database, and of the given type (if specified),
+ * the full object ID, object ID length (`GIT_OID_SHA1_HEXSIZE`) and type will be
+ * written back to the array. For IDs that are not found (or are ambiguous),
+ * the array entry will be zeroed.
+ *
+ * Note that since this function operates on multiple objects, the
+ * underlying database will not be asked to be reloaded if an object is
+ * not found (which is unlike other object database operations.)
+ *
+ * @param db The database to be searched for the given objects.
+ * @param ids An array of short object IDs to search for
+ * @param count The length of the `ids` array
+ * @return 0 on success or an error code on failure
+ */
+GIT_EXTERN(int) git_odb_expand_ids(
+ git_odb *db,
+ git_odb_expand_id *ids,
+ size_t count);
+
+/**
+ * Refresh the object database to load newly added files.
+ *
+ * If the object databases have changed on disk while the library
+ * is running, this function will force a reload of the underlying
+ * indexes.
+ *
+ * Use this function when you're confident that an external
+ * application has tampered with the ODB.
+ *
+ * NOTE that it is not necessary to call this function at all. The
+ * library will automatically attempt to refresh the ODB
+ * when a lookup fails, to see if the looked up object exists
+ * on disk but hasn't been loaded yet.
+ *
+ * @param db database to refresh
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_refresh(struct git_odb *db);
+
+/**
+ * List all objects available in the database
+ *
+ * The callback will be called for each object available in the
+ * database. Note that the objects are likely to be returned in the index
+ * order, which would make accessing the objects in that order inefficient.
+ * Return a non-zero value from the callback to stop looping.
+ *
+ * @param db database to use
+ * @param cb the callback to call for each object
+ * @param payload data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload);
+
+/**
+ * Write an object directly into the ODB
+ *
+ * This method writes a full object straight into the ODB.
+ * For most cases, it is preferred to write objects through a write
+ * stream, which is both faster and less memory intensive, specially
+ * for big objects.
+ *
+ * This method is provided for compatibility with custom backends
+ * which are not able to support streaming writes
+ *
+ * @param out pointer to store the OID result of the write
+ * @param odb object database where to store the object
+ * @param data buffer with the data to store
+ * @param len size of the buffer
+ * @param type type of the data to store
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_object_t type);
+
+/**
+ * Open a stream to write an object into the ODB
+ *
+ * The type and final length of the object must be specified
+ * when opening the stream.
+ *
+ * The returned stream will be of type `GIT_STREAM_WRONLY`, and it
+ * won't be effective until `git_odb_stream_finalize_write` is called
+ * and returns without an error
+ *
+ * The stream must always be freed when done with `git_odb_stream_free` or
+ * will leak memory.
+ *
+ * @see git_odb_stream
+ *
+ * @param out pointer where to store the stream
+ * @param db object database where the stream will write
+ * @param size final size of the object that will be written
+ * @param type type of the object that will be written
+ * @return 0 if the stream was created; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, git_object_size_t size, git_object_t type);
+
+/**
+ * Write to an odb stream
+ *
+ * This method will fail if the total number of received bytes exceeds the
+ * size declared with `git_odb_open_wstream()`
+ *
+ * @param stream the stream
+ * @param buffer the data to write
+ * @param len the buffer's length
+ * @return 0 if the write succeeded, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len);
+
+/**
+ * Finish writing to an odb stream
+ *
+ * The object will take its final name and will be available to the
+ * odb.
+ *
+ * This method will fail if the total number of received bytes
+ * differs from the size declared with `git_odb_open_wstream()`
+ *
+ * @param out pointer to store the resulting object's id
+ * @param stream the stream
+ * @return 0 on success, an error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream);
+
+/**
+ * Read from an odb stream
+ *
+ * Most backends don't implement streaming reads
+ *
+ * @param stream the stream
+ * @param buffer a user-allocated buffer to store the data in.
+ * @param len the buffer's length
+ * @return 0 if the read succeeded, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len);
+
+/**
+ * Free an odb stream
+ *
+ * @param stream the stream to free
+ */
+GIT_EXTERN(void) git_odb_stream_free(git_odb_stream *stream);
+
+/**
+ * Open a stream to read an object from the ODB
+ *
+ * Note that most backends do *not* support streaming reads
+ * because they store their objects as compressed/delta'ed blobs.
+ *
+ * It's recommended to use `git_odb_read` instead, which is
+ * assured to work on all backends.
+ *
+ * The returned stream will be of type `GIT_STREAM_RDONLY` and
+ * will have the following methods:
+ *
+ * - stream->read: read `n` bytes from the stream
+ * - stream->free: free the stream
+ *
+ * The stream must always be free'd or will leak memory.
+ *
+ * @see git_odb_stream
+ *
+ * @param out pointer where to store the stream
+ * @param len pointer where to store the length of the object
+ * @param type pointer where to store the type of the object
+ * @param db object database where the stream will read from
+ * @param oid oid of the object the stream will read from
+ * @return 0 if the stream was created, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_open_rstream(
+ git_odb_stream **out,
+ size_t *len,
+ git_object_t *type,
+ git_odb *db,
+ const git_oid *oid);
+
+/**
+ * Open a stream for writing a pack file to the ODB.
+ *
+ * If the ODB layer understands pack files, then the given
+ * packfile will likely be streamed directly to disk (and a
+ * corresponding index created). If the ODB layer does not
+ * understand pack files, the objects will be stored in whatever
+ * format the ODB layer uses.
+ *
+ * @see git_odb_writepack
+ *
+ * @param out pointer to the writepack functions
+ * @param db object database where the stream will read from
+ * @param progress_cb function to call with progress information.
+ * Be aware that this is called inline with network and indexing operations,
+ * so performance may be affected.
+ * @param progress_payload payload for the progress callback
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_odb_write_pack(
+ git_odb_writepack **out,
+ git_odb *db,
+ git_indexer_progress_cb progress_cb,
+ void *progress_payload);
+
+/**
+ * Write a `multi-pack-index` file from all the `.pack` files in the ODB.
+ *
+ * If the ODB layer understands pack files, then this will create a file called
+ * `multi-pack-index` next to the `.pack` and `.idx` files, which will contain
+ * an index of all objects stored in `.pack` files. This will allow for
+ * O(log n) lookup for n objects (regardless of how many packfiles there
+ * exist).
+ *
+ * @param db object database where the `multi-pack-index` file will be written.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_odb_write_multi_pack_index(
+ git_odb *db);
+
+/**
+ * Determine the object-ID (sha1 or sha256 hash) of a data buffer
+ *
+ * The resulting OID will be the identifier for the data buffer as if
+ * the data buffer it were to written to the ODB.
+ *
+ * @param out the resulting object-ID.
+ * @param data data to hash
+ * @param len size of the data
+ * @param object_type of the data to hash
+ * @param oid_type the oid type to hash to
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_hash(
+ git_oid *out,
+ const void *data,
+ size_t len,
+ git_object_t object_type,
+ git_oid_t oid_type);
+#else
+GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_object_t type);
+#endif
+
+/**
+ * Read a file from disk and fill a git_oid with the object id
+ * that the file would have if it were written to the Object
+ * Database as an object of the given type (w/o applying filters).
+ * Similar functionality to git.git's `git hash-object` without
+ * the `-w` flag, however, with the --no-filters flag.
+ * If you need filters, see git_repository_hashfile.
+ *
+ * @param out oid structure the result is written into.
+ * @param path file to read and determine object id for
+ * @param object_type of the data to hash
+ * @param oid_type the oid type to hash to
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_hashfile(
+ git_oid *out,
+ const char *path,
+ git_object_t object_type,
+ git_oid_t oid_type);
+#else
+GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_object_t type);
+#endif
+
+/**
+ * Create a copy of an odb_object
+ *
+ * The returned copy must be manually freed with `git_odb_object_free`.
+ * Note that because of an implementation detail, the returned copy will be
+ * the same pointer as `source`: the object is internally refcounted, so the
+ * copy still needs to be freed twice.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_object_dup(git_odb_object **dest, git_odb_object *source);
+
+/**
+ * Close an ODB object
+ *
+ * This method must always be called once a `git_odb_object` is no
+ * longer needed, otherwise memory will leak.
+ *
+ * @param object object to close
+ */
+GIT_EXTERN(void) git_odb_object_free(git_odb_object *object);
+
+/**
+ * Return the OID of an ODB object
+ *
+ * This is the OID from which the object was read from
+ *
+ * @param object the object
+ * @return a pointer to the OID
+ */
+GIT_EXTERN(const git_oid *) git_odb_object_id(git_odb_object *object);
+
+/**
+ * Return the data of an ODB object
+ *
+ * This is the uncompressed, raw data as read from the ODB,
+ * without the leading header.
+ *
+ * This pointer is owned by the object and shall not be free'd.
+ *
+ * @param object the object
+ * @return a pointer to the data
+ */
+GIT_EXTERN(const void *) git_odb_object_data(git_odb_object *object);
+
+/**
+ * Return the size of an ODB object
+ *
+ * This is the real size of the `data` buffer, not the
+ * actual size of the object.
+ *
+ * @param object the object
+ * @return the size
+ */
+GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object);
+
+/**
+ * Return the type of an ODB object
+ *
+ * @param object the object
+ * @return the type
+ */
+GIT_EXTERN(git_object_t) git_odb_object_type(git_odb_object *object);
+
+/**
+ * Add a custom backend to an existing Object DB
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Read <sys/odb_backend.h> for more information.
+ *
+ * @param odb database to add the backend to
+ * @param backend pointer to a git_odb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Add a custom backend to an existing Object DB; this
+ * backend will work as an alternate.
+ *
+ * Alternate backends are always checked for objects *after*
+ * all the main backends have been exhausted.
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Writing is disabled on alternate backends.
+ *
+ * Read <sys/odb_backend.h> for more information.
+ *
+ * @param odb database to add the backend to
+ * @param backend pointer to a git_odb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Get the number of ODB backend objects
+ *
+ * @param odb object database
+ * @return number of backends in the ODB
+ */
+GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb);
+
+/**
+ * Lookup an ODB backend object by index
+ *
+ * @param out output pointer to ODB backend at pos
+ * @param odb object database
+ * @param pos index into object database backend list
+ * @return 0 on success, GIT_ENOTFOUND if pos is invalid, other errors < 0
+ */
+GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos);
+
+/**
+ * Set the git commit-graph for the ODB.
+ *
+ * After a successful call, the ownership of the cgraph parameter will be
+ * transferred to libgit2, and the caller should not free it.
+ *
+ * The commit-graph can also be unset by explicitly passing NULL as the cgraph
+ * parameter.
+ *
+ * @param odb object database
+ * @param cgraph the git commit-graph
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
new file mode 100644
index 0000000..12dd0fd
--- /dev/null
+++ b/include/git2/odb_backend.h
@@ -0,0 +1,223 @@
+/*
+ * 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_odb_backend_h__
+#define INCLUDE_git_odb_backend_h__
+
+#include "common.h"
+#include "types.h"
+#include "indexer.h"
+
+/**
+ * @file git2/backend.h
+ * @brief Git custom backend functions
+ * @defgroup git_odb Git object database routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/*
+ * Constructors for in-box ODB backends.
+ */
+
+/** Options for configuring a packfile object backend. */
+typedef struct {
+ unsigned int version; /**< version for the struct */
+
+ /**
+ * Type of object IDs to use for this object database, or
+ * 0 for default (currently SHA1).
+ */
+ git_oid_t oid_type;
+} git_odb_backend_pack_options;
+
+/* The current version of the diff options structure */
+#define GIT_ODB_BACKEND_PACK_OPTIONS_VERSION 1
+
+/* Stack initializer for odb pack backend options. Alternatively use
+ * `git_odb_backend_pack_options_init` programmatic initialization.
+ */
+#define GIT_ODB_BACKEND_PACK_OPTIONS_INIT \
+ { GIT_ODB_BACKEND_PACK_OPTIONS_VERSION }
+
+/**
+ * Create a backend for the packfiles.
+ *
+ * @param out location to store the odb backend pointer
+ * @param objects_dir the Git repository's objects directory
+ *
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_backend_pack(
+ git_odb_backend **out,
+ const char *objects_dir,
+ const git_odb_backend_pack_options *opts);
+#else
+GIT_EXTERN(int) git_odb_backend_pack(
+ git_odb_backend **out,
+ const char *objects_dir);
+#endif
+
+/**
+ * Create a backend out of a single packfile
+ *
+ * This can be useful for inspecting the contents of a single
+ * packfile.
+ *
+ * @param out location to store the odb backend pointer
+ * @param index_file path to the packfile's .idx file
+ *
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_backend_one_pack(
+ git_odb_backend **out,
+ const char *index_file,
+ const git_odb_backend_pack_options *opts);
+#else
+GIT_EXTERN(int) git_odb_backend_one_pack(
+ git_odb_backend **out,
+ const char *index_file);
+#endif
+
+typedef enum {
+ GIT_ODB_BACKEND_LOOSE_FSYNC = (1 << 0)
+} git_odb_backend_loose_flag_t;
+
+/** Options for configuring a loose object backend. */
+typedef struct {
+ unsigned int version; /**< version for the struct */
+
+ /** A combination of the `git_odb_backend_loose_flag_t` types. */
+ uint32_t flags;
+
+ /**
+ * zlib compression level to use (0-9), where 1 is the fastest
+ * at the expense of larger files, and 9 produces the best
+ * compression at the expense of speed. 0 indicates that no
+ * compression should be performed. -1 is the default (currently
+ * optimizing for speed).
+ */
+ int compression_level;
+
+ /** Permissions to use creating a directory or 0 for defaults */
+ unsigned int dir_mode;
+
+ /** Permissions to use creating a file or 0 for defaults */
+ unsigned int file_mode;
+
+ /**
+ * Type of object IDs to use for this object database, or
+ * 0 for default (currently SHA1).
+ */
+ git_oid_t oid_type;
+} git_odb_backend_loose_options;
+
+/* The current version of the diff options structure */
+#define GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION 1
+
+/* Stack initializer for odb loose backend options. Alternatively use
+ * `git_odb_backend_loose_options_init` programmatic initialization.
+ */
+#define GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT \
+ { GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION, 0, -1 }
+
+/**
+ * Create a backend for loose objects
+ *
+ * @param out location to store the odb backend pointer
+ * @param objects_dir the Git repository's objects directory
+ * @param opts options for the loose object backend or NULL
+ *
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_odb_backend_loose(
+ git_odb_backend **out,
+ const char *objects_dir,
+ git_odb_backend_loose_options *opts);
+#else
+GIT_EXTERN(int) git_odb_backend_loose(
+ git_odb_backend **out,
+ const char *objects_dir,
+ int compression_level,
+ int do_fsync,
+ unsigned int dir_mode,
+ unsigned int file_mode);
+#endif
+
+/** Streaming mode */
+typedef enum {
+ GIT_STREAM_RDONLY = (1 << 1),
+ GIT_STREAM_WRONLY = (1 << 2),
+ GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY)
+} git_odb_stream_t;
+
+/**
+ * A stream to read/write from a backend.
+ *
+ * This represents a stream of data being written to or read from a
+ * backend. When writing, the frontend functions take care of
+ * calculating the object's id and all `finalize_write` needs to do is
+ * store the object with the id it is passed.
+ */
+struct git_odb_stream {
+ git_odb_backend *backend;
+ unsigned int mode;
+ void *hash_ctx;
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ git_oid_t oid_type;
+#endif
+
+ git_object_size_t declared_size;
+ git_object_size_t received_bytes;
+
+ /**
+ * Write at most `len` bytes into `buffer` and advance the stream.
+ */
+ int GIT_CALLBACK(read)(git_odb_stream *stream, char *buffer, size_t len);
+
+ /**
+ * Write `len` bytes from `buffer` into the stream.
+ */
+ int GIT_CALLBACK(write)(git_odb_stream *stream, const char *buffer, size_t len);
+
+ /**
+ * Store the contents of the stream as an object with the id
+ * specified in `oid`.
+ *
+ * This method might not be invoked if:
+ * - an error occurs earlier with the `write` callback,
+ * - the object referred to by `oid` already exists in any backend, or
+ * - the final number of received bytes differs from the size declared
+ * with `git_odb_open_wstream()`
+ */
+ int GIT_CALLBACK(finalize_write)(git_odb_stream *stream, const git_oid *oid);
+
+ /**
+ * Free the stream's memory.
+ *
+ * This method might be called without a call to `finalize_write` if
+ * an error occurs or if the object is already present in the ODB.
+ */
+ void GIT_CALLBACK(free)(git_odb_stream *stream);
+};
+
+/** A stream to write a pack file to the ODB */
+struct git_odb_writepack {
+ git_odb_backend *backend;
+
+ int GIT_CALLBACK(append)(git_odb_writepack *writepack, const void *data, size_t size, git_indexer_progress *stats);
+ int GIT_CALLBACK(commit)(git_odb_writepack *writepack, git_indexer_progress *stats);
+ void GIT_CALLBACK(free)(git_odb_writepack *writepack);
+};
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/oid.h b/include/git2/oid.h
new file mode 100644
index 0000000..35b43ef
--- /dev/null
+++ b/include/git2/oid.h
@@ -0,0 +1,373 @@
+/*
+ * 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_oid_h__
+#define INCLUDE_git_oid_h__
+
+#include "common.h"
+#include "types.h"
+#include "experimental.h"
+
+/**
+ * @file git2/oid.h
+ * @brief Git object id routines
+ * @defgroup git_oid Git object id routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** The type of object id. */
+typedef enum {
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ GIT_OID_SHA1 = 1, /**< SHA1 */
+ GIT_OID_SHA256 = 2 /**< SHA256 */
+#else
+ GIT_OID_SHA1 = 1 /**< SHA1 */
+#endif
+
+} git_oid_t;
+
+/*
+ * SHA1 is currently the only supported object ID type.
+ */
+
+/** SHA1 is currently libgit2's default oid type. */
+#define GIT_OID_DEFAULT GIT_OID_SHA1
+
+/** Size (in bytes) of a raw/binary sha1 oid */
+#define GIT_OID_SHA1_SIZE 20
+/** Size (in bytes) of a hex formatted sha1 oid */
+#define GIT_OID_SHA1_HEXSIZE (GIT_OID_SHA1_SIZE * 2)
+
+/**
+ * The binary representation of the null sha1 object ID.
+ */
+#ifndef GIT_EXPERIMENTAL_SHA256
+# define GIT_OID_SHA1_ZERO { { 0 } }
+#else
+# define GIT_OID_SHA1_ZERO { GIT_OID_SHA1, { 0 } }
+#endif
+
+/**
+ * The string representation of the null sha1 object ID.
+ */
+#define GIT_OID_SHA1_HEXZERO "0000000000000000000000000000000000000000"
+
+/*
+ * Experimental SHA256 support is a breaking change to the API.
+ * This exists for application compatibility testing.
+ */
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+
+/** Size (in bytes) of a raw/binary sha256 oid */
+# define GIT_OID_SHA256_SIZE 32
+/** Size (in bytes) of a hex formatted sha256 oid */
+# define GIT_OID_SHA256_HEXSIZE (GIT_OID_SHA256_SIZE * 2)
+
+/**
+ * The binary representation of the null sha256 object ID.
+ */
+# define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } }
+
+/**
+ * The string representation of the null sha256 object ID.
+ */
+# define GIT_OID_SHA256_HEXZERO "0000000000000000000000000000000000000000000000000000000000000000"
+
+#endif
+
+/* Maximum possible object ID size in raw / hex string format. */
+#ifndef GIT_EXPERIMENTAL_SHA256
+# define GIT_OID_MAX_SIZE GIT_OID_SHA1_SIZE
+# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA1_HEXSIZE
+#else
+# define GIT_OID_MAX_SIZE GIT_OID_SHA256_SIZE
+# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA256_HEXSIZE
+#endif
+
+/** Minimum length (in number of hex characters,
+ * i.e. packets of 4 bits) of an oid prefix */
+#define GIT_OID_MINPREFIXLEN 4
+
+/** Unique identity of any object (commit, tree, blob, tag). */
+typedef struct git_oid {
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ /** type of object id */
+ unsigned char type;
+#endif
+
+ /** raw binary formatted id */
+ unsigned char id[GIT_OID_MAX_SIZE];
+} git_oid;
+
+/**
+ * Parse a hex formatted object id into a git_oid.
+ *
+ * The appropriate number of bytes for the given object ID type will
+ * be read from the string - 40 bytes for SHA1, 64 bytes for SHA256.
+ * The given string need not be NUL terminated.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string; must be pointing at the start of
+ * the hex sequence and have at least the number of bytes
+ * needed for an oid encoded in hex (40 bytes for sha1,
+ * 256 bytes for sha256).
+ * @param type the type of object id
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str, git_oid_t type);
+#else
+GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
+#endif
+
+/**
+ * Parse a hex formatted NUL-terminated string into a git_oid.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string; must be null-terminated.
+ * @param type the type of object id
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str, git_oid_t type);
+#else
+GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
+#endif
+
+/**
+ * Parse N characters of a hex formatted object id into a git_oid.
+ *
+ * If N is odd, the last byte's high nibble will be read in and the
+ * low nibble set to zero.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string of at least size `length`
+ * @param length length of the input string
+ * @param type the type of object id
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length, git_oid_t type);
+#else
+GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length);
+#endif
+
+/**
+ * Copy an already raw oid into a git_oid structure.
+ *
+ * @param out oid structure the result is written into.
+ * @param raw the raw input bytes to be copied.
+ * @return 0 on success or error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type);
+#else
+GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw);
+#endif
+
+/**
+ * Format a git_oid into a hex string.
+ *
+ * @param out output hex string; must be pointing at the start of
+ * the hex sequence and have at least the number of bytes
+ * needed for an oid encoded in hex (40 bytes for SHA1,
+ * 64 bytes for SHA256). Only the oid digits are written;
+ * a '\\0' terminator must be added by the caller if it is
+ * required.
+ * @param id oid structure to format.
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_oid_fmt(char *out, const git_oid *id);
+
+/**
+ * Format a git_oid into a partial hex string.
+ *
+ * @param out output hex string; you say how many bytes to write.
+ * If the number of bytes is > GIT_OID_SHA1_HEXSIZE, extra bytes
+ * will be zeroed; if not, a '\0' terminator is NOT added.
+ * @param n number of characters to write into out string
+ * @param id oid structure to format.
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_oid_nfmt(char *out, size_t n, const git_oid *id);
+
+/**
+ * Format a git_oid into a loose-object path string.
+ *
+ * The resulting string is "aa/...", where "aa" is the first two
+ * hex digits of the oid and "..." is the remaining 38 digits.
+ *
+ * @param out output hex string; must be pointing at the start of
+ * the hex sequence and have at least the number of bytes
+ * needed for an oid encoded in hex (41 bytes for SHA1,
+ * 65 bytes for SHA256). Only the oid digits are written;
+ * a '\\0' terminator must be added by the caller if it
+ * is required.
+ * @param id oid structure to format.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_oid_pathfmt(char *out, const git_oid *id);
+
+/**
+ * Format a git_oid into a statically allocated c-string.
+ *
+ * The c-string is owned by the library and should not be freed
+ * by the user. If libgit2 is built with thread support, the string
+ * will be stored in TLS (i.e. one buffer per thread) to allow for
+ * concurrent calls of the function.
+ *
+ * @param oid The oid structure to format
+ * @return the c-string or NULL on failure
+ */
+GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
+
+/**
+ * Format a git_oid into a buffer as a hex format c-string.
+ *
+ * If the buffer is smaller than the size of a hex-formatted oid string
+ * plus an additional byte (GIT_OID_SHA_HEXSIZE + 1 for SHA1 or
+ * GIT_OID_SHA256_HEXSIZE + 1 for SHA256), then the resulting
+ * oid c-string will be truncated to n-1 characters (but will still be
+ * NUL-byte terminated).
+ *
+ * If there are any input parameter errors (out == NULL, n == 0, oid ==
+ * NULL), then a pointer to an empty string is returned, so that the
+ * return value can always be printed.
+ *
+ * @param out the buffer into which the oid string is output.
+ * @param n the size of the out buffer.
+ * @param id the oid structure to format.
+ * @return the out buffer pointer, assuming no input parameter
+ * errors, otherwise a pointer to an empty string.
+ */
+GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id);
+
+/**
+ * Copy an oid from one structure to another.
+ *
+ * @param out oid structure the result is written into.
+ * @param src oid structure to copy from.
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_oid_cpy(git_oid *out, const git_oid *src);
+
+/**
+ * Compare two oid structures.
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return <0, 0, >0 if a < b, a == b, a > b.
+ */
+GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
+
+/**
+ * Compare two oid structures for equality
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return true if equal, false otherwise
+ */
+GIT_EXTERN(int) git_oid_equal(const git_oid *a, const git_oid *b);
+
+/**
+ * Compare the first 'len' hexadecimal characters (packets of 4 bits)
+ * of two oid structures.
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @param len the number of hex chars to compare
+ * @return 0 in case of a match
+ */
+GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
+
+/**
+ * Check if an oid equals an hex formatted object id.
+ *
+ * @param id oid structure.
+ * @param str input hex string of an object id.
+ * @return 0 in case of a match, -1 otherwise.
+ */
+GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
+
+/**
+ * Compare an oid to an hex formatted object id.
+ *
+ * @param id oid structure.
+ * @param str input hex string of an object id.
+ * @return -1 if str is not valid, <0 if id sorts before str,
+ * 0 if id matches str, >0 if id sorts after str.
+ */
+GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str);
+
+/**
+ * Check is an oid is all zeros.
+ *
+ * @return 1 if all zeros, 0 otherwise.
+ */
+GIT_EXTERN(int) git_oid_is_zero(const git_oid *id);
+
+/**
+ * OID Shortener object
+ */
+typedef struct git_oid_shorten git_oid_shorten;
+
+/**
+ * Create a new OID shortener.
+ *
+ * The OID shortener is used to process a list of OIDs
+ * in text form and return the shortest length that would
+ * uniquely identify all of them.
+ *
+ * E.g. look at the result of `git log --abbrev`.
+ *
+ * @param min_length The minimal length for all identifiers,
+ * which will be used even if shorter OIDs would still
+ * be unique.
+ * @return a `git_oid_shorten` instance, NULL if OOM
+ */
+GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
+
+/**
+ * Add a new OID to set of shortened OIDs and calculate
+ * the minimal length to uniquely identify all the OIDs in
+ * the set.
+ *
+ * The OID is expected to be a 40-char hexadecimal string.
+ * The OID is owned by the user and will not be modified
+ * or freed.
+ *
+ * For performance reasons, there is a hard-limit of how many
+ * OIDs can be added to a single set (around ~32000, assuming
+ * a mostly randomized distribution), which should be enough
+ * for any kind of program, and keeps the algorithm fast and
+ * memory-efficient.
+ *
+ * Attempting to add more than those OIDs will result in a
+ * GIT_ERROR_INVALID error
+ *
+ * @param os a `git_oid_shorten` instance
+ * @param text_id an OID in text form
+ * @return the minimal length to uniquely identify all OIDs
+ * added so far to the set; or an error code (<0) if an
+ * error occurs.
+ */
+GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id);
+
+/**
+ * Free an OID shortener instance
+ *
+ * @param os a `git_oid_shorten` instance
+ */
+GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/oidarray.h b/include/git2/oidarray.h
new file mode 100644
index 0000000..94fc58d
--- /dev/null
+++ b/include/git2/oidarray.h
@@ -0,0 +1,37 @@
+/*
+ * 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_oidarray_h__
+#define INCLUDE_git_oidarray_h__
+
+#include "common.h"
+#include "oid.h"
+
+GIT_BEGIN_DECL
+
+/** Array of object ids */
+typedef struct git_oidarray {
+ git_oid *ids;
+ size_t count;
+} git_oidarray;
+
+/**
+ * Free the object IDs contained in an oid_array. This method should
+ * be called on `git_oidarray` objects that were provided by the
+ * library. Not doing so will result in a memory leak.
+ *
+ * This does not free the `git_oidarray` itself, since the library will
+ * never allocate that object directly itself.
+ *
+ * @param array git_oidarray from which to free oid data
+ */
+GIT_EXTERN(void) git_oidarray_dispose(git_oidarray *array);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/pack.h b/include/git2/pack.h
new file mode 100644
index 0000000..0f6bd2a
--- /dev/null
+++ b/include/git2/pack.h
@@ -0,0 +1,267 @@
+/*
+ * 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_pack_h__
+#define INCLUDE_git_pack_h__
+
+#include "common.h"
+#include "oid.h"
+#include "indexer.h"
+
+/**
+ * @file git2/pack.h
+ * @brief Git pack management routines
+ *
+ * Packing objects
+ * ---------------
+ *
+ * Creation of packfiles requires two steps:
+ *
+ * - First, insert all the objects you want to put into the packfile
+ * using `git_packbuilder_insert` and `git_packbuilder_insert_tree`.
+ * It's important to add the objects in recency order ("in the order
+ * that they are 'reachable' from head").
+ *
+ * "ANY order will give you a working pack, ... [but it is] the thing
+ * that gives packs good locality. It keeps the objects close to the
+ * head (whether they are old or new, but they are _reachable_ from the
+ * head) at the head of the pack. So packs actually have absolutely
+ * _wonderful_ IO patterns." - Linus Torvalds
+ * git.git/Documentation/technical/pack-heuristics.txt
+ *
+ * - Second, use `git_packbuilder_write` or `git_packbuilder_foreach` to
+ * write the resulting packfile.
+ *
+ * libgit2 will take care of the delta ordering and generation.
+ * `git_packbuilder_set_threads` can be used to adjust the number of
+ * threads used for the process.
+ *
+ * See tests/pack/packbuilder.c for an example.
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Stages that are reported by the packbuilder progress callback.
+ */
+typedef enum {
+ GIT_PACKBUILDER_ADDING_OBJECTS = 0,
+ GIT_PACKBUILDER_DELTAFICATION = 1
+} git_packbuilder_stage_t;
+
+/**
+ * Initialize a new packbuilder
+ *
+ * @param out The new packbuilder object
+ * @param repo The repository
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo);
+
+/**
+ * Set number of threads to spawn
+ *
+ * By default, libgit2 won't spawn any threads at all;
+ * when set to 0, libgit2 will autodetect the number of
+ * CPUs.
+ *
+ * @param pb The packbuilder
+ * @param n Number of threads to spawn
+ * @return number of actual threads to be used
+ */
+GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n);
+
+/**
+ * Insert a single object
+ *
+ * For an optimal pack it's mandatory to insert objects in recency order,
+ * commits followed by trees and blobs.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the commit
+ * @param name The name; might be NULL
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name);
+
+/**
+ * Insert a root tree object
+ *
+ * This will add the tree as well as all referenced trees and blobs.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the root tree
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id);
+
+/**
+ * Insert a commit object
+ *
+ * This will add a commit as well as the completed referenced tree.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the commit
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id);
+
+/**
+ * Insert objects as given by the walk
+ *
+ * Those commits and all objects they reference will be inserted into
+ * the packbuilder.
+ *
+ * @param pb the packbuilder
+ * @param walk the revwalk to use to fill the packbuilder
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk);
+
+/**
+ * Recursively insert an object and its referenced objects
+ *
+ * Insert the object as well as any object it references.
+ *
+ * @param pb the packbuilder
+ * @param id the id of the root object to insert
+ * @param name optional name for the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const char *name);
+
+/**
+ * Write the contents of the packfile to an in-memory buffer
+ *
+ * The contents of the buffer will become a valid packfile, even though there
+ * will be no attached index
+ *
+ * @param buf Buffer where to write the packfile
+ * @param pb The packbuilder
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
+
+/**
+ * Write the new pack and corresponding index file to path.
+ *
+ * @param pb The packbuilder
+ * @param path Path to the directory where the packfile and index should be stored, or NULL for default location
+ * @param mode permissions to use creating a packfile or 0 for defaults
+ * @param progress_cb function to call with progress information from the indexer (optional)
+ * @param progress_cb_payload payload for the progress callback (optional)
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_write(
+ git_packbuilder *pb,
+ const char *path,
+ unsigned int mode,
+ git_indexer_progress_cb progress_cb,
+ void *progress_cb_payload);
+
+#ifndef GIT_DEPRECATE_HARD
+/**
+ * Get the packfile's hash
+ *
+ * A packfile's name is derived from the sorted hashing of all object
+ * names. This is only correct after the packfile has been written.
+ *
+ * @deprecated use git_packbuilder_name
+ * @param pb The packbuilder object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
+#endif
+
+/**
+ * Get the unique name for the resulting packfile.
+ *
+ * The packfile's name is derived from the packfile's content.
+ * This is only correct after the packfile has been written.
+ *
+ * @param pb the packbuilder instance
+ * @return a NUL terminated string for the packfile name
+ */
+GIT_EXTERN(const char *) git_packbuilder_name(git_packbuilder *pb);
+
+/**
+ * Callback used to iterate over packed objects
+ *
+ * @see git_packbuilder_foreach
+ *
+ * @param buf A pointer to the object's data
+ * @param size The size of the underlying object
+ * @param payload Payload passed to git_packbuilder_foreach
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
+
+/**
+ * Create the new pack and pass each object to the callback
+ *
+ * @param pb the packbuilder
+ * @param cb the callback to call with each packed object's buffer
+ * @param payload the callback's data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload);
+
+/**
+ * Get the total number of objects the packbuilder will write out
+ *
+ * @param pb the packbuilder
+ * @return the number of objects in the packfile
+ */
+GIT_EXTERN(size_t) git_packbuilder_object_count(git_packbuilder *pb);
+
+/**
+ * Get the number of objects the packbuilder has already written out
+ *
+ * @param pb the packbuilder
+ * @return the number of objects which have already been written
+ */
+GIT_EXTERN(size_t) git_packbuilder_written(git_packbuilder *pb);
+
+/** Packbuilder progress notification function */
+typedef int GIT_CALLBACK(git_packbuilder_progress)(
+ int stage,
+ uint32_t current,
+ uint32_t total,
+ void *payload);
+
+/**
+ * Set the callbacks for a packbuilder
+ *
+ * @param pb The packbuilder object
+ * @param progress_cb Function to call with progress information during
+ * pack building. Be aware that this is called inline with pack building
+ * operations, so performance may be affected.
+ * @param progress_cb_payload Payload for progress callback.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_set_callbacks(
+ git_packbuilder *pb,
+ git_packbuilder_progress progress_cb,
+ void *progress_cb_payload);
+
+/**
+ * Free the packbuilder and all associated data
+ *
+ * @param pb The packbuilder
+ */
+GIT_EXTERN(void) git_packbuilder_free(git_packbuilder *pb);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/patch.h b/include/git2/patch.h
new file mode 100644
index 0000000..9cf758a
--- /dev/null
+++ b/include/git2/patch.h
@@ -0,0 +1,290 @@
+/*
+ * 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_patch_h__
+#define INCLUDE_git_patch_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "diff.h"
+
+/**
+ * @file git2/patch.h
+ * @brief Patch handling routines.
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The diff patch is used to store all the text diffs for a delta.
+ *
+ * You can easily loop over the content of patches and get information about
+ * them.
+ */
+typedef struct git_patch git_patch;
+
+/**
+ * Get the repository associated with this patch. May be NULL.
+ *
+ * @param patch the patch
+ * @return a pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_patch_owner(const git_patch *patch);
+
+/**
+ * Return a patch for an entry in the diff list.
+ *
+ * The `git_patch` is a newly created object contains the text diffs
+ * for the delta. You have to call `git_patch_free()` when you are
+ * done with it. You can use the patch object to loop over all the hunks
+ * and lines in the diff of the one delta.
+ *
+ * For an unchanged file or a binary file, no `git_patch` will be
+ * created, the output will be set to NULL, and the `binary` flag will be
+ * set true in the `git_diff_delta` structure.
+ *
+ * It is okay to pass NULL for either of the output parameters; if you pass
+ * NULL for the `git_patch`, then the text diff will not be calculated.
+ *
+ * @param out Output parameter for the delta patch object
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return 0 on success, other value < 0 on error
+ */
+GIT_EXTERN(int) git_patch_from_diff(
+ git_patch **out, git_diff *diff, size_t idx);
+
+/**
+ * Directly generate a patch from the difference between two blobs.
+ *
+ * This is just like `git_diff_blobs()` except it generates a patch object
+ * for the difference instead of directly making callbacks. You can use the
+ * standard `git_patch` accessor functions to read the patch data, and
+ * you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param new_as_path Treat new blob as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blobs(
+ git_patch **out,
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const git_blob *new_blob,
+ const char *new_as_path,
+ const git_diff_options *opts);
+
+/**
+ * Directly generate a patch from the difference between a blob and a buffer.
+ *
+ * This is just like `git_diff_blob_to_buffer()` except it generates a patch
+ * object for the difference instead of directly making callbacks. You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param buffer Raw data for new side of diff, or NULL for empty
+ * @param buffer_len Length of raw data for new side of diff
+ * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blob_and_buffer(
+ git_patch **out,
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const void *buffer,
+ size_t buffer_len,
+ const char *buffer_as_path,
+ const git_diff_options *opts);
+
+/**
+ * Directly generate a patch from the difference between two buffers.
+ *
+ * This is just like `git_diff_buffers()` except it generates a patch
+ * object for the difference instead of directly making callbacks. You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_buffers(
+ git_patch **out,
+ const void *old_buffer,
+ size_t old_len,
+ const char *old_as_path,
+ const void *new_buffer,
+ size_t new_len,
+ const char *new_as_path,
+ const git_diff_options *opts);
+
+/**
+ * Free a git_patch object.
+ *
+ * @param patch The patch to free.
+ */
+GIT_EXTERN(void) git_patch_free(git_patch *patch);
+
+/**
+ * Get the delta associated with a patch. This delta points to internal
+ * data and you do not have to release it when you are done with it.
+ *
+ * @param patch The patch in which to get the delta.
+ * @return The delta associated with the patch.
+ */
+GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch);
+
+/**
+ * Get the number of hunks in a patch
+ *
+ * @param patch The patch in which to get the number of hunks.
+ * @return The number of hunks of the patch.
+ */
+GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch);
+
+/**
+ * Get line counts of each type in a patch.
+ *
+ * This helps imitate a diff --numstat type of output. For that purpose,
+ * you only need the `total_additions` and `total_deletions` values, but we
+ * include the `total_context` line count in case you want the total number
+ * of lines of diff output that will be generated.
+ *
+ * All outputs are optional. Pass NULL if you don't need a particular count.
+ *
+ * @param total_context Count of context lines in output, can be NULL.
+ * @param total_additions Count of addition lines in output, can be NULL.
+ * @param total_deletions Count of deletion lines in output, can be NULL.
+ * @param patch The git_patch object
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_patch_line_stats(
+ size_t *total_context,
+ size_t *total_additions,
+ size_t *total_deletions,
+ const git_patch *patch);
+
+/**
+ * Get the information about a hunk in a patch
+ *
+ * Given a patch and a hunk index into the patch, this returns detailed
+ * information about that hunk. Any of the output pointers can be passed
+ * as NULL if you don't care about that particular piece of information.
+ *
+ * @param out Output pointer to git_diff_hunk of hunk
+ * @param lines_in_hunk Output count of total lines in this hunk
+ * @param patch Input pointer to patch object
+ * @param hunk_idx Input index of hunk to get information about
+ * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error
+ */
+GIT_EXTERN(int) git_patch_get_hunk(
+ const git_diff_hunk **out,
+ size_t *lines_in_hunk,
+ git_patch *patch,
+ size_t hunk_idx);
+
+/**
+ * Get the number of lines in a hunk.
+ *
+ * @param patch The git_patch object
+ * @param hunk_idx Index of the hunk
+ * @return Number of lines in hunk or GIT_ENOTFOUND if invalid hunk index
+ */
+GIT_EXTERN(int) git_patch_num_lines_in_hunk(
+ const git_patch *patch,
+ size_t hunk_idx);
+
+/**
+ * Get data about a line in a hunk of a patch.
+ *
+ * Given a patch, a hunk index, and a line index in the hunk, this
+ * will return a lot of details about that line. If you pass a hunk
+ * index larger than the number of hunks or a line index larger than
+ * the number of lines in the hunk, this will return -1.
+ *
+ * @param out The git_diff_line data for this line
+ * @param patch The patch to look in
+ * @param hunk_idx The index of the hunk
+ * @param line_of_hunk The index of the line in the hunk
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_patch_get_line_in_hunk(
+ const git_diff_line **out,
+ git_patch *patch,
+ size_t hunk_idx,
+ size_t line_of_hunk);
+
+/**
+ * Look up size of patch diff data in bytes
+ *
+ * This returns the raw size of the patch data. This only includes the
+ * actual data from the lines of the diff, not the file or hunk headers.
+ *
+ * If you pass `include_context` as true (non-zero), this will be the size
+ * of all of the diff output; if you pass it as false (zero), this will
+ * only include the actual changed lines (as if `context_lines` was 0).
+ *
+ * @param patch A git_patch representing changes to one file
+ * @param include_context Include context lines in size if non-zero
+ * @param include_hunk_headers Include hunk header lines if non-zero
+ * @param include_file_headers Include file header lines if non-zero
+ * @return The number of bytes of data
+ */
+GIT_EXTERN(size_t) git_patch_size(
+ git_patch *patch,
+ int include_context,
+ int include_hunk_headers,
+ int include_file_headers);
+
+/**
+ * Serialize the patch to text via callback.
+ *
+ * Returning a non-zero value from the callback will terminate the iteration
+ * and return that value to the caller.
+ *
+ * @param patch A git_patch representing changes to one file
+ * @param print_cb Callback function to output lines of the patch. Will be
+ * called for file headers, hunk headers, and diff lines.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_patch_print(
+ git_patch *patch,
+ git_diff_line_cb print_cb,
+ void *payload);
+
+/**
+ * Get the content of a patch as a single diff text.
+ *
+ * @param out The git_buf to be filled in
+ * @param patch A git_patch representing changes to one file
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_patch_to_buf(
+ git_buf *out,
+ git_patch *patch);
+
+GIT_END_DECL
+
+/**@}*/
+
+#endif
diff --git a/include/git2/pathspec.h b/include/git2/pathspec.h
new file mode 100644
index 0000000..acbd5cd
--- /dev/null
+++ b/include/git2/pathspec.h
@@ -0,0 +1,280 @@
+/*
+ * 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_pathspec_h__
+#define INCLUDE_git_pathspec_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "diff.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Compiled pathspec
+ */
+typedef struct git_pathspec git_pathspec;
+
+/**
+ * List of filenames matching a pathspec
+ */
+typedef struct git_pathspec_match_list git_pathspec_match_list;
+
+/**
+ * Options controlling how pathspec match should be executed
+ */
+typedef enum {
+ GIT_PATHSPEC_DEFAULT = 0,
+
+ /**
+ * GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
+ * match will use native case sensitivity of platform filesystem
+ */
+ GIT_PATHSPEC_IGNORE_CASE = (1u << 0),
+
+ /**
+ * GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
+ * match will use native case sensitivity of platform filesystem
+ */
+ GIT_PATHSPEC_USE_CASE = (1u << 1),
+
+ /**
+ * GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
+ * string comparison for matching
+ */
+ GIT_PATHSPEC_NO_GLOB = (1u << 2),
+
+ /**
+ * GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
+ * code GIT_ENOTFOUND if no matches are found; otherwise no matches is
+ * still success (return 0) but `git_pathspec_match_list_entrycount`
+ * will indicate 0 matches.
+ */
+ GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
+
+ /**
+ * GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
+ * should track which patterns matched which files so that at the end of
+ * the match we can identify patterns that did not match any files.
+ */
+ GIT_PATHSPEC_FIND_FAILURES = (1u << 4),
+
+ /**
+ * GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
+ * does not need to keep the actual matching filenames. Use this to
+ * just test if there were any matches at all or in combination with
+ * GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
+ */
+ GIT_PATHSPEC_FAILURES_ONLY = (1u << 5)
+} git_pathspec_flag_t;
+
+/**
+ * Compile a pathspec
+ *
+ * @param out Output of the compiled pathspec
+ * @param pathspec A git_strarray of the paths to match
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_pathspec_new(
+ git_pathspec **out, const git_strarray *pathspec);
+
+/**
+ * Free a pathspec
+ *
+ * @param ps The compiled pathspec
+ */
+GIT_EXTERN(void) git_pathspec_free(git_pathspec *ps);
+
+/**
+ * Try to match a path against a pathspec
+ *
+ * Unlike most of the other pathspec matching functions, this will not
+ * fall back on the native case-sensitivity for your platform. You must
+ * explicitly pass flags to control case sensitivity or else this will
+ * fall back on being case sensitive.
+ *
+ * @param ps The compiled pathspec
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param path The pathname to attempt to match
+ * @return 1 is path matches spec, 0 if it does not
+ */
+GIT_EXTERN(int) git_pathspec_matches_path(
+ const git_pathspec *ps, uint32_t flags, const char *path);
+
+/**
+ * Match a pathspec against the working directory of a repository.
+ *
+ * This matches the pathspec against the current files in the working
+ * directory of the repository. It is an error to invoke this on a bare
+ * repo. This handles git ignores (i.e. ignored files will not be
+ * considered to match the `pathspec` unless the file is tracked in the
+ * index).
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param repo The repository in which to match; bare repo is an error
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag was given
+ */
+GIT_EXTERN(int) git_pathspec_match_workdir(
+ git_pathspec_match_list **out,
+ git_repository *repo,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against entries in an index.
+ *
+ * This matches the pathspec against the files in the repository index.
+ *
+ * NOTE: At the moment, the case sensitivity of this match is controlled
+ * by the current case-sensitivity of the index object itself and the
+ * USE_CASE and IGNORE_CASE flags will have no effect. This behavior will
+ * be corrected in a future release.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param index The index to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_index(
+ git_pathspec_match_list **out,
+ git_index *index,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a tree.
+ *
+ * This matches the pathspec against the files in the given tree.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param tree The root-level tree to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_tree(
+ git_pathspec_match_list **out,
+ git_tree *tree,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a diff list.
+ *
+ * This matches the pathspec against the files in the given diff list.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param diff A generated diff list
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_diff(
+ git_pathspec_match_list **out,
+ git_diff *diff,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Free memory associates with a git_pathspec_match_list
+ *
+ * @param m The git_pathspec_match_list to be freed
+ */
+GIT_EXTERN(void) git_pathspec_match_list_free(git_pathspec_match_list *m);
+
+/**
+ * Get the number of items in a match list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in match list
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_entrycount(
+ const git_pathspec_match_list *m);
+
+/**
+ * Get a matching filename by position.
+ *
+ * This routine cannot be used if the match list was generated by
+ * `git_pathspec_match_diff`. If so, it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get a matching diff delta by position.
+ *
+ * This routine can only be used if the match list was generated by
+ * `git_pathspec_match_diff`. Otherwise it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const git_diff_delta *) git_pathspec_match_list_diff_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get the number of pathspec items that did not match.
+ *
+ * This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when
+ * generating the git_pathspec_match_list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in original pathspec that had no matches
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
+ const git_pathspec_match_list *m);
+
+/**
+ * Get an original pathspec string that had no matches.
+ *
+ * This will be return NULL for positions out of range.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the failed items
+ * @return The pathspec pattern that didn't match anything
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+GIT_END_DECL
+#endif
diff --git a/include/git2/proxy.h b/include/git2/proxy.h
new file mode 100644
index 0000000..cfc0c64
--- /dev/null
+++ b/include/git2/proxy.h
@@ -0,0 +1,98 @@
+/*
+ * 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_proxy_h__
+#define INCLUDE_git_proxy_h__
+
+#include "common.h"
+
+#include "cert.h"
+#include "credential.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * The type of proxy to use.
+ */
+typedef enum {
+ /**
+ * Do not attempt to connect through a proxy
+ *
+ * If built against libcurl, it itself may attempt to connect
+ * to a proxy if the environment variables specify it.
+ */
+ GIT_PROXY_NONE,
+ /**
+ * Try to auto-detect the proxy from the git configuration.
+ */
+ GIT_PROXY_AUTO,
+ /**
+ * Connect via the URL given in the options
+ */
+ GIT_PROXY_SPECIFIED
+} git_proxy_t;
+
+/**
+ * Options for connecting through a proxy
+ *
+ * Note that not all types may be supported, depending on the platform
+ * and compilation options.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * The type of proxy to use, by URL, auto-detect.
+ */
+ git_proxy_t type;
+
+ /**
+ * The URL of the proxy.
+ */
+ const char *url;
+
+ /**
+ * This will be called if the remote host requires
+ * authentication in order to connect to it.
+ *
+ * Returning GIT_PASSTHROUGH will make libgit2 behave as
+ * though this field isn't set.
+ */
+ git_credential_acquire_cb credentials;
+
+ /**
+ * If cert verification fails, this will be called to let the
+ * user make the final decision of whether to allow the
+ * connection to proceed. Returns 0 to allow the connection
+ * or a negative value to indicate an error.
+ */
+ git_transport_certificate_check_cb certificate_check;
+
+ /**
+ * Payload to be provided to the credentials and certificate
+ * check callbacks.
+ */
+ void *payload;
+} git_proxy_options;
+
+#define GIT_PROXY_OPTIONS_VERSION 1
+#define GIT_PROXY_OPTIONS_INIT {GIT_PROXY_OPTIONS_VERSION}
+
+/**
+ * Initialize git_proxy_options structure
+ *
+ * Initializes a `git_proxy_options` with default values. Equivalent to
+ * creating an instance with `GIT_PROXY_OPTIONS_INIT`.
+ *
+ * @param opts The `git_proxy_options` struct to initialize.
+ * @param version The struct version; pass `GIT_PROXY_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_proxy_options_init(git_proxy_options *opts, unsigned int version);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/rebase.h b/include/git2/rebase.h
new file mode 100644
index 0000000..b1ac71f
--- /dev/null
+++ b/include/git2/rebase.h
@@ -0,0 +1,399 @@
+/*
+ * 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_rebase_h__
+#define INCLUDE_git_rebase_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "annotated_commit.h"
+#include "merge.h"
+#include "checkout.h"
+#include "commit.h"
+
+/**
+ * @file git2/rebase.h
+ * @brief Git rebase routines
+ * @defgroup git_rebase Git merge routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Rebase options
+ *
+ * Use to tell the rebase machinery how to operate.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Used by `git_rebase_init`, this will instruct other clients working
+ * on this rebase that you want a quiet rebase experience, which they
+ * may choose to provide in an application-specific manner. This has no
+ * effect upon libgit2 directly, but is provided for interoperability
+ * between Git tools.
+ */
+ int quiet;
+
+ /**
+ * Used by `git_rebase_init`, this will begin an in-memory rebase,
+ * which will allow callers to step through the rebase operations and
+ * commit the rebased changes, but will not rewind HEAD or update the
+ * repository to be in a rebasing state. This will not interfere with
+ * the working directory (if there is one).
+ */
+ int inmemory;
+
+ /**
+ * Used by `git_rebase_finish`, this is the name of the notes reference
+ * used to rewrite notes for rebased commits when finishing the rebase;
+ * if NULL, the contents of the configuration option `notes.rewriteRef`
+ * is examined, unless the configuration option `notes.rewrite.rebase`
+ * is set to false. If `notes.rewriteRef` is also NULL, notes will
+ * not be rewritten.
+ */
+ const char *rewrite_notes_ref;
+
+ /**
+ * Options to control how trees are merged during `git_rebase_next`.
+ */
+ git_merge_options merge_options;
+
+ /**
+ * Options to control how files are written during `git_rebase_init`,
+ * `git_rebase_next` and `git_rebase_abort`. Note that a minimum
+ * strategy of `GIT_CHECKOUT_SAFE` is defaulted in `init` and `next`,
+ * and a minimum strategy of `GIT_CHECKOUT_FORCE` is defaulted in
+ * `abort` to match git semantics.
+ */
+ git_checkout_options checkout_options;
+
+ /**
+ * Optional callback that allows users to override commit
+ * creation in `git_rebase_commit`. If specified, users can
+ * create their own commit and provide the commit ID, which
+ * may be useful for signing commits or otherwise customizing
+ * the commit creation.
+ *
+ * If this callback returns `GIT_PASSTHROUGH`, then
+ * `git_rebase_commit` will continue to create the commit.
+ */
+ git_commit_create_cb commit_create_cb;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ /**
+ * If provided, this will be called with the commit content, allowing
+ * a signature to be added to the rebase commit. Can be skipped with
+ * GIT_PASSTHROUGH. If GIT_PASSTHROUGH is returned, a commit will be made
+ * without a signature.
+ *
+ * This field is only used when performing git_rebase_commit.
+ *
+ * This callback is not invoked if a `git_commit_create_cb` is
+ * specified.
+ *
+ * This callback is deprecated; users should provide a
+ * creation callback as `commit_create_cb` that produces a
+ * commit buffer, signs it, and commits it.
+ */
+ int (*signing_cb)(git_buf *, git_buf *, const char *, void *);
+#endif
+
+ /**
+ * This will be passed to each of the callbacks in this struct
+ * as the last parameter.
+ */
+ void *payload;
+} git_rebase_options;
+
+/**
+ * Type of rebase operation in-progress after calling `git_rebase_next`.
+ */
+typedef enum {
+ /**
+ * The given commit is to be cherry-picked. The client should commit
+ * the changes and continue if there are no conflicts.
+ */
+ GIT_REBASE_OPERATION_PICK = 0,
+
+ /**
+ * The given commit is to be cherry-picked, but the client should prompt
+ * the user to provide an updated commit message.
+ */
+ GIT_REBASE_OPERATION_REWORD,
+
+ /**
+ * The given commit is to be cherry-picked, but the client should stop
+ * to allow the user to edit the changes before committing them.
+ */
+ GIT_REBASE_OPERATION_EDIT,
+
+ /**
+ * The given commit is to be squashed into the previous commit. The
+ * commit message will be merged with the previous message.
+ */
+ GIT_REBASE_OPERATION_SQUASH,
+
+ /**
+ * The given commit is to be squashed into the previous commit. The
+ * commit message from this commit will be discarded.
+ */
+ GIT_REBASE_OPERATION_FIXUP,
+
+ /**
+ * No commit will be cherry-picked. The client should run the given
+ * command and (if successful) continue.
+ */
+ GIT_REBASE_OPERATION_EXEC
+} git_rebase_operation_t;
+
+#define GIT_REBASE_OPTIONS_VERSION 1
+#define GIT_REBASE_OPTIONS_INIT \
+ { GIT_REBASE_OPTIONS_VERSION, 0, 0, NULL, GIT_MERGE_OPTIONS_INIT, \
+ GIT_CHECKOUT_OPTIONS_INIT, NULL, NULL }
+
+/** Indicates that a rebase operation is not (yet) in progress. */
+#define GIT_REBASE_NO_OPERATION SIZE_MAX
+
+/**
+ * A rebase operation
+ *
+ * Describes a single instruction/operation to be performed during the
+ * rebase.
+ */
+typedef struct {
+ /** The type of rebase operation. */
+ git_rebase_operation_t type;
+
+ /**
+ * The commit ID being cherry-picked. This will be populated for
+ * all operations except those of type `GIT_REBASE_OPERATION_EXEC`.
+ */
+ const git_oid id;
+
+ /**
+ * The executable the user has requested be run. This will only
+ * be populated for operations of type `GIT_REBASE_OPERATION_EXEC`.
+ */
+ const char *exec;
+} git_rebase_operation;
+
+/**
+ * Initialize git_rebase_options structure
+ *
+ * Initializes a `git_rebase_options` with default values. Equivalent to
+ * creating an instance with `GIT_REBASE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_rebase_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REBASE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_options_init(
+ git_rebase_options *opts,
+ unsigned int version);
+
+/**
+ * Initializes a rebase operation to rebase the changes in `branch`
+ * relative to `upstream` onto another branch. To begin the rebase
+ * process, call `git_rebase_next`. When you have finished with this
+ * object, call `git_rebase_free`.
+ *
+ * @param out Pointer to store the rebase object
+ * @param repo The repository to perform the rebase
+ * @param branch The terminal commit to rebase, or NULL to rebase the
+ * current branch
+ * @param upstream The commit to begin rebasing from, or NULL to rebase all
+ * reachable commits
+ * @param onto The branch to rebase onto, or NULL to rebase onto the given
+ * upstream
+ * @param opts Options to specify how rebase is performed, or NULL
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_init(
+ git_rebase **out,
+ git_repository *repo,
+ const git_annotated_commit *branch,
+ const git_annotated_commit *upstream,
+ const git_annotated_commit *onto,
+ const git_rebase_options *opts);
+
+/**
+ * Opens an existing rebase that was previously started by either an
+ * invocation of `git_rebase_init` or by another client.
+ *
+ * @param out Pointer to store the rebase object
+ * @param repo The repository that has a rebase in-progress
+ * @param opts Options to specify how rebase is performed
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_open(
+ git_rebase **out,
+ git_repository *repo,
+ const git_rebase_options *opts);
+
+/**
+ * Gets the original `HEAD` ref name for merge rebases.
+ *
+ * @param rebase The in-progress rebase.
+ * @return The original `HEAD` ref name
+ */
+GIT_EXTERN(const char *) git_rebase_orig_head_name(git_rebase *rebase);
+
+/**
+ * Gets the original `HEAD` id for merge rebases.
+ *
+ * @param rebase The in-progress rebase.
+ * @return The original `HEAD` id
+ */
+GIT_EXTERN(const git_oid *) git_rebase_orig_head_id(git_rebase *rebase);
+
+/**
+ * Gets the `onto` ref name for merge rebases.
+ *
+ * @param rebase The in-progress rebase.
+ * @return The `onto` ref name
+ */
+GIT_EXTERN(const char *) git_rebase_onto_name(git_rebase *rebase);
+
+/**
+ * Gets the `onto` id for merge rebases.
+ *
+ * @param rebase The in-progress rebase.
+ * @return The `onto` id
+ */
+GIT_EXTERN(const git_oid *) git_rebase_onto_id(git_rebase *rebase);
+
+/**
+ * Gets the count of rebase operations that are to be applied.
+ *
+ * @param rebase The in-progress rebase
+ * @return The number of rebase operations in total
+ */
+GIT_EXTERN(size_t) git_rebase_operation_entrycount(git_rebase *rebase);
+
+/**
+ * Gets the index of the rebase operation that is currently being applied.
+ * If the first operation has not yet been applied (because you have
+ * called `init` but not yet `next`) then this returns
+ * `GIT_REBASE_NO_OPERATION`.
+ *
+ * @param rebase The in-progress rebase
+ * @return The index of the rebase operation currently being applied.
+ */
+GIT_EXTERN(size_t) git_rebase_operation_current(git_rebase *rebase);
+
+/**
+ * Gets the rebase operation specified by the given index.
+ *
+ * @param rebase The in-progress rebase
+ * @param idx The index of the rebase operation to retrieve
+ * @return The rebase operation or NULL if `idx` was out of bounds
+ */
+GIT_EXTERN(git_rebase_operation *) git_rebase_operation_byindex(
+ git_rebase *rebase,
+ size_t idx);
+
+/**
+ * Performs the next rebase operation and returns the information about it.
+ * If the operation is one that applies a patch (which is any operation except
+ * GIT_REBASE_OPERATION_EXEC) then the patch will be applied and the index and
+ * working directory will be updated with the changes. If there are conflicts,
+ * you will need to address those before committing the changes.
+ *
+ * @param operation Pointer to store the rebase operation that is to be performed next
+ * @param rebase The rebase in progress
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_next(
+ git_rebase_operation **operation,
+ git_rebase *rebase);
+
+/**
+ * Gets the index produced by the last operation, which is the result
+ * of `git_rebase_next` and which will be committed by the next
+ * invocation of `git_rebase_commit`. This is useful for resolving
+ * conflicts in an in-memory rebase before committing them. You must
+ * call `git_index_free` when you are finished with this.
+ *
+ * This is only applicable for in-memory rebases; for rebases within
+ * a working directory, the changes were applied to the repository's
+ * index.
+ *
+ * @param index The result index of the last operation.
+ * @param rebase The in-progress rebase.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_rebase_inmemory_index(
+ git_index **index,
+ git_rebase *rebase);
+
+/**
+ * Commits the current patch. You must have resolved any conflicts that
+ * were introduced during the patch application from the `git_rebase_next`
+ * invocation.
+ *
+ * @param id Pointer in which to store the OID of the newly created commit
+ * @param rebase The rebase that is in-progress
+ * @param author The author of the updated commit, or NULL to keep the
+ * author from the original commit
+ * @param committer The committer of the rebase
+ * @param message_encoding The encoding for the message in the commit,
+ * represented with a standard encoding name. If message is NULL,
+ * this should also be NULL, and the encoding from the original
+ * commit will be maintained. If message is specified, this may be
+ * NULL to indicate that "UTF-8" is to be used.
+ * @param message The message for this commit, or NULL to use the message
+ * from the original commit.
+ * @return Zero on success, GIT_EUNMERGED if there are unmerged changes in
+ * the index, GIT_EAPPLIED if the current commit has already
+ * been applied to the upstream and there is nothing to commit,
+ * -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_commit(
+ git_oid *id,
+ git_rebase *rebase,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message);
+
+/**
+ * Aborts a rebase that is currently in progress, resetting the repository
+ * and working directory to their state before rebase began.
+ *
+ * @param rebase The rebase that is in-progress
+ * @return Zero on success; GIT_ENOTFOUND if a rebase is not in progress,
+ * -1 on other errors.
+ */
+GIT_EXTERN(int) git_rebase_abort(git_rebase *rebase);
+
+/**
+ * Finishes a rebase that is currently in progress once all patches have
+ * been applied.
+ *
+ * @param rebase The rebase that is in-progress
+ * @param signature The identity that is finishing the rebase (optional)
+ * @return Zero on success; -1 on error
+ */
+GIT_EXTERN(int) git_rebase_finish(
+ git_rebase *rebase,
+ const git_signature *signature);
+
+/**
+ * Frees the `git_rebase` object.
+ *
+ * @param rebase The rebase object
+ */
+GIT_EXTERN(void) git_rebase_free(git_rebase *rebase);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/refdb.h b/include/git2/refdb.h
new file mode 100644
index 0000000..c4849ab
--- /dev/null
+++ b/include/git2/refdb.h
@@ -0,0 +1,71 @@
+/*
+ * 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_refdb_h__
+#define INCLUDE_git_refdb_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "refs.h"
+
+/**
+ * @file git2/refdb.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new reference database with no backends.
+ *
+ * Before the Ref DB can be used for read/writing, a custom database
+ * backend must be manually set using `git_refdb_set_backend()`
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_new(git_refdb **out, git_repository *repo);
+
+/**
+ * Create a new reference database and automatically add
+ * the default backends:
+ *
+ * - git_refdb_dir: read and write loose and packed refs
+ * from disk, assuming the repository dir as the folder
+ *
+ * @param out location to store the database pointer, if opened.
+ * Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_open(git_refdb **out, git_repository *repo);
+
+/**
+ * Suggests that the given refdb compress or optimize its references.
+ * This mechanism is implementation specific. For on-disk reference
+ * databases, for example, this may pack all loose references.
+ *
+ * @param refdb The reference database to optimize.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb);
+
+/**
+ * Close an open reference database.
+ *
+ * @param refdb reference database pointer or NULL
+ */
+GIT_EXTERN(void) git_refdb_free(git_refdb *refdb);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/reflog.h b/include/git2/reflog.h
new file mode 100644
index 0000000..ec365c1
--- /dev/null
+++ b/include/git2/reflog.h
@@ -0,0 +1,170 @@
+/*
+ * 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_reflog_h__
+#define INCLUDE_git_reflog_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/reflog.h
+ * @brief Git reflog management routines
+ * @defgroup git_reflog Git reflog management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Read the reflog for the given reference
+ *
+ * If there is no reflog file for the given
+ * reference yet, an empty reflog object will
+ * be returned.
+ *
+ * The reflog must be freed manually by using
+ * git_reflog_free().
+ *
+ * @param out pointer to reflog
+ * @param repo the repository
+ * @param name reference to look up
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_read(git_reflog **out, git_repository *repo, const char *name);
+
+/**
+ * Write an existing in-memory reflog object back to disk
+ * using an atomic file lock.
+ *
+ * @param reflog an existing reflog object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_write(git_reflog *reflog);
+
+/**
+ * Add a new entry to the in-memory reflog.
+ *
+ * `msg` is optional and can be NULL.
+ *
+ * @param reflog an existing reflog object
+ * @param id the OID the reference is now pointing to
+ * @param committer the signature of the committer
+ * @param msg the reflog message
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg);
+
+/**
+ * Rename a reflog
+ *
+ * The reflog to be renamed is expected to already exist
+ *
+ * The new name will be checked for validity.
+ * See `git_reference_create_symbolic()` for rules about valid names.
+ *
+ * @param repo the repository
+ * @param old_name the old name of the reference
+ * @param name the new name of the reference
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reflog_rename(git_repository *repo, const char *old_name, const char *name);
+
+/**
+ * Delete the reflog for the given reference
+ *
+ * @param repo the repository
+ * @param name the reflog to delete
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_delete(git_repository *repo, const char *name);
+
+/**
+ * Get the number of log entries in a reflog
+ *
+ * @param reflog the previously loaded reflog
+ * @return the number of log entries
+ */
+GIT_EXTERN(size_t) git_reflog_entrycount(git_reflog *reflog);
+
+/**
+ * Lookup an entry by its index
+ *
+ * Requesting the reflog entry with an index of 0 (zero) will
+ * return the most recently created entry.
+ *
+ * @param reflog a previously loaded reflog
+ * @param idx the position of the entry to lookup. Should be greater than or
+ * equal to 0 (zero) and less than `git_reflog_entrycount()`.
+ * @return the entry; NULL if not found
+ */
+GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(const git_reflog *reflog, size_t idx);
+
+/**
+ * Remove an entry from the reflog by its index
+ *
+ * To ensure there's no gap in the log history, set `rewrite_previous_entry`
+ * param value to 1. When deleting entry `n`, member old_oid of entry `n-1`
+ * (if any) will be updated with the value of member new_oid of entry `n+1`.
+ *
+ * @param reflog a previously loaded reflog.
+ *
+ * @param idx the position of the entry to remove. Should be greater than or
+ * equal to 0 (zero) and less than `git_reflog_entrycount()`.
+ *
+ * @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if the entry doesn't exist
+ * or an error code.
+ */
+GIT_EXTERN(int) git_reflog_drop(
+ git_reflog *reflog,
+ size_t idx,
+ int rewrite_previous_entry);
+
+/**
+ * Get the old oid
+ *
+ * @param entry a reflog entry
+ * @return the old oid
+ */
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry);
+
+/**
+ * Get the new oid
+ *
+ * @param entry a reflog entry
+ * @return the new oid at this time
+ */
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry);
+
+/**
+ * Get the committer of this entry
+ *
+ * @param entry a reflog entry
+ * @return the committer
+ */
+GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
+
+/**
+ * Get the log message
+ *
+ * @param entry a reflog entry
+ * @return the log msg
+ */
+GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry);
+
+/**
+ * Free the reflog
+ *
+ * @param reflog reflog to free
+ */
+GIT_EXTERN(void) git_reflog_free(git_reflog *reflog);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/refs.h b/include/git2/refs.h
new file mode 100644
index 0000000..06f8bb9
--- /dev/null
+++ b/include/git2/refs.h
@@ -0,0 +1,771 @@
+/*
+ * 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_refs_h__
+#define INCLUDE_git_refs_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "strarray.h"
+
+/**
+ * @file git2/refs.h
+ * @brief Git reference management routines
+ * @defgroup git_reference Git reference management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a reference by name in a repository.
+ *
+ * The returned reference must be freed by the user.
+ *
+ * The name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param out pointer to the looked-up reference
+ * @param repo the repository to look up the reference
+ * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name);
+
+/**
+ * Lookup a reference by name and resolve immediately to OID.
+ *
+ * This function provides a quick way to resolve a reference name straight
+ * through to the object id that it refers to. This avoids having to
+ * allocate or free any `git_reference` objects for simple situations.
+ *
+ * The name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param out Pointer to oid to be filled in
+ * @param repo The repository in which to look up the reference
+ * @param name The long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_reference_name_to_id(
+ git_oid *out, git_repository *repo, const char *name);
+
+/**
+ * Lookup a reference by DWIMing its short name
+ *
+ * Apply the git precedence rules to the given shorthand to determine
+ * which reference the user is referring to.
+ *
+ * @param out pointer in which to store the reference
+ * @param repo the repository in which to look
+ * @param shorthand the short name for the reference
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, const char *shorthand);
+
+/**
+ * Conditionally create a new symbolic reference.
+ *
+ * A symbolic reference is a reference name that refers to another
+ * reference name. If the other name moves, the symbolic name will move,
+ * too. As a simple example, the "HEAD" reference might refer to
+ * "refs/heads/master" while on the "master" branch of a repository.
+ *
+ * The symbolic reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_value`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * If `current_value` is all zeros, this function will return GIT_EMODIFIED
+ * if the ref already exists.
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param target The target of the reference
+ * @param force Overwrite existing references
+ * @param current_value The expected value of the reference when updating
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC, GIT_EMODIFIED or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_create_matching(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *current_value, const char *log_message);
+
+/**
+ * Create a new symbolic reference.
+ *
+ * A symbolic reference is a reference name that refers to another
+ * reference name. If the other name moves, the symbolic name will move,
+ * too. As a simple example, the "HEAD" reference might refer to
+ * "refs/heads/master" while on the "master" branch of a repository.
+ *
+ * The symbolic reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param target The target of the reference
+ * @param force Overwrite existing references
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *log_message);
+
+/**
+ * Create a new direct reference.
+ *
+ * A direct reference (also called an object id reference) refers directly
+ * to a specific object id (a.k.a. OID or SHA) in the repository. The id
+ * permanently refers to the object (although the reference itself can be
+ * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"
+ * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
+ *
+ * The direct reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param id The object id pointed to by the reference.
+ * @param force Overwrite existing references
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const char *log_message);
+
+/**
+ * Conditionally create new direct reference
+ *
+ * A direct reference (also called an object id reference) refers directly
+ * to a specific object id (a.k.a. OID or SHA) in the repository. The id
+ * permanently refers to the object (although the reference itself can be
+ * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"
+ * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
+ *
+ * The direct reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_id`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param id The object id pointed to by the reference.
+ * @param force Overwrite existing references
+ * @param current_id The expected value of the reference at the time of update
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_create_matching(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_oid *current_id, const char *log_message);
+
+/**
+ * Get the OID pointed to by a direct reference.
+ *
+ * Only available if the reference is direct (i.e. an object id reference,
+ * not a symbolic one).
+ *
+ * To find the OID of a symbolic ref, call `git_reference_resolve()` and
+ * then this function (or maybe use `git_reference_name_to_id()` to
+ * directly resolve a reference name all the way through to an OID).
+ *
+ * @param ref The reference
+ * @return a pointer to the oid if available, NULL otherwise
+ */
+GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref);
+
+/**
+ * Return the peeled OID target of this reference.
+ *
+ * This peeled OID only applies to direct references that point to
+ * a hard Tag object: it is the result of peeling such Tag.
+ *
+ * @param ref The reference
+ * @return a pointer to the oid if available, NULL otherwise
+ */
+GIT_EXTERN(const git_oid *) git_reference_target_peel(const git_reference *ref);
+
+/**
+ * Get full name to the reference pointed to by a symbolic reference.
+ *
+ * Only available if the reference is symbolic.
+ *
+ * @param ref The reference
+ * @return a pointer to the name if available, NULL otherwise
+ */
+GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref);
+
+/**
+ * Get the type of a reference.
+ *
+ * Either direct (GIT_REFERENCE_DIRECT) or symbolic (GIT_REFERENCE_SYMBOLIC)
+ *
+ * @param ref The reference
+ * @return the type
+ */
+GIT_EXTERN(git_reference_t) git_reference_type(const git_reference *ref);
+
+/**
+ * Get the full name of a reference.
+ *
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param ref The reference
+ * @return the full name for the ref
+ */
+GIT_EXTERN(const char *) git_reference_name(const git_reference *ref);
+
+/**
+ * Resolve a symbolic reference to a direct reference.
+ *
+ * This method iteratively peels a symbolic reference until it resolves to
+ * a direct reference to an OID.
+ *
+ * The peeled reference is returned in the `resolved_ref` argument, and
+ * must be freed manually once it's no longer needed.
+ *
+ * If a direct reference is passed as an argument, a copy of that
+ * reference is returned. This copy must be manually freed too.
+ *
+ * @param out Pointer to the peeled reference
+ * @param ref The reference
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref);
+
+/**
+ * Get the repository where a reference resides.
+ *
+ * @param ref The reference
+ * @return a pointer to the repo
+ */
+GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
+
+/**
+ * Create a new reference with the same name as the given reference but a
+ * different symbolic target. The reference must be a symbolic reference,
+ * otherwise this will fail.
+ *
+ * The new reference will be written to disk, overwriting the given reference.
+ *
+ * The target name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param ref The reference
+ * @param target The new target for the reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const char *target,
+ const char *log_message);
+
+/**
+ * Conditionally create a new reference with the same name as the given reference but a
+ * different OID target. The reference must be a direct reference, otherwise
+ * this will fail.
+ *
+ * The new reference will be written to disk, overwriting the given reference.
+ *
+ * @param out Pointer to the newly created reference
+ * @param ref The reference
+ * @param id The new target OID for the reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed since it was read, or an error code
+ */
+GIT_EXTERN(int) git_reference_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const git_oid *id,
+ const char *log_message);
+
+/**
+ * Rename an existing reference.
+ *
+ * This method works for both direct and symbolic references.
+ *
+ * The new name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * If the `force` flag is not enabled, and there's already
+ * a reference with the given name, the renaming will fail.
+ *
+ * IMPORTANT:
+ * The user needs to write a proper reflog entry if the
+ * reflog is enabled for the repository. We only rename
+ * the reflog if it exists.
+ *
+ * @param ref The reference to rename
+ * @param new_name The new name for the reference
+ * @param force Overwrite an existing reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ *
+ */
+GIT_EXTERN(int) git_reference_rename(
+ git_reference **new_ref,
+ git_reference *ref,
+ const char *new_name,
+ int force,
+ const char *log_message);
+
+/**
+ * Delete an existing reference.
+ *
+ * This method works for both direct and symbolic references. The reference
+ * will be immediately removed on disk but the memory will not be freed.
+ * Callers must call `git_reference_free`.
+ *
+ * This function will return an error if the reference has changed
+ * from the time it was looked up.
+ *
+ * @param ref The reference to remove
+ * @return 0, GIT_EMODIFIED or an error code
+ */
+GIT_EXTERN(int) git_reference_delete(git_reference *ref);
+
+/**
+ * Delete an existing reference by name
+ *
+ * This method removes the named reference from the repository without
+ * looking at its old value.
+ *
+ * @param name The reference to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_remove(git_repository *repo, const char *name);
+
+/**
+ * Fill a list with all the references that can be found in a repository.
+ *
+ * The string array will be filled with the names of all references; these
+ * values are owned by the user and should be free'd manually when no
+ * longer needed, using `git_strarray_free()`.
+ *
+ * @param array Pointer to a git_strarray structure where
+ * the reference names will be stored
+ * @param repo Repository where to find the refs
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo);
+
+/**
+ * Callback used to iterate over references
+ *
+ * @see git_reference_foreach
+ *
+ * @param reference The reference object
+ * @param payload Payload passed to git_reference_foreach
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(git_reference_foreach_cb)(git_reference *reference, void *payload);
+
+/**
+ * Callback used to iterate over reference names
+ *
+ * @see git_reference_foreach_name
+ *
+ * @param name The reference name
+ * @param payload Payload passed to git_reference_foreach_name
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(git_reference_foreach_name_cb)(const char *name, void *payload);
+
+/**
+ * Perform a callback on each reference in the repository.
+ *
+ * The `callback` function will be called for each reference in the
+ * repository, receiving the reference object and the `payload` value
+ * passed to this method. Returning a non-zero value from the callback
+ * will terminate the iteration.
+ *
+ * Note that the callback function is responsible to call `git_reference_free`
+ * on each reference passed to it.
+ *
+ * @param repo Repository where to find the refs
+ * @param callback Function which will be called for every listed ref
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach(
+ git_repository *repo,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+/**
+ * Perform a callback on the fully-qualified name of each reference.
+ *
+ * The `callback` function will be called for each reference in the
+ * repository, receiving the name of the reference and the `payload` value
+ * passed to this method. Returning a non-zero value from the callback
+ * will terminate the iteration.
+ *
+ * @param repo Repository where to find the refs
+ * @param callback Function which will be called for every listed ref name
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach_name(
+ git_repository *repo,
+ git_reference_foreach_name_cb callback,
+ void *payload);
+
+/**
+ * Create a copy of an existing reference.
+ *
+ * Call `git_reference_free` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_dup(git_reference **dest, git_reference *source);
+
+/**
+ * Free the given reference.
+ *
+ * @param ref git_reference
+ */
+GIT_EXTERN(void) git_reference_free(git_reference *ref);
+
+/**
+ * Compare two references.
+ *
+ * @param ref1 The first git_reference
+ * @param ref2 The second git_reference
+ * @return 0 if the same, else a stable but meaningless ordering.
+ */
+GIT_EXTERN(int) git_reference_cmp(
+ const git_reference *ref1,
+ const git_reference *ref2);
+
+/**
+ * Create an iterator for the repo's references
+ *
+ * @param out pointer in which to store the iterator
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_iterator_new(
+ git_reference_iterator **out,
+ git_repository *repo);
+
+/**
+ * Create an iterator for the repo's references that match the
+ * specified glob
+ *
+ * @param out pointer in which to store the iterator
+ * @param repo the repository
+ * @param glob the glob to match against the reference names
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_iterator_glob_new(
+ git_reference_iterator **out,
+ git_repository *repo,
+ const char *glob);
+
+/**
+ * Get the next reference
+ *
+ * @param out pointer in which to store the reference
+ * @param iter the iterator
+ * @return 0, GIT_ITEROVER if there are no more; or an error code
+ */
+GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter);
+
+/**
+ * Get the next reference's name
+ *
+ * This function is provided for convenience in case only the names
+ * are interesting as it avoids the allocation of the `git_reference`
+ * object which `git_reference_next()` needs.
+ *
+ * @param out pointer in which to store the string
+ * @param iter the iterator
+ * @return 0, GIT_ITEROVER if there are no more; or an error code
+ */
+GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter);
+
+/**
+ * Free the iterator and its associated resources
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter);
+
+/**
+ * Perform a callback on each reference in the repository whose name
+ * matches the given pattern.
+ *
+ * This function acts like `git_reference_foreach()` with an additional
+ * pattern match being applied to the reference name before issuing the
+ * callback function. See that function for more information.
+ *
+ * The pattern is matched using fnmatch or "glob" style where a '*' matches
+ * any sequence of letters, a '?' matches any letter, and square brackets
+ * can be used to define character ranges (such as "[0-9]" for digits).
+ *
+ * @param repo Repository where to find the refs
+ * @param glob Pattern to match (fnmatch-style) against reference name.
+ * @param callback Function which will be called for every listed ref
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach_glob(
+ git_repository *repo,
+ const char *glob,
+ git_reference_foreach_name_cb callback,
+ void *payload);
+
+/**
+ * Check if a reflog exists for the specified reference.
+ *
+ * @param repo the repository
+ * @param refname the reference's name
+ * @return 0 when no reflog can be found, 1 when it exists;
+ * otherwise an error code.
+ */
+GIT_EXTERN(int) git_reference_has_log(git_repository *repo, const char *refname);
+
+/**
+ * Ensure there is a reflog for a particular reference.
+ *
+ * Make sure that successive updates to the reference will append to
+ * its log.
+ *
+ * @param repo the repository
+ * @param refname the reference's name
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_reference_ensure_log(git_repository *repo, const char *refname);
+
+/**
+ * Check if a reference is a local branch.
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/heads
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_branch(const git_reference *ref);
+
+/**
+ * Check if a reference is a remote tracking branch
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/remotes
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_remote(const git_reference *ref);
+
+/**
+ * Check if a reference is a tag
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/tags
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_tag(const git_reference *ref);
+
+/**
+ * Check if a reference is a note
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/notes
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_note(const git_reference *ref);
+
+/**
+ * Normalization options for reference lookup
+ */
+typedef enum {
+ /**
+ * No particular normalization.
+ */
+ GIT_REFERENCE_FORMAT_NORMAL = 0u,
+
+ /**
+ * Control whether one-level refnames are accepted
+ * (i.e., refnames that do not contain multiple /-separated
+ * components). Those are expected to be written only using
+ * uppercase letters and underscore (FETCH_HEAD, ...)
+ */
+ GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL = (1u << 0),
+
+ /**
+ * Interpret the provided name as a reference pattern for a
+ * refspec (as used with remote repositories). If this option
+ * is enabled, the name is allowed to contain a single * (<star>)
+ * in place of a one full pathname component
+ * (e.g., foo/<star>/bar but not foo/bar<star>).
+ */
+ GIT_REFERENCE_FORMAT_REFSPEC_PATTERN = (1u << 1),
+
+ /**
+ * Interpret the name as part of a refspec in shorthand form
+ * so the `ONELEVEL` naming rules aren't enforced and 'master'
+ * becomes a valid name.
+ */
+ GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND = (1u << 2)
+} git_reference_format_t;
+
+/**
+ * Normalize reference name and check validity.
+ *
+ * This will normalize the reference name by removing any leading slash
+ * '/' characters and collapsing runs of adjacent slashes between name
+ * components into a single slash.
+ *
+ * Once normalized, if the reference name is valid, it will be returned in
+ * the user allocated buffer.
+ *
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param buffer_out User allocated buffer to store normalized name
+ * @param buffer_size Size of buffer_out
+ * @param name Reference name to be checked.
+ * @param flags Flags to constrain name validation rules - see the
+ * GIT_REFERENCE_FORMAT constants above.
+ * @return 0 on success, GIT_EBUFS if buffer is too small, GIT_EINVALIDSPEC
+ * or an error code.
+ */
+GIT_EXTERN(int) git_reference_normalize_name(
+ char *buffer_out,
+ size_t buffer_size,
+ const char *name,
+ unsigned int flags);
+
+/**
+ * Recursively peel reference until object of the specified type is found.
+ *
+ * The retrieved `peeled` object is owned by the repository
+ * and should be closed with the `git_object_free` method.
+ *
+ * If you pass `GIT_OBJECT_ANY` as the target type, then the object
+ * will be peeled until a non-tag object is met.
+ *
+ * @param out Pointer to the peeled git_object
+ * @param ref The reference to be processed
+ * @param type The type of the requested object (GIT_OBJECT_COMMIT,
+ * GIT_OBJECT_TAG, GIT_OBJECT_TREE, GIT_OBJECT_BLOB or GIT_OBJECT_ANY).
+ * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
+ */
+GIT_EXTERN(int) git_reference_peel(
+ git_object **out,
+ const git_reference *ref,
+ git_object_t type);
+
+/**
+ * Ensure the reference name is well-formed.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * @param valid output pointer to set with validity of given reference name
+ * @param refname name to be checked.
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_reference_name_is_valid(int *valid, const char *refname);
+
+/**
+ * Get the reference's short name
+ *
+ * This will transform the reference name into a name "human-readable"
+ * version. If no shortname is appropriate, it will return the full
+ * name.
+ *
+ * The memory is owned by the reference and must not be freed.
+ *
+ * @param ref a reference
+ * @return the human-readable version of the name
+ */
+GIT_EXTERN(const char *) git_reference_shorthand(const git_reference *ref);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/refspec.h b/include/git2/refspec.h
new file mode 100644
index 0000000..eaf7747
--- /dev/null
+++ b/include/git2/refspec.h
@@ -0,0 +1,121 @@
+/*
+ * 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_refspec_h__
+#define INCLUDE_git_refspec_h__
+
+#include "common.h"
+#include "types.h"
+#include "net.h"
+#include "buffer.h"
+
+/**
+ * @file git2/refspec.h
+ * @brief Git refspec attributes
+ * @defgroup git_refspec Git refspec attributes
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Parse a given refspec string
+ *
+ * @param refspec a pointer to hold the refspec handle
+ * @param input the refspec string
+ * @param is_fetch is this a refspec for a fetch
+ * @return 0 if the refspec string could be parsed, -1 otherwise
+ */
+GIT_EXTERN(int) git_refspec_parse(git_refspec **refspec, const char *input, int is_fetch);
+
+/**
+ * Free a refspec object which has been created by git_refspec_parse
+ *
+ * @param refspec the refspec object
+ */
+GIT_EXTERN(void) git_refspec_free(git_refspec *refspec);
+
+/**
+ * Get the source specifier
+ *
+ * @param refspec the refspec
+ * @return the refspec's source specifier
+ */
+GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec);
+
+/**
+ * Get the destination specifier
+ *
+ * @param refspec the refspec
+ * @return the refspec's destination specifier
+ */
+GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
+
+/**
+ * Get the refspec's string
+ *
+ * @param refspec the refspec
+ * @returns the refspec's original string
+ */
+GIT_EXTERN(const char *) git_refspec_string(const git_refspec *refspec);
+
+/**
+ * Get the force update setting
+ *
+ * @param refspec the refspec
+ * @return 1 if force update has been set, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec);
+
+/**
+ * Get the refspec's direction.
+ *
+ * @param spec refspec
+ * @return GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ */
+GIT_EXTERN(git_direction) git_refspec_direction(const git_refspec *spec);
+
+/**
+ * Check if a refspec's source descriptor matches a reference
+ *
+ * @param refspec the refspec
+ * @param refname the name of the reference to check
+ * @return 1 if the refspec matches, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname);
+
+/**
+ * Check if a refspec's destination descriptor matches a reference
+ *
+ * @param refspec the refspec
+ * @param refname the name of the reference to check
+ * @return 1 if the refspec matches, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_dst_matches(const git_refspec *refspec, const char *refname);
+
+/**
+ * Transform a reference to its target following the refspec's rules
+ *
+ * @param out where to store the target name
+ * @param spec the refspec
+ * @param name the name of the reference to transform
+ * @return 0, GIT_EBUFS or another error
+ */
+GIT_EXTERN(int) git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name);
+
+/**
+ * Transform a target reference to its source reference following the refspec's rules
+ *
+ * @param out where to store the source reference name
+ * @param spec the refspec
+ * @param name the name of the reference to transform
+ * @return 0, GIT_EBUFS or another error
+ */
+GIT_EXTERN(int) git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/remote.h b/include/git2/remote.h
new file mode 100644
index 0000000..e9065b2
--- /dev/null
+++ b/include/git2/remote.h
@@ -0,0 +1,1173 @@
+/*
+ * 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_remote_h__
+#define INCLUDE_git_remote_h__
+
+#include "common.h"
+#include "repository.h"
+#include "refspec.h"
+#include "net.h"
+#include "indexer.h"
+#include "strarray.h"
+#include "transport.h"
+#include "pack.h"
+#include "proxy.h"
+
+/**
+ * @file git2/remote.h
+ * @brief Git remote management functions
+ * @defgroup git_remote remote management functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Add a remote with the default fetch refspec to the repository's configuration.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create(
+ git_remote **out,
+ git_repository *repo,
+ const char *name,
+ const char *url);
+
+/**
+ * Remote redirection settings; whether redirects to another host
+ * are permitted. By default, git will follow a redirect on the
+ * initial request (`/info/refs`), but not subsequent requests.
+ */
+typedef enum {
+ /**
+ * Do not follow any off-site redirects at any stage of
+ * the fetch or push.
+ */
+ GIT_REMOTE_REDIRECT_NONE = (1 << 0),
+
+ /**
+ * Allow off-site redirects only upon the initial request.
+ * This is the default.
+ */
+ GIT_REMOTE_REDIRECT_INITIAL = (1 << 1),
+
+ /**
+ * Allow redirects at any stage in the fetch or push.
+ */
+ GIT_REMOTE_REDIRECT_ALL = (1 << 2)
+} git_remote_redirect_t;
+
+/**
+ * Remote creation options flags
+ */
+typedef enum {
+ /** Ignore the repository apply.insteadOf configuration */
+ GIT_REMOTE_CREATE_SKIP_INSTEADOF = (1 << 0),
+
+ /** Don't build a fetchspec from the name if none is set */
+ GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1)
+} git_remote_create_flags;
+
+/**
+ * Remote creation options structure
+ *
+ * Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_remote_create_options_init`.
+ *
+ */
+typedef struct git_remote_create_options {
+ unsigned int version;
+
+ /**
+ * The repository that should own the remote.
+ * Setting this to NULL results in a detached remote.
+ */
+ git_repository *repository;
+
+ /**
+ * The remote's name.
+ * Setting this to NULL results in an in-memory/anonymous remote.
+ */
+ const char *name;
+
+ /** The fetchspec the remote should use. */
+ const char *fetchspec;
+
+ /** Additional flags for the remote. See git_remote_create_flags. */
+ unsigned int flags;
+} git_remote_create_options;
+
+#define GIT_REMOTE_CREATE_OPTIONS_VERSION 1
+#define GIT_REMOTE_CREATE_OPTIONS_INIT {GIT_REMOTE_CREATE_OPTIONS_VERSION}
+
+/**
+ * Initialize git_remote_create_options structure
+ *
+ * Initializes a `git_remote_create_options` with default values. Equivalent to
+ * creating an instance with `GIT_REMOTE_CREATE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_remote_create_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REMOTE_CREATE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_create_options_init(
+ git_remote_create_options *opts,
+ unsigned int version);
+
+/**
+ * Create a remote, with options.
+ *
+ * This function allows more fine-grained control over the remote creation.
+ *
+ * Passing NULL as the opts argument will result in a detached remote.
+ *
+ * @param out the resulting remote
+ * @param url the remote's url
+ * @param opts the remote creation options
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create_with_opts(
+ git_remote **out,
+ const char *url,
+ const git_remote_create_options *opts);
+
+/**
+ * Add a remote with the provided fetch refspec (or default if NULL) to the repository's
+ * configuration.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @param fetch the remote fetch value
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create_with_fetchspec(
+ git_remote **out,
+ git_repository *repo,
+ const char *name,
+ const char *url,
+ const char *fetch);
+
+/**
+ * Create an anonymous remote
+ *
+ * Create a remote with the given url in-memory. You can use this when
+ * you have a URL instead of a remote's name.
+ *
+ * @param out pointer to the new remote objects
+ * @param repo the associated repository
+ * @param url the remote repository's URL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_create_anonymous(
+ git_remote **out,
+ git_repository *repo,
+ const char *url);
+
+/**
+ * Create a remote without a connected local repo
+ *
+ * Create a remote with the given url in-memory. You can use this when
+ * you have a URL instead of a remote's name.
+ *
+ * Contrasted with git_remote_create_anonymous, a detached remote
+ * will not consider any repo configuration values (such as insteadof url
+ * substitutions).
+ *
+ * @param out pointer to the new remote objects
+ * @param url the remote repository's URL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_create_detached(
+ git_remote **out,
+ const char *url);
+
+/**
+ * Get the information for a particular remote
+ *
+ * The name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param out pointer to the new remote object
+ * @param repo the associated repository
+ * @param name the remote's name
+ * @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_remote_lookup(git_remote **out, git_repository *repo, const char *name);
+
+/**
+ * Create a copy of an existing remote. All internal strings are also
+ * duplicated. Callbacks are not duplicated.
+ *
+ * Call `git_remote_free` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_dup(git_remote **dest, git_remote *source);
+
+/**
+ * Get the remote's repository
+ *
+ * @param remote the remote
+ * @return a pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_remote_owner(const git_remote *remote);
+
+/**
+ * Get the remote's name
+ *
+ * @param remote the remote
+ * @return a pointer to the name or NULL for in-memory remotes
+ */
+GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
+
+/**
+ * Get the remote's url
+ *
+ * If url.*.insteadOf has been configured for this URL, it will
+ * return the modified URL. If `git_remote_set_instance_pushurl`
+ * has been called for this remote, then that URL will be returned.
+ *
+ * @param remote the remote
+ * @return a pointer to the url
+ */
+GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
+
+/**
+ * Get the remote's url for pushing.
+ *
+ * If url.*.pushInsteadOf has been configured for this URL, it
+ * will return the modified URL. If `git_remote_set_instance_pushurl`
+ * has been called for this remote, then that URL will be returned.
+ *
+ * @param remote the remote
+ * @return a pointer to the url or NULL if no special url for pushing is set
+ */
+GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote);
+
+/**
+ * Set the remote's url in the configuration
+ *
+ * Remote objects already in memory will not be affected. This assumes
+ * the common case of a single-url remote and will otherwise return an error.
+ *
+ * @param repo the repository in which to perform the change
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char *url);
+
+/**
+ * Set the remote's url for pushing in the configuration.
+ *
+ * Remote objects already in memory will not be affected. This assumes
+ * the common case of a single-url remote and will otherwise return an error.
+ *
+ *
+ * @param repo the repository in which to perform the change
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url);
+
+/**
+ * Set the url for this particular url instance. The URL in the
+ * configuration will be ignored, and will not be changed.
+ *
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_instance_url(git_remote *remote, const char *url);
+
+/**
+ * Set the push url for this particular url instance. The URL in the
+ * configuration will be ignored, and will not be changed.
+ *
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_instance_pushurl(git_remote *remote, const char *url);
+
+/**
+ * Add a fetch refspec to the remote's configuration
+ *
+ * Add the given refspec to the fetch list in the configuration. No
+ * loaded remote instances will be affected.
+ *
+ * @param repo the repository in which to change the configuration
+ * @param remote the name of the remote to change
+ * @param refspec the new fetch refspec
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid or an error value
+ */
+GIT_EXTERN(int) git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec);
+
+/**
+ * Get the remote's list of fetch refspecs
+ *
+ * The memory is owned by the user and should be freed with
+ * `git_strarray_free`.
+ *
+ * @param array pointer to the array in which to store the strings
+ * @param remote the remote to query
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote);
+
+/**
+ * Add a push refspec to the remote's configuration
+ *
+ * Add the given refspec to the push list in the configuration. No
+ * loaded remote instances will be affected.
+ *
+ * @param repo the repository in which to change the configuration
+ * @param remote the name of the remote to change
+ * @param refspec the new push refspec
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid or an error value
+ */
+GIT_EXTERN(int) git_remote_add_push(git_repository *repo, const char *remote, const char *refspec);
+
+/**
+ * Get the remote's list of push refspecs
+ *
+ * The memory is owned by the user and should be freed with
+ * `git_strarray_free`.
+ *
+ * @param array pointer to the array in which to store the strings
+ * @param remote the remote to query
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote);
+
+/**
+ * Get the number of refspecs for a remote
+ *
+ * @param remote the remote
+ * @return the amount of refspecs configured in this remote
+ */
+GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote);
+
+/**
+ * Get a refspec from the remote
+ *
+ * @param remote the remote to query
+ * @param n the refspec to get
+ * @return the nth refspec
+ */
+GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, size_t n);
+
+/**
+ * Get the remote repository's reference advertisement list
+ *
+ * Get the list of references with which the server responds to a new
+ * connection.
+ *
+ * The remote (or more exactly its transport) must have connected to
+ * the remote repository. This list is available as soon as the
+ * connection to the remote is initiated and it remains available
+ * after disconnecting.
+ *
+ * The memory belongs to the remote. The pointer will be valid as long
+ * as a new connection is not initiated, but it is recommended that
+ * you make a copy in order to make use of the data.
+ *
+ * @param out pointer to the array
+ * @param size the number of remote heads
+ * @param remote the remote
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote);
+
+/**
+ * Check whether the remote is connected
+ *
+ * Check whether the remote's underlying transport is connected to the
+ * remote host.
+ *
+ * @param remote the remote
+ * @return 1 if it's connected, 0 otherwise.
+ */
+GIT_EXTERN(int) git_remote_connected(const git_remote *remote);
+
+/**
+ * Cancel the operation
+ *
+ * At certain points in its operation, the network code checks whether
+ * the operation has been cancelled and if so stops the operation.
+ *
+ * @param remote the remote
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_remote_stop(git_remote *remote);
+
+/**
+ * Disconnect from the remote
+ *
+ * Close the connection to the remote.
+ *
+ * @param remote the remote to disconnect from
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_remote_disconnect(git_remote *remote);
+
+/**
+ * Free the memory associated with a remote
+ *
+ * This also disconnects from the remote, if the connection
+ * has not been closed yet (using git_remote_disconnect).
+ *
+ * @param remote the remote to free
+ */
+GIT_EXTERN(void) git_remote_free(git_remote *remote);
+
+/**
+ * Get a list of the configured remotes for a repo
+ *
+ * The string array must be freed by the user.
+ *
+ * @param out a string array which receives the names of the remotes
+ * @param repo the repository to query
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
+
+/**
+ * Argument to the completion callback which tells it which operation
+ * finished.
+ */
+typedef enum git_remote_completion_t {
+ GIT_REMOTE_COMPLETION_DOWNLOAD,
+ GIT_REMOTE_COMPLETION_INDEXING,
+ GIT_REMOTE_COMPLETION_ERROR
+} git_remote_completion_t;
+
+/** Push network progress notification function */
+typedef int GIT_CALLBACK(git_push_transfer_progress_cb)(
+ unsigned int current,
+ unsigned int total,
+ size_t bytes,
+ void *payload);
+
+/**
+ * Represents an update which will be performed on the remote during push
+ */
+typedef struct {
+ /**
+ * The source name of the reference
+ */
+ char *src_refname;
+ /**
+ * The name of the reference to update on the server
+ */
+ char *dst_refname;
+ /**
+ * The current target of the reference
+ */
+ git_oid src;
+ /**
+ * The new target for the reference
+ */
+ git_oid dst;
+} git_push_update;
+
+/**
+ * Callback used to inform of upcoming updates.
+ *
+ * @param updates an array containing the updates which will be sent
+ * as commands to the destination.
+ * @param len number of elements in `updates`
+ * @param payload Payload provided by the caller
+ */
+typedef int GIT_CALLBACK(git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
+
+/**
+ * Callback used to inform of the update status from the remote.
+ *
+ * Called for each updated reference on push. If `status` is
+ * not `NULL`, the update was rejected by the remote server
+ * and `status` contains the reason given.
+ *
+ * @param refname refname specifying to the remote ref
+ * @param status status message sent from the remote
+ * @param data data provided by the caller
+ * @return 0 on success, otherwise an error
+ */
+typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, const char *status, void *data);
+
+#ifndef GIT_DEPRECATE_HARD
+/**
+ * Callback to resolve URLs before connecting to remote
+ *
+ * If you return GIT_PASSTHROUGH, you don't need to write anything to
+ * url_resolved.
+ *
+ * @param url_resolved The buffer to write the resolved URL to
+ * @param url The URL to resolve
+ * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ * @param payload Payload provided by the caller
+ * @return 0 on success, GIT_PASSTHROUGH or an error
+ * @deprecated Use `git_remote_set_instance_url`
+ */
+typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload);
+#endif
+
+/**
+ * Callback invoked immediately before we attempt to connect to the
+ * given url. Callers may change the URL before the connection by
+ * calling `git_remote_set_instance_url` in the callback.
+ *
+ * @param remote The remote to be connected
+ * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ * @param payload Payload provided by the caller
+ * @return 0 on success, or an error
+ */
+typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload);
+
+/**
+ * The callback settings structure
+ *
+ * Set the callbacks to be called by the remote when informing the user
+ * about the progress of the network operations.
+ */
+struct git_remote_callbacks {
+ unsigned int version; /**< The version */
+
+ /**
+ * Textual progress from the remote. Text send over the
+ * progress side-band will be passed to this function (this is
+ * the 'counting objects' output).
+ */
+ git_transport_message_cb sideband_progress;
+
+ /**
+ * Completion is called when different parts of the download
+ * process are done (currently unused).
+ */
+ int GIT_CALLBACK(completion)(git_remote_completion_t type, void *data);
+
+ /**
+ * This will be called if the remote host requires
+ * authentication in order to connect to it.
+ *
+ * Returning GIT_PASSTHROUGH will make libgit2 behave as
+ * though this field isn't set.
+ */
+ git_credential_acquire_cb credentials;
+
+ /**
+ * If cert verification fails, this will be called to let the
+ * user make the final decision of whether to allow the
+ * connection to proceed. Returns 0 to allow the connection
+ * or a negative value to indicate an error.
+ */
+ git_transport_certificate_check_cb certificate_check;
+
+ /**
+ * During the download of new data, this will be regularly
+ * called with the current count of progress done by the
+ * indexer.
+ */
+ git_indexer_progress_cb transfer_progress;
+
+ /**
+ * Each time a reference is updated locally, this function
+ * will be called with information about it.
+ */
+ int GIT_CALLBACK(update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
+
+ /**
+ * Function to call with progress information during pack
+ * building. Be aware that this is called inline with pack
+ * building operations, so performance may be affected.
+ */
+ git_packbuilder_progress pack_progress;
+
+ /**
+ * Function to call with progress information during the
+ * upload portion of a push. Be aware that this is called
+ * inline with pack building operations, so performance may be
+ * affected.
+ */
+ git_push_transfer_progress_cb push_transfer_progress;
+
+ /**
+ * See documentation of git_push_update_reference_cb
+ */
+ git_push_update_reference_cb push_update_reference;
+
+ /**
+ * Called once between the negotiation step and the upload. It
+ * provides information about what updates will be performed.
+ */
+ git_push_negotiation push_negotiation;
+
+ /**
+ * Create the transport to use for this operation. Leave NULL
+ * to auto-detect.
+ */
+ git_transport_cb transport;
+
+ /**
+ * Callback when the remote is ready to connect.
+ */
+ git_remote_ready_cb remote_ready;
+
+ /**
+ * This will be passed to each of the callbacks in this struct
+ * as the last parameter.
+ */
+ void *payload;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ /**
+ * Resolve URL before connecting to remote.
+ * The returned URL will be used to connect to the remote instead.
+ *
+ * This callback is deprecated; users should use
+ * git_remote_ready_cb and configure the instance URL instead.
+ */
+ git_url_resolve_cb resolve_url;
+#endif
+};
+
+#define GIT_REMOTE_CALLBACKS_VERSION 1
+#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
+
+/**
+ * Initializes a `git_remote_callbacks` with default values. Equivalent to
+ * creating an instance with GIT_REMOTE_CALLBACKS_INIT.
+ *
+ * @param opts the `git_remote_callbacks` struct to initialize
+ * @param version Version of struct; pass `GIT_REMOTE_CALLBACKS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_init_callbacks(
+ git_remote_callbacks *opts,
+ unsigned int version);
+
+/** Acceptable prune settings when fetching */
+typedef enum {
+ /**
+ * Use the setting from the configuration
+ */
+ GIT_FETCH_PRUNE_UNSPECIFIED,
+ /**
+ * Force pruning on
+ */
+ GIT_FETCH_PRUNE,
+ /**
+ * Force pruning off
+ */
+ GIT_FETCH_NO_PRUNE
+} git_fetch_prune_t;
+
+/**
+ * Automatic tag following option
+ *
+ * Lets us select the --tags option to use.
+ */
+typedef enum {
+ /**
+ * Use the setting from the configuration.
+ */
+ GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED = 0,
+ /**
+ * Ask the server for tags pointing to objects we're already
+ * downloading.
+ */
+ GIT_REMOTE_DOWNLOAD_TAGS_AUTO,
+ /**
+ * Don't ask for any tags beyond the refspecs.
+ */
+ GIT_REMOTE_DOWNLOAD_TAGS_NONE,
+ /**
+ * Ask for the all the tags.
+ */
+ GIT_REMOTE_DOWNLOAD_TAGS_ALL
+} git_remote_autotag_option_t;
+
+/** Constants for fetch depth (shallowness of fetch). */
+typedef enum {
+ /** The fetch is "full" (not shallow). This is the default. */
+ GIT_FETCH_DEPTH_FULL = 0,
+
+ /** The fetch should "unshallow" and fetch missing data. */
+ GIT_FETCH_DEPTH_UNSHALLOW = 2147483647
+} git_fetch_depth_t;
+
+/**
+ * Fetch options structure.
+ *
+ * Zero out for defaults. Initialize with `GIT_FETCH_OPTIONS_INIT` macro to
+ * correctly set the `version` field. E.g.
+ *
+ * git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
+ */
+typedef struct {
+ int version;
+
+ /**
+ * Callbacks to use for this fetch operation
+ */
+ git_remote_callbacks callbacks;
+
+ /**
+ * Whether to perform a prune after the fetch
+ */
+ git_fetch_prune_t prune;
+
+ /**
+ * Whether to write the results to FETCH_HEAD. Defaults to
+ * on. Leave this default in order to behave like git.
+ */
+ int update_fetchhead;
+
+ /**
+ * Determines how to behave regarding tags on the remote, such
+ * as auto-downloading tags for objects we're downloading or
+ * downloading all of them.
+ *
+ * The default is to auto-follow tags.
+ */
+ git_remote_autotag_option_t download_tags;
+
+ /**
+ * Proxy options to use, by default no proxy is used.
+ */
+ git_proxy_options proxy_opts;
+
+ /**
+ * Depth of the fetch to perform, or `GIT_FETCH_DEPTH_FULL`
+ * (or `0`) for full history, or `GIT_FETCH_DEPTH_UNSHALLOW`
+ * to "unshallow" a shallow repository.
+ *
+ * The default is full (`GIT_FETCH_DEPTH_FULL` or `0`).
+ */
+ int depth;
+
+ /**
+ * Whether to allow off-site redirects. If this is not
+ * specified, the `http.followRedirects` configuration setting
+ * will be consulted.
+ */
+ git_remote_redirect_t follow_redirects;
+
+ /**
+ * Extra headers for this fetch operation
+ */
+ git_strarray custom_headers;
+} git_fetch_options;
+
+#define GIT_FETCH_OPTIONS_VERSION 1
+#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, GIT_FETCH_PRUNE_UNSPECIFIED, 1, \
+ GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_fetch_options structure
+ *
+ * Initializes a `git_fetch_options` with default values. Equivalent to
+ * creating an instance with `GIT_FETCH_OPTIONS_INIT`.
+ *
+ * @param opts The `git_fetch_options` struct to initialize.
+ * @param version The struct version; pass `GIT_FETCH_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_fetch_options_init(
+ git_fetch_options *opts,
+ unsigned int version);
+
+
+/**
+ * Controls the behavior of a git_push object.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * If the transport being used to push to the remote requires the creation
+ * of a pack file, this controls the number of worker threads used by
+ * the packbuilder when creating that pack file to be sent to the remote.
+ *
+ * If set to 0, the packbuilder will auto-detect the number of threads
+ * to create. The default value is 1.
+ */
+ unsigned int pb_parallelism;
+
+ /**
+ * Callbacks to use for this push operation
+ */
+ git_remote_callbacks callbacks;
+
+ /**
+ * Proxy options to use, by default no proxy is used.
+ */
+ git_proxy_options proxy_opts;
+
+ /**
+ * Whether to allow off-site redirects. If this is not
+ * specified, the `http.followRedirects` configuration setting
+ * will be consulted.
+ */
+ git_remote_redirect_t follow_redirects;
+
+ /**
+ * Extra headers for this push operation
+ */
+ git_strarray custom_headers;
+} git_push_options;
+
+#define GIT_PUSH_OPTIONS_VERSION 1
+#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION, 1, GIT_REMOTE_CALLBACKS_INIT, GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_push_options structure
+ *
+ * Initializes a `git_push_options` with default values. Equivalent to
+ * creating an instance with `GIT_PUSH_OPTIONS_INIT`.
+ *
+ * @param opts The `git_push_options` struct to initialize.
+ * @param version The struct version; pass `GIT_PUSH_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_push_options_init(
+ git_push_options *opts,
+ unsigned int version);
+
+/**
+ * Remote creation options structure
+ *
+ * Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_remote_create_options_init`.
+ *
+ */
+typedef struct {
+ unsigned int version;
+
+ /** Callbacks to use for this connection */
+ git_remote_callbacks callbacks;
+
+ /** HTTP Proxy settings */
+ git_proxy_options proxy_opts;
+
+ /**
+ * Whether to allow off-site redirects. If this is not
+ * specified, the `http.followRedirects` configuration setting
+ * will be consulted.
+ */
+ git_remote_redirect_t follow_redirects;
+
+ /** Extra HTTP headers to use in this connection */
+ git_strarray custom_headers;
+} git_remote_connect_options;
+
+#define GIT_REMOTE_CONNECT_OPTIONS_VERSION 1
+#define GIT_REMOTE_CONNECT_OPTIONS_INIT { \
+ GIT_REMOTE_CONNECT_OPTIONS_VERSION, \
+ GIT_REMOTE_CALLBACKS_INIT, \
+ GIT_PROXY_OPTIONS_INIT }
+
+/**
+ * Initialize git_remote_connect_options structure.
+ *
+ * Initializes a `git_remote_connect_options` with default values.
+ * Equivalent to creating an instance with
+ * `GIT_REMOTE_CONNECT_OPTIONS_INIT`.
+ *
+ * @param opts The `git_remote_connect_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REMOTE_CONNECT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_connect_options_init(
+ git_remote_connect_options *opts,
+ unsigned int version);
+
+/**
+ * Open a connection to a remote.
+ *
+ * The transport is selected based on the URL; the direction argument
+ * is due to a limitation of the git protocol which starts up a
+ * specific binary which can only do the one or the other.
+ *
+ * @param remote the remote to connect to
+ * @param direction GIT_DIRECTION_FETCH if you want to fetch or
+ * GIT_DIRECTION_PUSH if you want to push
+ * @param callbacks the callbacks to use for this connection
+ * @param proxy_opts proxy settings
+ * @param custom_headers extra HTTP headers to use in this connection
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_connect(
+ git_remote *remote,
+ git_direction direction,
+ const git_remote_callbacks *callbacks,
+ const git_proxy_options *proxy_opts,
+ const git_strarray *custom_headers);
+
+/**
+ * Open a connection to a remote with extended options.
+ *
+ * The transport is selected based on the URL; the direction argument
+ * is due to a limitation of the git protocol which starts up a
+ * specific binary which can only do the one or the other.
+ *
+ * The given options structure will form the defaults for connection
+ * options and callback setup. Callers may override these defaults
+ * by specifying `git_fetch_options` or `git_push_options` in
+ * subsequent calls.
+ *
+ * @param remote the remote to connect to
+ * @param direction GIT_DIRECTION_FETCH if you want to fetch or
+ * GIT_DIRECTION_PUSH if you want to push
+ * @param opts the remote connection options
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_connect_ext(
+ git_remote *remote,
+ git_direction direction,
+ const git_remote_connect_options *opts);
+
+/**
+ * Download and index the packfile.
+ *
+ * Connect to the remote if it hasn't been done yet, negotiate with
+ * the remote git which objects are missing, download and index the
+ * packfile.
+ *
+ * The .idx file will be created and both it and the packfile with be
+ * renamed to their final name.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @param remote the remote
+ * @param refspecs the refspecs to use for this negotiation and
+ * download. Use NULL or an empty array to use the base refspecs
+ * @param opts the options to use for this fetch or NULL
+ * @return 0 or an error code
+ */
+ GIT_EXTERN(int) git_remote_download(
+ git_remote *remote,
+ const git_strarray *refspecs,
+ const git_fetch_options *opts);
+
+/**
+ * Create a packfile and send it to the server
+ *
+ * Connect to the remote if it hasn't been done yet, negotiate with
+ * the remote git which objects are missing, create a packfile with
+ * the missing objects and send it.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @param remote the remote
+ * @param refspecs the refspecs to use for this negotiation and
+ * upload. Use NULL or an empty array to use the base refspecs
+ * @param opts the options to use for this push
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_upload(
+ git_remote *remote,
+ const git_strarray *refspecs,
+ const git_push_options *opts);
+
+/**
+ * Update the tips to the new state.
+ *
+ * If callbacks are not specified then the callbacks specified to
+ * `git_remote_connect` will be used (if it was called).
+ *
+ * @param remote the remote to update
+ * @param reflog_message The message to insert into the reflogs. If
+ * NULL and fetching, the default is "fetch <name>", where <name> is
+ * the name of the remote (or its url, for in-memory remotes). This
+ * parameter is ignored when pushing.
+ * @param callbacks pointer to the callback structure to use or NULL
+ * @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git.
+ * @param download_tags what the behaviour for downloading tags is for this fetch. This is
+ * ignored for push. This must be the same value passed to `git_remote_download()`.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_update_tips(
+ git_remote *remote,
+ const git_remote_callbacks *callbacks,
+ int update_fetchhead,
+ git_remote_autotag_option_t download_tags,
+ const char *reflog_message);
+
+/**
+ * Download new data and update tips.
+ *
+ * Convenience function to connect to a remote, download the data,
+ * disconnect and update the remote-tracking branches.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @param remote the remote to fetch from
+ * @param refspecs the refspecs to use for this fetch. Pass NULL or an
+ * empty array to use the base refspecs.
+ * @param opts options to use for this fetch or NULL
+ * @param reflog_message The message to insert into the reflogs. If NULL, the
+ * default is "fetch"
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_fetch(
+ git_remote *remote,
+ const git_strarray *refspecs,
+ const git_fetch_options *opts,
+ const char *reflog_message);
+
+/**
+ * Prune tracking refs that are no longer present on remote.
+ *
+ * If callbacks are not specified then the callbacks specified to
+ * `git_remote_connect` will be used (if it was called).
+ *
+ * @param remote the remote to prune
+ * @param callbacks callbacks to use for this prune
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_prune(
+ git_remote *remote,
+ const git_remote_callbacks *callbacks);
+
+/**
+ * Perform a push.
+ *
+ * If options are specified and this remote is already connected then
+ * the existing remote connection options will be discarded and the
+ * remote will now use the new options.
+ *
+ * @param remote the remote to push to
+ * @param refspecs the refspecs to use for pushing. If NULL or an empty
+ * array, the configured refspecs will be used
+ * @param opts options to use for this push
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_remote_push(
+ git_remote *remote,
+ const git_strarray *refspecs,
+ const git_push_options *opts);
+
+/**
+ * Get the statistics structure that is filled in by the fetch operation.
+ */
+GIT_EXTERN(const git_indexer_progress *) git_remote_stats(git_remote *remote);
+
+/**
+ * Retrieve the tag auto-follow setting
+ *
+ * @param remote the remote to query
+ * @return the auto-follow setting
+ */
+GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *remote);
+
+/**
+ * Set the remote's tag following setting.
+ *
+ * The change will be made in the configuration. No loaded remotes
+ * will be affected.
+ *
+ * @param repo the repository in which to make the change
+ * @param remote the name of the remote
+ * @param value the new value to take.
+ * @return 0, or an error code.
+ */
+GIT_EXTERN(int) git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value);
+
+/**
+ * Retrieve the ref-prune setting
+ *
+ * @param remote the remote to query
+ * @return the ref-prune setting
+ */
+GIT_EXTERN(int) git_remote_prune_refs(const git_remote *remote);
+
+/**
+ * Give the remote a new name
+ *
+ * All remote-tracking branches and configuration settings
+ * for the remote are updated.
+ *
+ * The new name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * No loaded instances of a the remote with the old name will change
+ * their name or their list of refspecs.
+ *
+ * @param problems non-default refspecs cannot be renamed and will be
+ * stored here for further processing by the caller. Always free this
+ * strarray on successful return.
+ * @param repo the repository in which to rename
+ * @param name the current name of the remote
+ * @param new_name the new name the remote should bear
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_rename(
+ git_strarray *problems,
+ git_repository *repo,
+ const char *name,
+ const char *new_name);
+
+/**
+ * Ensure the remote name is well-formed.
+ *
+ * @param valid output pointer to set with validity of given remote name
+ * @param remote_name name to be checked.
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_remote_name_is_valid(int *valid, const char *remote_name);
+
+/**
+* Delete an existing persisted remote.
+*
+* All remote-tracking branches and configuration settings
+* for the remote will be removed.
+*
+* @param repo the repository in which to act
+* @param name the name of the remote to delete
+* @return 0 on success, or an error code.
+*/
+GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name);
+
+/**
+ * Retrieve the name of the remote's default branch
+ *
+ * The default branch of a repository is the branch which HEAD points
+ * to. If the remote does not support reporting this information
+ * directly, it performs the guess as git does; that is, if there are
+ * multiple branches which point to the same commit, the first one is
+ * chosen. If the master branch is a candidate, it wins.
+ *
+ * This function must only be called after connecting.
+ *
+ * @param out the buffer in which to store the reference name
+ * @param remote the remote
+ * @return 0, GIT_ENOTFOUND if the remote does not have any references
+ * or none of them point to HEAD's commit, or an error message.
+ */
+GIT_EXTERN(int) git_remote_default_branch(git_buf *out, git_remote *remote);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/repository.h b/include/git2/repository.h
new file mode 100644
index 0000000..6ec2ac8
--- /dev/null
+++ b/include/git2/repository.h
@@ -0,0 +1,983 @@
+/*
+ * 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
+ * @param oid_type the oid type of the object database
+ * @return 0 or an error code
+ */
+#ifdef GIT_EXPERIMENTAL_SHA256
+GIT_EXTERN(int) git_repository_wrap_odb(
+ git_repository **out,
+ git_odb *odb,
+ git_oid_t oid_type);
+#else
+GIT_EXTERN(int) git_repository_wrap_odb(
+ git_repository **out,
+ git_odb *odb);
+#endif
+
+/**
+ * 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`.
+ */
+typedef enum {
+ /**
+ * 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_NO_SEARCH = (1 << 0),
+
+ /**
+ * Unless this flag is set, open will not continue searching across
+ * filesystem boundaries (i.e. when `st_dev` changes from the `stat`
+ * system call). For example, searching in a user's home directory at
+ * "/home/user/source/" will not return "/.git/" as the found repo if
+ * "/" is a different filesystem than "/home".
+ */
+ GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
+
+ /**
+ * 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_BARE = (1 << 2),
+
+ /**
+ * 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_NO_DOTGIT = (1 << 3),
+
+ /**
+ * 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.
+ */
+ 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.
+ */
+typedef enum {
+ /**
+ * Create a bare repository with no working directory.
+ */
+ GIT_REPOSITORY_INIT_BARE = (1u << 0),
+
+ /**
+ * Return an GIT_EEXISTS error if the repo_path appears to already be
+ * an git repository.
+ */
+ GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1),
+
+ /**
+ * 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.
+ */
+ GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2),
+
+ /**
+ * 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.
+ */
+ GIT_REPOSITORY_INIT_MKDIR = (1u << 3),
+
+ /**
+ * Recursively make all components of the repo and workdir paths as
+ * necessary.
+ */
+ GIT_REPOSITORY_INIT_MKPATH = (1u << 4),
+
+ /**
+ * 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_EXTERNAL_TEMPLATE = (1u << 5),
+
+ /**
+ * If an alternate workdir is specified, use relative paths for the gitdir
+ * and core.worktree.
+ */
+ 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
+ * defined modes.
+ */
+typedef enum {
+ /**
+ * Use permissions configured by umask - the default.
+ */
+ GIT_REPOSITORY_INIT_SHARED_UMASK = 0,
+
+ /**
+ * Use "--shared=group" behavior, chmod'ing the new repo to be group
+ * writable and "g+sx" for sticky group assignment.
+ */
+ GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775,
+
+ /**
+ * Use "--shared=all" behavior, adding world readability.
+ */
+ 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.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Combination of GIT_REPOSITORY_INIT flags above.
+ */
+ uint32_t flags;
+
+ /**
+ * Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... constants
+ * above, or to a custom value that you would like.
+ */
+ uint32_t mode;
+
+ /**
+ * 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.
+ */
+ const char *workdir_path;
+
+ /**
+ * If set, this will be used to initialize the "description" file in the
+ * repository, instead of using the template content.
+ */
+ const char *description;
+
+ /**
+ * 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.
+ */
+ const char *template_path;
+
+ /**
+ * 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.
+ */
+ const char *initial_head;
+
+ /**
+ * 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.
+ */
+ const char *origin_url;
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ /**
+ *
+ * Type of object IDs to use for this repository, or 0 for
+ * default (currently SHA1).
+ */
+ git_oid_t oid_type;
+#endif
+} git_repository_init_options;
+
+#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1
+#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}
+
+/**
+ * Initialize git_repository_init_options structure
+ *
+ * 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 The struct version; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_repository_init_options_init(
+ 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,
+ * or the branch specified for the repository in the `init.defaultBranch`
+ * configuration variable.
+ *
+ * @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__LAST
+} 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), GIT_ENOTFOUND 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, GIT_ENOTFOUND if the path cannot exist or an error code
+ */
+GIT_EXTERN(int) git_repository_item_path(git_buf *out, const 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(const 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(const git_repository *repo);
+
+/**
+ * Get the path of the shared common directory for this repository.
+ *
+ * If the repository is bare, it is the root directory for the repository.
+ * If the repository is a worktree, it is the parent repo's gitdir.
+ * Otherwise, it is the gitdir.
+ *
+ * @param repo A repository object
+ * @return the path to the common dir
+ */
+GIT_EXTERN(const char *) git_repository_commondir(const 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(const 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(const 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.
+ *
+ * @param repo Repository to remove prepared message from.
+ * @return 0 or an error code.
+ */
+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);
+
+/**
+ * Callback used to iterate over each FETCH_HEAD entry
+ *
+ * @see git_repository_fetchhead_foreach
+ *
+ * @param ref_name The reference name
+ * @param remote_url The remote URL
+ * @param oid The reference target OID
+ * @param is_merge Was the reference the result of a merge
+ * @param payload Payload passed to git_repository_fetchhead_foreach
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(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);
+
+/**
+ * Callback used to iterate over each MERGE_HEAD entry
+ *
+ * @see git_repository_mergehead_foreach
+ *
+ * @param oid The merge OID
+ * @param payload Payload passed to git_repository_mergehead_foreach
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(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. This
+ * may be an absolute path or a relative path, in which case it
+ * will be treated as a path within the working directory.
+ * @param type The object type to hash as (e.g. GIT_OBJECT_BLOB)
+ * @param as_path The path to use to look up filtering rules. If this is
+ * an empty string then no filters will be applied when
+ * calculating the hash. If this is `NULL` and the `path`
+ * parameter is a file within the repository's working
+ * directory, then the `path` will be used.
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_hashfile(
+ git_oid *out,
+ git_repository *repo,
+ const char *path,
+ git_object_t 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 committish 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 committish 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 *committish);
+
+/**
+ * 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 *committish);
+
+/**
+ * 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 committish, 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
+ * @return 0 or an error code
+ */
+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
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email);
+
+/**
+ * Gets the object type used by this repository.
+ *
+ * @param repo the repository
+ * @return the object id type
+ */
+GIT_EXTERN(git_oid_t) git_repository_oid_type(git_repository *repo);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/reset.h b/include/git2/reset.h
new file mode 100644
index 0000000..b2ee2ba
--- /dev/null
+++ b/include/git2/reset.h
@@ -0,0 +1,111 @@
+/*
+ * 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_reset_h__
+#define INCLUDE_git_reset_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "checkout.h"
+
+/**
+ * @file git2/reset.h
+ * @brief Git reset management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Kinds of reset operation
+ */
+typedef enum {
+ GIT_RESET_SOFT = 1, /**< Move the head to the given commit */
+ GIT_RESET_MIXED = 2, /**< SOFT plus reset index to the commit */
+ GIT_RESET_HARD = 3 /**< MIXED plus changes in working tree discarded */
+} git_reset_t;
+
+/**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * SOFT reset means the Head will be moved to the commit.
+ *
+ * MIXED reset will trigger a SOFT reset, plus the index will be replaced
+ * with the content of the commit tree.
+ *
+ * HARD reset will trigger a MIXED reset and the working directory will be
+ * replaced with the content of the index. (Untracked and ignored files
+ * will be left alone, however.)
+ *
+ * TODO: Implement remaining kinds of resets.
+ *
+ * @param repo Repository where to perform the reset operation.
+ *
+ * @param target Committish to which the Head should be moved to. This object
+ * must belong to the given `repo` and can either be a git_commit or a
+ * git_tag. When a git_tag is being passed, it should be dereferenceable
+ * to a git_commit which oid will be used as the target of the branch.
+ *
+ * @param reset_type Kind of reset operation to perform.
+ *
+ * @param checkout_opts Optional checkout options to be used for a HARD reset.
+ * The checkout_strategy field will be overridden (based on reset_type).
+ * This parameter can be used to propagate notify and progress callbacks.
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_reset(
+ git_repository *repo,
+ const git_object *target,
+ git_reset_t reset_type,
+ const git_checkout_options *checkout_opts);
+
+/**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * This behaves like `git_reset()` 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_reset()`.
+ *
+ * @see git_reset
+ */
+GIT_EXTERN(int) git_reset_from_annotated(
+ git_repository *repo,
+ const git_annotated_commit *commit,
+ git_reset_t reset_type,
+ const git_checkout_options *checkout_opts);
+
+/**
+ * Updates some entries in the index from the target commit tree.
+ *
+ * The scope of the updated entries is determined by the paths
+ * being passed in the `pathspec` parameters.
+ *
+ * Passing a NULL `target` will result in removing
+ * entries in the index matching the provided pathspecs.
+ *
+ * @param repo Repository where to perform the reset operation.
+ *
+ * @param target The committish which content will be used to reset the content
+ * of the index.
+ *
+ * @param pathspecs List of pathspecs to operate on.
+ *
+ * @return 0 on success or an error code < 0
+ */
+GIT_EXTERN(int) git_reset_default(
+ git_repository *repo,
+ const git_object *target,
+ const git_strarray* pathspecs);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/revert.h b/include/git2/revert.h
new file mode 100644
index 0000000..331e90d
--- /dev/null
+++ b/include/git2/revert.h
@@ -0,0 +1,91 @@
+/*
+ * 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_revert_h__
+#define INCLUDE_git_revert_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/revert.h
+ * @brief Git revert routines
+ * @defgroup git_revert Git revert routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Options for revert
+ */
+typedef struct {
+ unsigned int version;
+
+ /** For merge commits, the "mainline" is treated as the parent. */
+ unsigned int mainline;
+
+ git_merge_options merge_opts; /**< Options for the merging */
+ git_checkout_options checkout_opts; /**< Options for the checkout */
+} git_revert_options;
+
+#define GIT_REVERT_OPTIONS_VERSION 1
+#define GIT_REVERT_OPTIONS_INIT {GIT_REVERT_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initialize git_revert_options structure
+ *
+ * Initializes a `git_revert_options` with default values. Equivalent to
+ * creating an instance with `GIT_REVERT_OPTIONS_INIT`.
+ *
+ * @param opts The `git_revert_options` struct to initialize.
+ * @param version The struct version; pass `GIT_REVERT_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_revert_options_init(
+ git_revert_options *opts,
+ unsigned int version);
+
+/**
+ * Reverts the given commit against the given "our" commit, producing an
+ * index that reflects the result of the revert.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param revert_commit the commit to revert
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_revert_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *revert_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_options);
+
+/**
+ * Reverts the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to revert
+ * @param commit the commit to revert
+ * @param given_opts the revert options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_revert(
+ git_repository *repo,
+ git_commit *commit,
+ const git_revert_options *given_opts);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/revparse.h b/include/git2/revparse.h
new file mode 100644
index 0000000..51ea2dc
--- /dev/null
+++ b/include/git2/revparse.h
@@ -0,0 +1,113 @@
+/*
+ * 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_revparse_h__
+#define INCLUDE_git_revparse_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/revparse.h
+ * @brief Git revision parsing routines
+ * @defgroup git_revparse Git revision parsing routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Find a single object, as specified by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * The returned object should be released with `git_object_free` when no
+ * longer needed.
+ *
+ * @param out pointer to output object
+ * @param repo the repository to search in
+ * @param spec the textual specification for an object
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_revparse_single(
+ git_object **out, git_repository *repo, const char *spec);
+
+/**
+ * Find a single object and intermediate reference by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * In some cases (`@{<-n>}` or `<branchname>@{upstream}`), the expression may
+ * point to an intermediate reference. When such expressions are being passed
+ * in, `reference_out` will be valued as well.
+ *
+ * The returned object should be released with `git_object_free` and the
+ * returned reference with `git_reference_free` when no longer needed.
+ *
+ * @param object_out pointer to output object
+ * @param reference_out pointer to output reference or NULL
+ * @param repo the repository to search in
+ * @param spec the textual specification for an object
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC
+ * or an error code
+ */
+GIT_EXTERN(int) git_revparse_ext(
+ git_object **object_out,
+ git_reference **reference_out,
+ git_repository *repo,
+ const char *spec);
+
+/**
+ * Revparse flags. These indicate the intended behavior of the spec passed to
+ * git_revparse.
+ */
+typedef enum {
+ /** The spec targeted a single object. */
+ GIT_REVSPEC_SINGLE = 1 << 0,
+ /** The spec targeted a range of commits. */
+ GIT_REVSPEC_RANGE = 1 << 1,
+ /** The spec used the '...' operator, which invokes special semantics. */
+ GIT_REVSPEC_MERGE_BASE = 1 << 2
+} git_revspec_t;
+
+/**
+ * Git Revision Spec: output of a `git_revparse` operation
+ */
+typedef struct {
+ /** The left element of the revspec; must be freed by the user */
+ git_object *from;
+ /** The right element of the revspec; must be freed by the user */
+ git_object *to;
+ /** The intent of the revspec (i.e. `git_revspec_mode_t` flags) */
+ unsigned int flags;
+} git_revspec;
+
+/**
+ * Parse a revision string for `from`, `to`, and intent.
+ *
+ * See `man gitrevisions` or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * @param revspec Pointer to an user-allocated git_revspec struct where
+ * the result of the rev-parse will be stored
+ * @param repo the repository to search in
+ * @param spec the rev-parse spec to parse
+ * @return 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code
+ */
+GIT_EXTERN(int) git_revparse(
+ git_revspec *revspec,
+ git_repository *repo,
+ const char *spec);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h
new file mode 100644
index 0000000..4aa9f5b
--- /dev/null
+++ b/include/git2/revwalk.h
@@ -0,0 +1,302 @@
+/*
+ * 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_revwalk_h__
+#define INCLUDE_git_revwalk_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/revwalk.h
+ * @brief Git revision traversal routines
+ * @defgroup git_revwalk Git revision traversal routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags to specify the sorting which a revwalk should perform.
+ */
+typedef enum {
+ /**
+ * Sort the output with the same default method from `git`: reverse
+ * chronological order. This is the default sorting for new walkers.
+ */
+ GIT_SORT_NONE = 0,
+
+ /**
+ * Sort the repository contents in topological order (no parents before
+ * all of its children are shown); this sorting mode can be combined
+ * with time sorting to produce `git`'s `--date-order``.
+ */
+ GIT_SORT_TOPOLOGICAL = 1 << 0,
+
+ /**
+ * Sort the repository contents by commit time;
+ * this sorting mode can be combined with
+ * topological sorting.
+ */
+ GIT_SORT_TIME = 1 << 1,
+
+ /**
+ * Iterate through the repository contents in reverse
+ * order; this sorting mode can be combined with
+ * any of the above.
+ */
+ GIT_SORT_REVERSE = 1 << 2
+} git_sort_t;
+
+/**
+ * Allocate a new revision walker to iterate through a repo.
+ *
+ * This revision walker uses a custom memory pool and an internal
+ * commit cache, so it is relatively expensive to allocate.
+ *
+ * For maximum performance, this revision walker should be
+ * reused for different walks.
+ *
+ * This revision walker is *not* thread safe: it may only be
+ * used to walk a repository on a single thread; however,
+ * it is possible to have several revision walkers in
+ * several different threads walking the same repository.
+ *
+ * @param out pointer to the new revision walker
+ * @param repo the repo to walk through
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo);
+
+/**
+ * Reset the revision walker for reuse.
+ *
+ * This will clear all the pushed and hidden commits, and
+ * leave the walker in a blank state (just like at
+ * creation) ready to receive new commit pushes and
+ * start a new walk.
+ *
+ * The revision walk is automatically reset when a walk
+ * is over.
+ *
+ * @param walker handle to reset.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_reset(git_revwalk *walker);
+
+/**
+ * Add a new root for the traversal
+ *
+ * The pushed commit will be marked as one of the roots from which to
+ * start the walk. This commit may not be walked if it or a child is
+ * hidden.
+ *
+ * At least one commit must be pushed onto the walker before a walk
+ * can be started.
+ *
+ * The given id must belong to a committish on the walked
+ * repository.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param id the oid of the commit to start from.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
+
+/**
+ * Push matching references
+ *
+ * The OIDs pointed to by the references that match the given glob
+ * pattern will be pushed to the revision walker.
+ *
+ * A leading 'refs/' is implied if not present as well as a trailing
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
+ *
+ * @param walk the walker being used for the traversal
+ * @param glob the glob pattern references should match
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob);
+
+/**
+ * Push the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
+
+/**
+ * Mark a commit (and its ancestors) uninteresting for the output.
+ *
+ * The given id must belong to a committish on the walked
+ * repository.
+ *
+ * The resolved commit and all its parents will be hidden from the
+ * output on the revision walk.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param commit_id the oid of commit that will be ignored during the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
+
+/**
+ * Hide matching references.
+ *
+ * The OIDs pointed to by the references that match the given glob
+ * pattern and their ancestors will be hidden from the output on the
+ * revision walk.
+ *
+ * A leading 'refs/' is implied if not present as well as a trailing
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
+ *
+ * @param walk the walker being used for the traversal
+ * @param glob the glob pattern references should match
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
+
+/**
+ * Hide the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
+
+/**
+ * Push the OID pointed to by a reference
+ *
+ * The reference must point to a committish.
+ *
+ * @param walk the walker being used for the traversal
+ * @param refname the reference to push
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
+
+/**
+ * Hide the OID pointed to by a reference
+ *
+ * The reference must point to a committish.
+ *
+ * @param walk the walker being used for the traversal
+ * @param refname the reference to hide
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
+
+/**
+ * Get the next commit from the revision walk.
+ *
+ * The initial call to this method is *not* blocking when
+ * iterating through a repo with a time-sorting mode.
+ *
+ * Iterating with Topological or inverted modes makes the initial
+ * call blocking to preprocess the commit list, but this block should be
+ * mostly unnoticeable on most repositories (topological preprocessing
+ * times at 0.3s on the git.git repo).
+ *
+ * The revision walker is reset when the walk is over.
+ *
+ * @param out Pointer where to store the oid of the next commit
+ * @param walk the walker to pop the commit from.
+ * @return 0 if the next commit was found;
+ * GIT_ITEROVER if there are no commits left to iterate
+ */
+GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk);
+
+/**
+ * Change the sorting mode when iterating through the
+ * repository's contents.
+ *
+ * Changing the sorting mode resets the walker.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param sort_mode combination of GIT_SORT_XXX flags
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode);
+
+/**
+ * Push and hide the respective endpoints of the given range.
+ *
+ * The range should be of the form
+ * <commit>..<commit>
+ * where each <commit> is in the form accepted by 'git_revparse_single'.
+ * The left-hand commit will be hidden and the right-hand commit pushed.
+ *
+ * @param walk the walker being used for the traversal
+ * @param range the range
+ * @return 0 or an error code
+ *
+ */
+GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range);
+
+/**
+ * Simplify the history by first-parent
+ *
+ * No parents other than the first for each commit will be enqueued.
+ *
+ * @param walk The revision walker.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_simplify_first_parent(git_revwalk *walk);
+
+
+/**
+ * Free a revision walker previously allocated.
+ *
+ * @param walk traversal handle to close. If NULL nothing occurs.
+ */
+GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk);
+
+/**
+ * Return the repository on which this walker
+ * is operating.
+ *
+ * @param walk the revision walker
+ * @return the repository being walked
+ */
+GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk);
+
+/**
+ * This is a callback function that user can provide to hide a
+ * commit and its parents. If the callback function returns non-zero value,
+ * then this commit and its parents will be hidden.
+ *
+ * @param commit_id oid of Commit
+ * @param payload User-specified pointer to data to be passed as data payload
+ * @return non-zero to hide the commmit and it parent.
+ */
+typedef int GIT_CALLBACK(git_revwalk_hide_cb)(
+ const git_oid *commit_id,
+ void *payload);
+
+/**
+ * Adds, changes or removes a callback function to hide a commit and its parents
+ *
+ * @param walk the revision walker
+ * @param hide_cb callback function to hide a commit and its parents
+ * @param payload data payload to be passed to callback function
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_revwalk_add_hide_cb(
+ git_revwalk *walk,
+ git_revwalk_hide_cb hide_cb,
+ void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/signature.h b/include/git2/signature.h
new file mode 100644
index 0000000..849998e
--- /dev/null
+++ b/include/git2/signature.h
@@ -0,0 +1,103 @@
+/*
+ * 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_signature_h__
+#define INCLUDE_git_signature_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/signature.h
+ * @brief Git signature creation
+ * @defgroup git_signature Git signature creation
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new action signature.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * Note: angle brackets ('<' and '>') characters are not allowed
+ * to be used in either the `name` or the `email` parameter.
+ *
+ * @param out new signature, in case of error NULL
+ * @param name name of the person
+ * @param email email of the person
+ * @param time time (in seconds from epoch) when the action happened
+ * @param offset timezone offset (in minutes) for the time
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const char *email, git_time_t time, int offset);
+
+/**
+ * Create a new action signature with a timestamp of 'now'.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * @param out new signature, in case of error NULL
+ * @param name name of the person
+ * @param email email of the person
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email);
+
+/**
+ * Create a new action signature with default user and now timestamp.
+ *
+ * This looks up the user.name and user.email from the configuration and
+ * uses the current time as the timestamp, and creates a new signature
+ * based on that information. It will return GIT_ENOTFOUND if either the
+ * user.name or user.email are not set.
+ *
+ * @param out new signature
+ * @param repo repository pointer
+ * @return 0 on success, GIT_ENOTFOUND if config is missing, or error code
+ */
+GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo);
+
+/**
+ * Create a new signature by parsing the given buffer, which is
+ * expected to be in the format "Real Name <email> timestamp tzoffset",
+ * where `timestamp` is the number of seconds since the Unix epoch and
+ * `tzoffset` is the timezone offset in `hhmm` format (note the lack
+ * of a colon separator).
+ *
+ * @param out new signature
+ * @param buf signature string
+ * @return 0 on success, GIT_EINVALID if the signature is not parseable, or an error code
+ */
+GIT_EXTERN(int) git_signature_from_buffer(git_signature **out, const char *buf);
+
+/**
+ * Create a copy of an existing signature. All internal strings are also
+ * duplicated.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param sig signature to duplicate
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_dup(git_signature **dest, const git_signature *sig);
+
+/**
+ * Free an existing signature.
+ *
+ * Because the signature is not an opaque structure, it is legal to free it
+ * manually, but be sure to free the "name" and "email" strings in addition
+ * to the structure itself.
+ *
+ * @param sig signature to free
+ */
+GIT_EXTERN(void) git_signature_free(git_signature *sig);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/stash.h b/include/git2/stash.h
new file mode 100644
index 0000000..dcfc013
--- /dev/null
+++ b/include/git2/stash.h
@@ -0,0 +1,314 @@
+/*
+ * 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_stash_h__
+#define INCLUDE_git_stash_h__
+
+#include "common.h"
+#include "types.h"
+#include "checkout.h"
+
+/**
+ * @file git2/stash.h
+ * @brief Git stash management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Stash flags
+ */
+typedef enum {
+ /**
+ * No option, default
+ */
+ GIT_STASH_DEFAULT = 0,
+
+ /**
+ * All changes already added to the index are left intact in
+ * the working directory
+ */
+ GIT_STASH_KEEP_INDEX = (1 << 0),
+
+ /**
+ * All untracked files are also stashed and then cleaned up
+ * from the working directory
+ */
+ GIT_STASH_INCLUDE_UNTRACKED = (1 << 1),
+
+ /**
+ * All ignored files are also stashed and then cleaned up from
+ * the working directory
+ */
+ GIT_STASH_INCLUDE_IGNORED = (1 << 2),
+
+ /**
+ * All changes in the index and working directory are left intact
+ */
+ GIT_STASH_KEEP_ALL = (1 << 3)
+} git_stash_flags;
+
+/**
+ * Save the local modifications to a new stash.
+ *
+ * @param out Object id of the commit containing the stashed state.
+ * This commit is also the target of the direct reference refs/stash.
+ * @param repo The owning repository.
+ * @param stasher The identity of the person performing the stashing.
+ * @param message Optional description along with the stashed state.
+ * @param flags Flags to control the stashing process. (see GIT_STASH_* above)
+ * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash,
+ * or error code.
+ */
+GIT_EXTERN(int) git_stash_save(
+ git_oid *out,
+ git_repository *repo,
+ const git_signature *stasher,
+ const char *message,
+ uint32_t flags);
+
+/**
+ * Stash save options structure
+ *
+ * Initialize with `GIT_STASH_SAVE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_stash_save_options_init`.
+ *
+ */
+typedef struct git_stash_save_options {
+ unsigned int version;
+
+ /** Flags to control the stashing process. (see GIT_STASH_* above) */
+ uint32_t flags;
+
+ /** The identity of the person performing the stashing. */
+ const git_signature *stasher;
+
+ /** Optional description along with the stashed state. */
+ const char *message;
+
+ /** Optional paths that control which files are stashed. */
+ git_strarray paths;
+} git_stash_save_options;
+
+#define GIT_STASH_SAVE_OPTIONS_VERSION 1
+#define GIT_STASH_SAVE_OPTIONS_INIT { GIT_STASH_SAVE_OPTIONS_VERSION }
+
+/**
+ * Initialize git_stash_save_options structure
+ *
+ * Initializes a `git_stash_save_options` with default values. Equivalent to
+ * creating an instance with `GIT_STASH_SAVE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_stash_save_options` struct to initialize.
+ * @param version The struct version; pass `GIT_STASH_SAVE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_stash_save_options_init(
+ git_stash_save_options *opts, unsigned int version);
+
+/**
+ * Save the local modifications to a new stash, with options.
+ *
+ * @param out Object id of the commit containing the stashed state.
+ * This commit is also the target of the direct reference refs/stash.
+ * @param repo The owning repository.
+ * @param opts The stash options.
+ * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash,
+ * or error code.
+ */
+GIT_EXTERN(int) git_stash_save_with_opts(
+ git_oid *out,
+ git_repository *repo,
+ const git_stash_save_options *opts);
+
+/** Stash application flags. */
+typedef enum {
+ GIT_STASH_APPLY_DEFAULT = 0,
+
+ /* Try to reinstate not only the working tree's changes,
+ * but also the index's changes.
+ */
+ GIT_STASH_APPLY_REINSTATE_INDEX = (1 << 0)
+} git_stash_apply_flags;
+
+/** Stash apply progression states */
+typedef enum {
+ GIT_STASH_APPLY_PROGRESS_NONE = 0,
+
+ /** Loading the stashed data from the object database. */
+ GIT_STASH_APPLY_PROGRESS_LOADING_STASH,
+
+ /** The stored index is being analyzed. */
+ GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX,
+
+ /** The modified files are being analyzed. */
+ GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED,
+
+ /** The untracked and ignored files are being analyzed. */
+ GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED,
+
+ /** The untracked files are being written to disk. */
+ GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED,
+
+ /** The modified files are being written to disk. */
+ GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED,
+
+ /** The stash was applied successfully. */
+ GIT_STASH_APPLY_PROGRESS_DONE
+} git_stash_apply_progress_t;
+
+/**
+ * Stash application progress notification function.
+ * Return 0 to continue processing, or a negative value to
+ * abort the stash application.
+ */
+typedef int GIT_CALLBACK(git_stash_apply_progress_cb)(
+ git_stash_apply_progress_t progress,
+ void *payload);
+
+/**
+ * Stash application options structure
+ *
+ * Initialize with `GIT_STASH_APPLY_OPTIONS_INIT`. Alternatively, you can
+ * use `git_stash_apply_options_init`.
+ *
+ */
+typedef struct git_stash_apply_options {
+ unsigned int version;
+
+ /** See `git_stash_apply_flags`, above. */
+ uint32_t flags;
+
+ /** Options to use when writing files to the working directory. */
+ git_checkout_options checkout_options;
+
+ /** Optional callback to notify the consumer of application progress. */
+ git_stash_apply_progress_cb progress_cb;
+ void *progress_payload;
+} git_stash_apply_options;
+
+#define GIT_STASH_APPLY_OPTIONS_VERSION 1
+#define GIT_STASH_APPLY_OPTIONS_INIT { \
+ GIT_STASH_APPLY_OPTIONS_VERSION, \
+ GIT_STASH_APPLY_DEFAULT, \
+ GIT_CHECKOUT_OPTIONS_INIT }
+
+/**
+ * Initialize git_stash_apply_options structure
+ *
+ * Initializes a `git_stash_apply_options` with default values. Equivalent to
+ * creating an instance with `GIT_STASH_APPLY_OPTIONS_INIT`.
+ *
+ * @param opts The `git_stash_apply_options` struct to initialize.
+ * @param version The struct version; pass `GIT_STASH_APPLY_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_stash_apply_options_init(
+ git_stash_apply_options *opts, unsigned int version);
+
+/**
+ * Apply a single stashed state from the stash list.
+ *
+ * If local changes in the working directory conflict with changes in the
+ * stash then GIT_EMERGECONFLICT will be returned. In this case, the index
+ * will always remain unmodified and all files in the working directory will
+ * remain unmodified. However, if you are restoring untracked files or
+ * ignored files and there is a conflict when applying the modified files,
+ * then those files will remain in the working directory.
+ *
+ * If passing the GIT_STASH_APPLY_REINSTATE_INDEX flag and there would be
+ * conflicts when reinstating the index, the function will return
+ * GIT_EMERGECONFLICT and both the working directory and index will be left
+ * unmodified.
+ *
+ * Note that a minimum checkout strategy of `GIT_CHECKOUT_SAFE` is implied.
+ *
+ * @param repo The owning repository.
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ * @param options Optional options to control how stashes are applied.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the
+ * given index, GIT_EMERGECONFLICT if changes exist in the working
+ * directory, or an error code
+ */
+GIT_EXTERN(int) git_stash_apply(
+ git_repository *repo,
+ size_t index,
+ const git_stash_apply_options *options);
+
+/**
+ * This is a callback function you can provide to iterate over all the
+ * stashed states that will be invoked per entry.
+ *
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ * @param message The stash message.
+ * @param stash_id The commit oid of the stashed state.
+ * @param payload Extra parameter to callback function.
+ * @return 0 to continue iterating or non-zero to stop.
+ */
+typedef int GIT_CALLBACK(git_stash_cb)(
+ size_t index,
+ const char *message,
+ const git_oid *stash_id,
+ void *payload);
+
+/**
+ * Loop over all the stashed states and issue a callback for each one.
+ *
+ * If the callback returns a non-zero value, this will stop looping.
+ *
+ * @param repo Repository where to find the stash.
+ *
+ * @param callback Callback to invoke per found stashed state. The most
+ * recent stash state will be enumerated first.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, non-zero callback return value, or error code.
+ */
+GIT_EXTERN(int) git_stash_foreach(
+ git_repository *repo,
+ git_stash_cb callback,
+ void *payload);
+
+/**
+ * Remove a single stashed state from the stash list.
+ *
+ * @param repo The owning repository.
+ *
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
+ * index, or error code.
+ */
+GIT_EXTERN(int) git_stash_drop(
+ git_repository *repo,
+ size_t index);
+
+/**
+ * Apply a single stashed state from the stash list and remove it from the list
+ * if successful.
+ *
+ * @param repo The owning repository.
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ * @param options Optional options to control how stashes are applied.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
+ * index, or error code. (see git_stash_apply() above for details)
+*/
+GIT_EXTERN(int) git_stash_pop(
+ git_repository *repo,
+ size_t index,
+ const git_stash_apply_options *options);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/status.h b/include/git2/status.h
new file mode 100644
index 0000000..bb28e87
--- /dev/null
+++ b/include/git2/status.h
@@ -0,0 +1,452 @@
+/*
+ * 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_status_h__
+#define INCLUDE_git_status_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "diff.h"
+
+/**
+ * @file git2/status.h
+ * @brief Git file status routines
+ * @defgroup git_status Git file status routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Status flags for a single file.
+ *
+ * A combination of these values will be returned to indicate the status of
+ * a file. Status compares the working directory, the index, and the
+ * current HEAD of the repository. The `GIT_STATUS_INDEX` set of flags
+ * represents the status of file in the index relative to the HEAD, and the
+ * `GIT_STATUS_WT` set of flags represent the status of the file in the
+ * working directory relative to the index.
+ */
+typedef enum {
+ GIT_STATUS_CURRENT = 0,
+
+ GIT_STATUS_INDEX_NEW = (1u << 0),
+ GIT_STATUS_INDEX_MODIFIED = (1u << 1),
+ GIT_STATUS_INDEX_DELETED = (1u << 2),
+ GIT_STATUS_INDEX_RENAMED = (1u << 3),
+ GIT_STATUS_INDEX_TYPECHANGE = (1u << 4),
+
+ GIT_STATUS_WT_NEW = (1u << 7),
+ GIT_STATUS_WT_MODIFIED = (1u << 8),
+ GIT_STATUS_WT_DELETED = (1u << 9),
+ GIT_STATUS_WT_TYPECHANGE = (1u << 10),
+ GIT_STATUS_WT_RENAMED = (1u << 11),
+ GIT_STATUS_WT_UNREADABLE = (1u << 12),
+
+ GIT_STATUS_IGNORED = (1u << 14),
+ GIT_STATUS_CONFLICTED = (1u << 15)
+} git_status_t;
+
+/**
+ * Function pointer to receive status on individual files
+ *
+ * `path` is the relative path to the file from the root of the repository.
+ *
+ * `status_flags` is a combination of `git_status_t` values that apply.
+ *
+ * `payload` is the value you passed to the foreach function as payload.
+ */
+typedef int GIT_CALLBACK(git_status_cb)(
+ const char *path, unsigned int status_flags, void *payload);
+
+/**
+ * Select the files on which to report status.
+ *
+ * With `git_status_foreach_ext`, this will control which changes get
+ * callbacks. With `git_status_list_new`, these will control which
+ * changes are included in the list.
+ */
+typedef enum {
+ /**
+ * The default. This roughly matches `git status --porcelain` regarding
+ * which files are included and in what order.
+ */
+ GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0,
+
+ /**
+ * Only gives status based on HEAD to index comparison, not looking at
+ * working directory changes.
+ */
+ GIT_STATUS_SHOW_INDEX_ONLY = 1,
+
+ /**
+ * Only gives status based on index to working directory comparison,
+ * not comparing the index to the HEAD.
+ */
+ GIT_STATUS_SHOW_WORKDIR_ONLY = 2
+} git_status_show_t;
+
+/**
+ * Flags to control status callbacks
+ *
+ * Calling `git_status_foreach()` is like calling the extended version
+ * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
+ * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. Those options are bundled
+ * together as `GIT_STATUS_OPT_DEFAULTS` if you want them as a baseline.
+ */
+typedef enum {
+ /**
+ * Says that callbacks should be made on untracked files.
+ * These will only be made if the workdir files are included in the status
+ * "show" option.
+ */
+ GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0),
+
+ /**
+ * Says that ignored files get callbacks.
+ * Again, these callbacks will only be made if the workdir files are
+ * included in the status "show" option.
+ */
+ GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1),
+
+ /**
+ * Indicates that callback should be made even on unmodified files.
+ */
+ GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2),
+
+ /**
+ * Indicates that submodules should be skipped.
+ * This only applies if there are no pending typechanges to the submodule
+ * (either from or to another type).
+ */
+ GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3),
+
+ /**
+ * Indicates that all files in untracked directories should be included.
+ * Normally if an entire directory is new, then just the top-level
+ * directory is included (with a trailing slash on the entry name).
+ * This flag says to include all of the individual files in the directory
+ * instead.
+ */
+ GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4),
+
+ /**
+ * Indicates that the given path should be treated as a literal path,
+ * and not as a pathspec pattern.
+ */
+ GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5),
+
+ /**
+ * Indicates that the contents of ignored directories should be included
+ * in the status. This is like doing `git ls-files -o -i --exclude-standard`
+ * with core git.
+ */
+ GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6),
+
+ /**
+ * Indicates that rename detection should be processed between the head and
+ * the index and enables the GIT_STATUS_INDEX_RENAMED as a possible status
+ * flag.
+ */
+ GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX = (1u << 7),
+
+ /**
+ * Indicates that rename detection should be run between the index and the
+ * working directory and enabled GIT_STATUS_WT_RENAMED as a possible status
+ * flag.
+ */
+ GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8),
+
+ /**
+ * Overrides the native case sensitivity for the file system and forces
+ * the output to be in case-sensitive order.
+ */
+ GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9),
+
+ /**
+ * Overrides the native case sensitivity for the file system and forces
+ * the output to be in case-insensitive order.
+ */
+ GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10),
+
+ /**
+ * Iindicates that rename detection should include rewritten files.
+ */
+ GIT_STATUS_OPT_RENAMES_FROM_REWRITES = (1u << 11),
+
+ /**
+ * Bypasses the default status behavior of doing a "soft" index reload
+ * (i.e. reloading the index data if the file on disk has been modified
+ * outside libgit2).
+ */
+ GIT_STATUS_OPT_NO_REFRESH = (1u << 12),
+
+ /**
+ * Tells libgit2 to refresh the stat cache in the index for files that are
+ * unchanged but have out of date stat einformation in the index.
+ * It will result in less work being done on subsequent calls to get status.
+ * This is mutually exclusive with the NO_REFRESH option.
+ */
+ GIT_STATUS_OPT_UPDATE_INDEX = (1u << 13),
+
+ /**
+ * Normally files that cannot be opened or read are ignored as
+ * these are often transient files; this option will return
+ * unreadable files as `GIT_STATUS_WT_UNREADABLE`.
+ */
+ GIT_STATUS_OPT_INCLUDE_UNREADABLE = (1u << 14),
+
+ /**
+ * Unreadable files will be detected and given the status
+ * untracked instead of unreadable.
+ */
+ GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15)
+} git_status_opt_t;
+
+#define GIT_STATUS_OPT_DEFAULTS \
+ (GIT_STATUS_OPT_INCLUDE_IGNORED | \
+ GIT_STATUS_OPT_INCLUDE_UNTRACKED | \
+ GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS)
+
+/**
+ * Options to control how `git_status_foreach_ext()` will issue callbacks.
+ *
+ * Initialize with `GIT_STATUS_OPTIONS_INIT`. Alternatively, you can
+ * use `git_status_options_init`.
+ *
+ */
+typedef struct {
+ /**
+ * The struct version; pass `GIT_STATUS_OPTIONS_VERSION`.
+ */
+ unsigned int version;
+
+ /**
+ * The `show` value is one of the `git_status_show_t` constants that
+ * control which files to scan and in what order. The default is
+ * `GIT_STATUS_SHOW_INDEX_AND_WORKDIR`.
+ */
+ git_status_show_t show;
+
+ /**
+ * The `flags` value is an OR'ed combination of the
+ * `git_status_opt_t` values above. The default is
+ * `GIT_STATUS_OPT_DEFAULTS`, which matches git's default
+ * behavior.
+ */
+ unsigned int flags;
+
+ /**
+ * The `pathspec` is an array of path patterns to match (using
+ * fnmatch-style matching), or just an array of paths to match
+ * exactly if `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified
+ * in the flags.
+ */
+ git_strarray pathspec;
+
+ /**
+ * The `baseline` is the tree to be used for comparison to the
+ * working directory and index; defaults to HEAD.
+ */
+ git_tree *baseline;
+
+ /**
+ * Threshold above which similar files will be considered renames.
+ * This is equivalent to the -M option. Defaults to 50.
+ */
+ uint16_t rename_threshold;
+} git_status_options;
+
+#define GIT_STATUS_OPTIONS_VERSION 1
+#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION}
+
+/**
+ * Initialize git_status_options structure
+ *
+ * Initializes a `git_status_options` with default values. Equivalent to
+ * creating an instance with `GIT_STATUS_OPTIONS_INIT`.
+ *
+ * @param opts The `git_status_options` struct to initialize.
+ * @param version The struct version; pass `GIT_STATUS_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_status_options_init(
+ git_status_options *opts,
+ unsigned int version);
+
+/**
+ * A status entry, providing the differences between the file as it exists
+ * in HEAD and the index, and providing the differences between the index
+ * and the working directory.
+ *
+ * The `status` value provides the status flags for this file.
+ *
+ * The `head_to_index` value provides detailed information about the
+ * differences between the file in HEAD and the file in the index.
+ *
+ * The `index_to_workdir` value provides detailed information about the
+ * differences between the file in the index and the file in the
+ * working directory.
+ */
+typedef struct {
+ git_status_t status;
+ git_diff_delta *head_to_index;
+ git_diff_delta *index_to_workdir;
+} git_status_entry;
+
+
+/**
+ * Gather file statuses and run a callback for each one.
+ *
+ * The callback is passed the path of the file, the status (a combination of
+ * the `git_status_t` values above) and the `payload` data pointer passed
+ * into this function.
+ *
+ * If the callback returns a non-zero value, this function will stop looping
+ * and return that value to caller.
+ *
+ * @param repo A repository object
+ * @param callback The function to call on each file
+ * @param payload Pointer to pass through to callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_status_foreach(
+ git_repository *repo,
+ git_status_cb callback,
+ void *payload);
+
+/**
+ * Gather file status information and run callbacks as requested.
+ *
+ * This is an extended version of the `git_status_foreach()` API that
+ * allows for more granular control over which paths will be processed and
+ * in what order. See the `git_status_options` structure for details
+ * about the additional controls that this makes available.
+ *
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate. To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
+ * @param repo Repository object
+ * @param opts Status options structure
+ * @param callback The function to call on each file
+ * @param payload Pointer to pass through to callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_status_foreach_ext(
+ git_repository *repo,
+ const git_status_options *opts,
+ git_status_cb callback,
+ void *payload);
+
+/**
+ * Get file status for a single file.
+ *
+ * This tries to get status for the filename that you give. If no files
+ * match that name (in either the HEAD, index, or working directory), this
+ * returns GIT_ENOTFOUND.
+ *
+ * If the name matches multiple files (for example, if the `path` names a
+ * directory or if running on a case- insensitive filesystem and yet the
+ * HEAD has two entries that both match the path), then this returns
+ * GIT_EAMBIGUOUS because it cannot give correct results.
+ *
+ * This does not do any sort of rename detection. Renames require a set of
+ * targets and because of the path filtering, there is not enough
+ * information to check renames correctly. To check file status with rename
+ * detection, there is no choice but to do a full `git_status_list_new` and
+ * scan through looking for the path that you are interested in.
+ *
+ * @param status_flags Output combination of git_status_t values for file
+ * @param repo A repository object
+ * @param path The exact path to retrieve status for relative to the
+ * repository working directory
+ * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,
+ * index, and work tree, GIT_EAMBIGUOUS if `path` matches multiple files
+ * or if it refers to a folder, and -1 on other errors.
+ */
+GIT_EXTERN(int) git_status_file(
+ unsigned int *status_flags,
+ git_repository *repo,
+ const char *path);
+
+/**
+ * Gather file status information and populate the `git_status_list`.
+ *
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate. To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
+ * @param out Pointer to store the status results in
+ * @param repo Repository object
+ * @param opts Status options structure
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_status_list_new(
+ git_status_list **out,
+ git_repository *repo,
+ const git_status_options *opts);
+
+/**
+ * Gets the count of status entries in this list.
+ *
+ * If there are no changes in status (at least according the options given
+ * when the status list was created), this can return 0.
+ *
+ * @param statuslist Existing status list object
+ * @return the number of status entries
+ */
+GIT_EXTERN(size_t) git_status_list_entrycount(
+ git_status_list *statuslist);
+
+/**
+ * Get a pointer to one of the entries in the status list.
+ *
+ * The entry is not modifiable and should not be freed.
+ *
+ * @param statuslist Existing status list object
+ * @param idx Position of the entry
+ * @return Pointer to the entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_status_entry *) git_status_byindex(
+ git_status_list *statuslist,
+ size_t idx);
+
+/**
+ * Free an existing status list
+ *
+ * @param statuslist Existing status list object
+ */
+GIT_EXTERN(void) git_status_list_free(
+ git_status_list *statuslist);
+
+/**
+ * Test if the ignore rules apply to a given file.
+ *
+ * This function checks the ignore rules to see if they would apply to the
+ * given file. This indicates if the file would be ignored regardless of
+ * whether the file is already in the index or committed to the repository.
+ *
+ * One way to think of this is if you were to do "git add ." on the
+ * directory containing the file, would it be added or not?
+ *
+ * @param ignored Boolean returning 0 if the file is not ignored, 1 if it is
+ * @param repo A repository object
+ * @param path The file to check ignores for, rooted at the repo's workdir.
+ * @return 0 if ignore rules could be processed for the file (regardless
+ * of whether it exists or not), or an error < 0 if they could not.
+ */
+GIT_EXTERN(int) git_status_should_ignore(
+ int *ignored,
+ git_repository *repo,
+ const char *path);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/stdint.h b/include/git2/stdint.h
new file mode 100644
index 0000000..6950427
--- /dev/null
+++ b/include/git2/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER // [
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
+
+#endif // _MSC_VER ] \ No newline at end of file
diff --git a/include/git2/strarray.h b/include/git2/strarray.h
new file mode 100644
index 0000000..03d93f8
--- /dev/null
+++ b/include/git2/strarray.h
@@ -0,0 +1,43 @@
+/*
+ * 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_strarray_h__
+#define INCLUDE_git_strarray_h__
+
+#include "common.h"
+
+/**
+ * @file git2/strarray.h
+ * @brief Git string array routines
+ * @defgroup git_strarray Git string array routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Array of strings */
+typedef struct git_strarray {
+ char **strings;
+ size_t count;
+} git_strarray;
+
+/**
+ * Free the strings contained in a string array. This method should
+ * be called on `git_strarray` objects that were provided by the
+ * library. Not doing so, will result in a memory leak.
+ *
+ * This does not free the `git_strarray` itself, since the library will
+ * never allocate that object directly itself.
+ *
+ * @param array The git_strarray that contains strings to free
+ */
+GIT_EXTERN(void) git_strarray_dispose(git_strarray *array);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/submodule.h b/include/git2/submodule.h
new file mode 100644
index 0000000..2082966
--- /dev/null
+++ b/include/git2/submodule.h
@@ -0,0 +1,668 @@
+/*
+ * 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_submodule_h__
+#define INCLUDE_git_submodule_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "remote.h"
+#include "checkout.h"
+
+/**
+ * @file git2/submodule.h
+ * @brief Git submodule management utilities
+ *
+ * Submodule support in libgit2 builds a list of known submodules and keeps
+ * it in the repository. The list is built from the .gitmodules file, the
+ * .git/config file, the index, and the HEAD tree. Items in the working
+ * directory that look like submodules (i.e. a git repo) but are not
+ * mentioned in those places won't be tracked.
+ *
+ * @defgroup git_submodule Git submodule management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Return codes for submodule status.
+ *
+ * A combination of these flags will be returned to describe the status of a
+ * submodule. Depending on the "ignore" property of the submodule, some of
+ * the flags may never be returned because they indicate changes that are
+ * supposed to be ignored.
+ *
+ * Submodule info is contained in 4 places: the HEAD tree, the index, config
+ * files (both .git/config and .gitmodules), and the working directory. Any
+ * or all of those places might be missing information about the submodule
+ * depending on what state the repo is in. We consider all four places to
+ * build the combination of status flags.
+ *
+ * There are four values that are not really status, but give basic info
+ * about what sources of submodule data are available. These will be
+ * returned even if ignore is set to "ALL".
+ *
+ * * IN_HEAD - superproject head contains submodule
+ * * IN_INDEX - superproject index contains submodule
+ * * IN_CONFIG - superproject gitmodules has submodule
+ * * IN_WD - superproject workdir has submodule
+ *
+ * The following values will be returned so long as ignore is not "ALL".
+ *
+ * * INDEX_ADDED - in index, not in head
+ * * INDEX_DELETED - in head, not in index
+ * * INDEX_MODIFIED - index and head don't match
+ * * WD_UNINITIALIZED - workdir contains empty directory
+ * * WD_ADDED - in workdir, not index
+ * * WD_DELETED - in index, not workdir
+ * * WD_MODIFIED - index and workdir head don't match
+ *
+ * The following can only be returned if ignore is "NONE" or "UNTRACKED".
+ *
+ * * WD_INDEX_MODIFIED - submodule workdir index is dirty
+ * * WD_WD_MODIFIED - submodule workdir has modified files
+ *
+ * Lastly, the following will only be returned for ignore "NONE".
+ *
+ * * WD_UNTRACKED - wd contains untracked files
+ */
+typedef enum {
+ GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0),
+ GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1),
+ GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2),
+ GIT_SUBMODULE_STATUS_IN_WD = (1u << 3),
+ GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4),
+ GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5),
+ GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6),
+ GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7),
+ GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8),
+ GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9),
+ GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10),
+ GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11),
+ GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12),
+ GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13)
+} git_submodule_status_t;
+
+#define GIT_SUBMODULE_STATUS__IN_FLAGS 0x000Fu
+#define GIT_SUBMODULE_STATUS__INDEX_FLAGS 0x0070u
+#define GIT_SUBMODULE_STATUS__WD_FLAGS 0x3F80u
+
+#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \
+ (((S) & ~GIT_SUBMODULE_STATUS__IN_FLAGS) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_INDEX_UNMODIFIED(S) \
+ (((S) & GIT_SUBMODULE_STATUS__INDEX_FLAGS) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(S) \
+ (((S) & (GIT_SUBMODULE_STATUS__WD_FLAGS & \
+ ~GIT_SUBMODULE_STATUS_WD_UNINITIALIZED)) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_WD_DIRTY(S) \
+ (((S) & (GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED | \
+ GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | \
+ GIT_SUBMODULE_STATUS_WD_UNTRACKED)) != 0)
+
+/**
+ * Function pointer to receive each submodule
+ *
+ * @param sm git_submodule currently being visited
+ * @param name name of the submodule
+ * @param payload value you passed to the foreach function as payload
+ * @return 0 on success or error code
+ */
+typedef int GIT_CALLBACK(git_submodule_cb)(
+ git_submodule *sm, const char *name, void *payload);
+
+/**
+ * Submodule update options structure
+ *
+ * Initialize with `GIT_SUBMODULE_UPDATE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_submodule_update_options_init`.
+ *
+ */
+typedef struct git_submodule_update_options {
+ unsigned int version;
+
+ /**
+ * These options are passed to the checkout step. To disable
+ * checkout, set the `checkout_strategy` to
+ * `GIT_CHECKOUT_NONE`. Generally you will want the use
+ * GIT_CHECKOUT_SAFE to update files in the working
+ * directory.
+ */
+ git_checkout_options checkout_opts;
+
+ /**
+ * Options which control the fetch, including callbacks.
+ *
+ * The callbacks to use for reporting fetch progress, and for acquiring
+ * credentials in the event they are needed.
+ */
+ git_fetch_options fetch_opts;
+
+ /**
+ * Allow fetching from the submodule's default remote if the target
+ * commit isn't found. Enabled by default.
+ */
+ int allow_fetch;
+} git_submodule_update_options;
+
+#define GIT_SUBMODULE_UPDATE_OPTIONS_VERSION 1
+#define GIT_SUBMODULE_UPDATE_OPTIONS_INIT \
+ { GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, \
+ { GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
+ GIT_FETCH_OPTIONS_INIT, 1 }
+
+/**
+ * Initialize git_submodule_update_options structure
+ *
+ * Initializes a `git_submodule_update_options` with default values. Equivalent to
+ * creating an instance with `GIT_SUBMODULE_UPDATE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_submodule_update_options` struct to initialize.
+ * @param version The struct version; pass `GIT_SUBMODULE_UPDATE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_submodule_update_options_init(
+ git_submodule_update_options *opts, unsigned int version);
+
+/**
+ * Update a submodule. This will clone a missing submodule and
+ * checkout the subrepository to the commit specified in the index of
+ * the containing repository. If the submodule repository doesn't contain
+ * the target commit (e.g. because fetchRecurseSubmodules isn't set), then
+ * the submodule is fetched using the fetch options supplied in options.
+ *
+ * @param submodule Submodule object
+ * @param init If the submodule is not initialized, setting this flag to true
+ * will initialize the submodule before updating. Otherwise, this will
+ * return an error if attempting to update an uninitialized repository.
+ * but setting this to true forces them to be updated.
+ * @param options configuration options for the update. If NULL, the
+ * function works as though GIT_SUBMODULE_UPDATE_OPTIONS_INIT was passed.
+ * @return 0 on success, any non-zero return value from a callback
+ * function, or a negative value to indicate an error (use
+ * `git_error_last` for a detailed error message).
+ */
+GIT_EXTERN(int) git_submodule_update(git_submodule *submodule, int init, git_submodule_update_options *options);
+
+/**
+ * Lookup submodule information by name or path.
+ *
+ * Given either the submodule name or path (they are usually the same), this
+ * returns a structure describing the submodule.
+ *
+ * There are two expected error scenarios:
+ *
+ * - The submodule is not mentioned in the HEAD, the index, and the config,
+ * but does "exist" in the working directory (i.e. there is a subdirectory
+ * that appears to be a Git repository). In this case, this function
+ * returns GIT_EEXISTS to indicate a sub-repository exists but not in a
+ * state where a git_submodule can be instantiated.
+ * - The submodule is not mentioned in the HEAD, index, or config and the
+ * working directory doesn't contain a value git repo at that path.
+ * There may or may not be anything else at that path, but nothing that
+ * looks like a submodule. In this case, this returns GIT_ENOTFOUND.
+ *
+ * You must call `git_submodule_free` when done with the submodule.
+ *
+ * @param out Output ptr to submodule; pass NULL to just get return code
+ * @param repo The parent repository
+ * @param name The name of or path to the submodule; trailing slashes okay
+ * @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
+ * GIT_EEXISTS if a repository is found in working directory only,
+ * -1 on other errors.
+ */
+GIT_EXTERN(int) git_submodule_lookup(
+ git_submodule **out,
+ git_repository *repo,
+ const char *name);
+
+/**
+ * Create an in-memory copy of a submodule. The copy must be explicitly
+ * free'd or it will leak.
+ *
+ * @param out Pointer to store the copy of the submodule.
+ * @param source Original submodule to copy.
+ * @return 0
+ */
+GIT_EXTERN(int) git_submodule_dup(git_submodule **out, git_submodule *source);
+
+/**
+ * Release a submodule
+ *
+ * @param submodule Submodule object
+ */
+GIT_EXTERN(void) git_submodule_free(git_submodule *submodule);
+
+/**
+ * Iterate over all tracked submodules of a repository.
+ *
+ * See the note on `git_submodule` above. This iterates over the tracked
+ * submodules as described therein.
+ *
+ * If you are concerned about items in the working directory that look like
+ * submodules but are not tracked, the diff API will generate a diff record
+ * for workdir items that look like submodules but are not tracked, showing
+ * them as added in the workdir. Also, the status API will treat the entire
+ * subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item.
+ *
+ * @param repo The repository
+ * @param callback Function to be called with the name of each submodule.
+ * Return a non-zero value to terminate the iteration.
+ * @param payload Extra data to pass to callback
+ * @return 0 on success, -1 on error, or non-zero return value of callback
+ */
+GIT_EXTERN(int) git_submodule_foreach(
+ git_repository *repo,
+ git_submodule_cb callback,
+ void *payload);
+
+/**
+ * Set up a new git submodule for checkout.
+ *
+ * This does "git submodule add" up to the fetch and checkout of the
+ * submodule contents. It preps a new submodule, creates an entry in
+ * .gitmodules and creates an empty initialized repository either at the
+ * given path in the working directory or in .git/modules with a gitlink
+ * from the working directory to the new repo.
+ *
+ * To fully emulate "git submodule add" call this function, then open the
+ * submodule repo and perform the clone step as needed (if you don't need
+ * anything custom see `git_submodule_add_clone()`). Lastly, call
+ * `git_submodule_add_finalize()` to wrap up adding the new submodule and
+ * .gitmodules to the index to be ready to commit.
+ *
+ * You must call `git_submodule_free` on the submodule object when done.
+ *
+ * @param out The newly created submodule ready to open for clone
+ * @param repo The repository in which you want to create the submodule
+ * @param url URL for the submodule's remote
+ * @param path Path at which the submodule should be created
+ * @param use_gitlink Should workdir contain a gitlink to the repo in
+ * .git/modules vs. repo directly in workdir.
+ * @return 0 on success, GIT_EEXISTS if submodule already exists,
+ * -1 on other errors.
+ */
+GIT_EXTERN(int) git_submodule_add_setup(
+ git_submodule **out,
+ git_repository *repo,
+ const char *url,
+ const char *path,
+ int use_gitlink);
+
+/**
+ * Perform the clone step for a newly created submodule.
+ *
+ * This performs the necessary `git_clone` to setup a newly-created submodule.
+ *
+ * @param out The newly created repository object. Optional.
+ * @param submodule The submodule currently waiting for its clone.
+ * @param opts The options to use.
+ *
+ * @return 0 on success, -1 on other errors (see git_clone).
+ */
+GIT_EXTERN(int) git_submodule_clone(
+ git_repository **out,
+ git_submodule *submodule,
+ const git_submodule_update_options *opts);
+
+/**
+ * Resolve the setup of a new git submodule.
+ *
+ * This should be called on a submodule once you have called add setup
+ * and done the clone of the submodule. This adds the .gitmodules file
+ * and the newly cloned submodule to the index to be ready to be committed
+ * (but doesn't actually do the commit).
+ *
+ * @param submodule The submodule to finish adding.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule);
+
+/**
+ * Add current submodule HEAD commit to index of superproject.
+ *
+ * @param submodule The submodule to add to the index
+ * @param write_index Boolean if this should immediately write the index
+ * file. If you pass this as false, you will have to get the
+ * git_index and explicitly call `git_index_write()` on it to
+ * save the change.
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_add_to_index(
+ git_submodule *submodule,
+ int write_index);
+
+/**
+ * Get the containing repository for a submodule.
+ *
+ * This returns a pointer to the repository that contains the submodule.
+ * This is a just a reference to the repository that was passed to the
+ * original `git_submodule_lookup()` call, so if that repository has been
+ * freed, then this may be a dangling reference.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to `git_repository`
+ */
+GIT_EXTERN(git_repository *) git_submodule_owner(git_submodule *submodule);
+
+/**
+ * Get the name of submodule.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule name
+ */
+GIT_EXTERN(const char *) git_submodule_name(git_submodule *submodule);
+
+/**
+ * Get the path to the submodule.
+ *
+ * The path is almost always the same as the submodule name, but the
+ * two are actually not required to match.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule path
+ */
+GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule);
+
+/**
+ * Get the URL for the submodule.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule url
+ */
+GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule);
+
+/**
+ * Resolve a submodule url relative to the given repository.
+ *
+ * @param out buffer to store the absolute submodule url in
+ * @param repo Pointer to repository object
+ * @param url Relative url
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url);
+
+/**
+* Get the branch for the submodule.
+*
+* @param submodule Pointer to submodule object
+* @return Pointer to the submodule branch
+*/
+GIT_EXTERN(const char *) git_submodule_branch(git_submodule *submodule);
+
+/**
+ * Set the branch for the submodule in the configuration
+ *
+ * After calling this, you may wish to call `git_submodule_sync()` to
+ * write the changes to the checked out submodule repository.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param branch Branch that should be used for the submodule
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_set_branch(git_repository *repo, const char *name, const char *branch);
+
+/**
+ * Set the URL for the submodule in the configuration
+ *
+ *
+ * After calling this, you may wish to call `git_submodule_sync()` to
+ * write the changes to the checked out submodule repository.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param url URL that should be used for the submodule
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_set_url(git_repository *repo, const char *name, const char *url);
+
+/**
+ * Get the OID for the submodule in the index.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not in index.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_index_id(git_submodule *submodule);
+
+/**
+ * Get the OID for the submodule in the current HEAD tree.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not in the HEAD.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule);
+
+/**
+ * Get the OID for the submodule in the current working directory.
+ *
+ * This returns the OID that corresponds to looking up 'HEAD' in the checked
+ * out submodule. If there are pending changes in the index or anything
+ * else, this won't notice that. You should call `git_submodule_status()`
+ * for a more complete picture about the state of the working directory.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not checked out.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
+
+/**
+ * Get the ignore rule that will be used for the submodule.
+ *
+ * These values control the behavior of `git_submodule_status()` for this
+ * submodule. There are four ignore values:
+ *
+ * - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents
+ * of the submodule from a clean checkout to be dirty, including the
+ * addition of untracked files. This is the default if unspecified.
+ * - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the
+ * working tree (i.e. call `git_status_foreach()` on the submodule) but
+ * UNTRACKED files will not count as making the submodule dirty.
+ * - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the
+ * submodule has moved for status. This is fast since it does not need to
+ * scan the working tree of the submodule at all.
+ * - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo.
+ * The working directory will be consider clean so long as there is a
+ * checked out version present.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_ignore_t valyue what will be used for
+ * this submodule.
+ */
+GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
+ git_submodule *submodule);
+
+/**
+ * Set the ignore rule for the submodule in the configuration
+ *
+ * This does not affect any currently-loaded instances.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submdule
+ * @param ignore The new value for the ignore rule
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_set_ignore(
+ git_repository *repo,
+ const char *name,
+ git_submodule_ignore_t ignore);
+
+/**
+ * Get the update rule that will be used for the submodule.
+ *
+ * This value controls the behavior of the `git submodule update` command.
+ * There are four useful values documented with `git_submodule_update_t`.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_update_t value that will be used
+ * for this submodule.
+ */
+GIT_EXTERN(git_submodule_update_t) git_submodule_update_strategy(
+ git_submodule *submodule);
+
+/**
+ * Set the update rule for the submodule in the configuration
+ *
+ * This setting won't affect any existing instances.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param update The new value to use
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_set_update(
+ git_repository *repo,
+ const char *name,
+ git_submodule_update_t update);
+
+/**
+ * Read the fetchRecurseSubmodules rule for a submodule.
+ *
+ * This accesses the submodule.<name>.fetchRecurseSubmodules value for
+ * the submodule that controls fetching behavior for the submodule.
+ *
+ * Note that at this time, libgit2 does not honor this setting and the
+ * fetch functionality current ignores submodules.
+ *
+ * @return 0 if fetchRecurseSubmodules is false, 1 if true
+ */
+GIT_EXTERN(git_submodule_recurse_t) git_submodule_fetch_recurse_submodules(
+ git_submodule *submodule);
+
+/**
+ * Set the fetchRecurseSubmodules rule for a submodule in the configuration
+ *
+ * This setting won't affect any existing instances.
+ *
+ * @param repo the repository to affect
+ * @param name the submodule to configure
+ * @param fetch_recurse_submodules Boolean value
+ * @return old value for fetchRecurseSubmodules
+ */
+GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
+ git_repository *repo,
+ const char *name,
+ git_submodule_recurse_t fetch_recurse_submodules);
+
+/**
+ * Copy submodule info into ".git/config" file.
+ *
+ * Just like "git submodule init", this copies information about the
+ * submodule into ".git/config". You can use the accessor functions
+ * above to alter the in-memory git_submodule object and control what
+ * is written to the config, overriding what is in .gitmodules.
+ *
+ * @param submodule The submodule to write into the superproject config
+ * @param overwrite By default, existing entries will not be overwritten,
+ * but setting this to true forces them to be updated.
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite);
+
+/**
+ * Set up the subrepository for a submodule in preparation for clone.
+ *
+ * This function can be called to init and set up a submodule
+ * repository from a submodule in preparation to clone it from
+ * its remote.
+ *
+ * @param out Output pointer to the created git repository.
+ * @param sm The submodule to create a new subrepository from.
+ * @param use_gitlink Should the workdir contain a gitlink to
+ * the repo in .git/modules vs. repo directly in workdir.
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_submodule_repo_init(
+ git_repository **out,
+ const git_submodule *sm,
+ int use_gitlink);
+
+/**
+ * Copy submodule remote info into submodule repo.
+ *
+ * This copies the information about the submodules URL into the checked out
+ * submodule config, acting like "git submodule sync". This is useful if
+ * you have altered the URL for the submodule (or it has been altered by a
+ * fetch of upstream changes) and you need to update your local repo.
+ *
+ * @param submodule The submodule to copy.
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule);
+
+/**
+ * Open the repository for a submodule.
+ *
+ * This is a newly opened repository object. The caller is responsible for
+ * calling `git_repository_free()` on it when done. Multiple calls to this
+ * function will return distinct `git_repository` objects. This will only
+ * work if the submodule is checked out into the working directory.
+ *
+ * @param repo Pointer to the submodule repo which was opened
+ * @param submodule Submodule to be opened
+ * @return 0 on success, <0 if submodule repo could not be opened.
+ */
+GIT_EXTERN(int) git_submodule_open(
+ git_repository **repo,
+ git_submodule *submodule);
+
+/**
+ * Reread submodule info from config, index, and HEAD.
+ *
+ * Call this to reread cached submodule information for this submodule if
+ * you have reason to believe that it has changed.
+ *
+ * @param submodule The submodule to reload
+ * @param force Force reload even if the data doesn't seem out of date
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule, int force);
+
+/**
+ * Get the status for a submodule.
+ *
+ * This looks at a submodule and tries to determine the status. It
+ * will return a combination of the `GIT_SUBMODULE_STATUS` values above.
+ * How deeply it examines the working directory to do this will depend
+ * on the `git_submodule_ignore_t` value for the submodule.
+ *
+ * @param status Combination of `GIT_SUBMODULE_STATUS` flags
+ * @param repo the repository in which to look
+ * @param name name of the submodule
+ * @param ignore the ignore rules to follow
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_status(
+ unsigned int *status,
+ git_repository *repo,
+ const char *name,
+ git_submodule_ignore_t ignore);
+
+/**
+ * Get the locations of submodule information.
+ *
+ * This is a bit like a very lightweight version of `git_submodule_status`.
+ * It just returns a made of the first four submodule status values (i.e.
+ * the ones like GIT_SUBMODULE_STATUS_IN_HEAD, etc) that tell you where the
+ * submodule data comes from (i.e. the HEAD commit, gitmodules file, etc.).
+ * This can be useful if you want to know if the submodule is present in the
+ * working directory at this point in time, etc.
+ *
+ * @param location_status Combination of first four `GIT_SUBMODULE_STATUS` flags
+ * @param submodule Submodule for which to get status
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_location(
+ unsigned int *location_status,
+ git_submodule *submodule);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/alloc.h b/include/git2/sys/alloc.h
new file mode 100644
index 0000000..e7f85b8
--- /dev/null
+++ b/include/git2/sys/alloc.h
@@ -0,0 +1,67 @@
+/*
+ * 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_sys_git_alloc_h__
+#define INCLUDE_sys_git_alloc_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * An instance for a custom memory allocator
+ *
+ * Setting the pointers of this structure allows the developer to implement
+ * custom memory allocators. The global memory allocator can be set by using
+ * "GIT_OPT_SET_ALLOCATOR" with the `git_libgit2_opts` function. Keep in mind
+ * that all fields need to be set to a proper function.
+ */
+typedef struct {
+ /** Allocate `n` bytes of memory */
+ void * GIT_CALLBACK(gmalloc)(size_t n, const char *file, int line);
+
+ /**
+ * This function shall deallocate the old object `ptr` and return a
+ * pointer to a new object that has the size specified by `size`. In
+ * case `ptr` is `NULL`, a new array shall be allocated.
+ */
+ void * GIT_CALLBACK(grealloc)(void *ptr, size_t size, const char *file, int line);
+
+ /**
+ * This function shall free the memory pointed to by `ptr`. In case
+ * `ptr` is `NULL`, this shall be a no-op.
+ */
+ void GIT_CALLBACK(gfree)(void *ptr);
+} git_allocator;
+
+/**
+ * Initialize the allocator structure to use the `stdalloc` pointer.
+ *
+ * Set up the structure so that all of its members are using the standard
+ * "stdalloc" allocator functions. The structure can then be used with
+ * `git_allocator_setup`.
+ *
+ * @param allocator The allocator that is to be initialized.
+ * @return An error code or 0.
+ */
+int git_stdalloc_init_allocator(git_allocator *allocator);
+
+/**
+ * Initialize the allocator structure to use the `crtdbg` pointer.
+ *
+ * Set up the structure so that all of its members are using the "crtdbg"
+ * allocator functions. Note that this allocator is only available on Windows
+ * platforms and only if libgit2 is being compiled with "-DMSVC_CRTDBG".
+ *
+ * @param allocator The allocator that is to be initialized.
+ * @return An error code or 0.
+ */
+int git_win32_crtdbg_init_allocator(git_allocator *allocator);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h
new file mode 100644
index 0000000..ba67106
--- /dev/null
+++ b/include/git2/sys/commit.h
@@ -0,0 +1,80 @@
+/*
+ * 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_sys_git_commit_h__
+#define INCLUDE_sys_git_commit_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/commit.h
+ * @brief Low-level Git commit creation
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create new commit in the repository from a list of `git_oid` values.
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` and
+ * `parents` now take `git_oid`. This is a dangerous API in that nor
+ * the `tree`, neither the `parents` list of `git_oid`s are checked for
+ * validity.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_from_ids(
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_oid *tree,
+ size_t parent_count,
+ const git_oid *parents[]);
+
+/**
+ * Callback function to return parents for commit.
+ *
+ * This is invoked with the count of the number of parents processed so far
+ * along with the user supplied payload. This should return a git_oid of
+ * the next parent or NULL if all parents have been provided.
+ */
+typedef const git_oid * GIT_CALLBACK(git_commit_parent_callback)(size_t idx, void *payload);
+
+/**
+ * Create a new commit in the repository with an callback to supply parents.
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` takes a
+ * `git_oid` and doesn't check for validity, and `parent_cb` is invoked
+ * with `parent_payload` and should return `git_oid` values or NULL to
+ * indicate that all parents are accounted for.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_from_callback(
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_oid *tree,
+ git_commit_parent_callback parent_cb,
+ void *parent_payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h
new file mode 100644
index 0000000..06e045f
--- /dev/null
+++ b/include/git2/sys/commit_graph.h
@@ -0,0 +1,184 @@
+/*
+ * 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_sys_git_commit_graph_h__
+#define INCLUDE_sys_git_commit_graph_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/commit_graph.h
+ * @brief Git commit-graph
+ * @defgroup git_commit_graph Git commit-graph APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Opens a `git_commit_graph` from a path to an objects directory.
+ *
+ * This finds, opens, and validates the `commit-graph` file.
+ *
+ * @param cgraph_out the `git_commit_graph` struct to initialize.
+ * @param objects_dir the path to a git objects directory.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_commit_graph_open(
+ git_commit_graph **cgraph_out,
+ const char *objects_dir
+#ifdef GIT_EXPERIMENTAL_SHA256
+ , git_oid_t oid_type
+#endif
+ );
+
+/**
+ * Frees commit-graph data. This should only be called when memory allocated
+ * using `git_commit_graph_open` is not returned to libgit2 because it was not
+ * associated with the ODB through a successful call to
+ * `git_odb_set_commit_graph`.
+ *
+ * @param cgraph the commit-graph object to free. If NULL, no action is taken.
+ */
+GIT_EXTERN(void) git_commit_graph_free(git_commit_graph *cgraph);
+
+/**
+ * Create a new writer for `commit-graph` files.
+ *
+ * @param out Location to store the writer pointer.
+ * @param objects_info_dir The `objects/info` directory.
+ * The `commit-graph` file will be written in this directory.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_graph_writer_new(
+ git_commit_graph_writer **out,
+ const char *objects_info_dir
+#ifdef GIT_EXPERIMENTAL_SHA256
+ , git_oid_t oid_type
+#endif
+ );
+
+/**
+ * Free the commit-graph writer and its resources.
+ *
+ * @param w The writer to free. If NULL no action is taken.
+ */
+GIT_EXTERN(void) git_commit_graph_writer_free(git_commit_graph_writer *w);
+
+/**
+ * Add an `.idx` file (associated to a packfile) to the writer.
+ *
+ * @param w The writer.
+ * @param repo The repository that owns the `.idx` file.
+ * @param idx_path The path of an `.idx` file.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_graph_writer_add_index_file(
+ git_commit_graph_writer *w,
+ git_repository *repo,
+ const char *idx_path);
+
+/**
+ * Add a revwalk to the writer. This will add all the commits from the revwalk
+ * to the commit-graph.
+ *
+ * @param w The writer.
+ * @param walk The git_revwalk.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_graph_writer_add_revwalk(
+ git_commit_graph_writer *w,
+ git_revwalk *walk);
+
+
+/**
+ * The strategy to use when adding a new set of commits to a pre-existing
+ * commit-graph chain.
+ */
+typedef enum {
+ /**
+ * Do not split commit-graph files. The other split strategy-related option
+ * fields are ignored.
+ */
+ GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE = 0
+} git_commit_graph_split_strategy_t;
+
+/**
+ * Options structure for
+ * `git_commit_graph_writer_commit`/`git_commit_graph_writer_dump`.
+ *
+ * Initialize with `GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT`. Alternatively, you
+ * can use `git_commit_graph_writer_options_init`.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * The strategy to use when adding new commits to a pre-existing commit-graph
+ * chain.
+ */
+ git_commit_graph_split_strategy_t split_strategy;
+
+ /**
+ * The number of commits in level N is less than X times the number of
+ * commits in level N + 1. Default is 2.
+ */
+ float size_multiple;
+
+ /**
+ * The number of commits in level N + 1 is more than C commits.
+ * Default is 64000.
+ */
+ size_t max_commits;
+} git_commit_graph_writer_options;
+
+#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION 1
+#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT { \
+ GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION \
+ }
+
+/**
+ * Initialize git_commit_graph_writer_options structure
+ *
+ * Initializes a `git_commit_graph_writer_options` with default values. Equivalent to
+ * creating an instance with `GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT`.
+ *
+ * @param opts The `git_commit_graph_writer_options` struct to initialize.
+ * @param version The struct version; pass `GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_commit_graph_writer_options_init(
+ git_commit_graph_writer_options *opts,
+ unsigned int version);
+
+/**
+ * Write a `commit-graph` file to a file.
+ *
+ * @param w The writer
+ * @param opts Pointer to git_commit_graph_writer_options struct.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_graph_writer_commit(
+ git_commit_graph_writer *w,
+ git_commit_graph_writer_options *opts);
+
+/**
+ * Dump the contents of the `commit-graph` to an in-memory buffer.
+ *
+ * @param buffer Buffer where to store the contents of the `commit-graph`.
+ * @param w The writer.
+ * @param opts Pointer to git_commit_graph_writer_options struct.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_graph_writer_dump(
+ git_buf *buffer,
+ git_commit_graph_writer *w,
+ git_commit_graph_writer_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h
new file mode 100644
index 0000000..0a9005e
--- /dev/null
+++ b/include/git2/sys/config.h
@@ -0,0 +1,130 @@
+/*
+ * 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_sys_git_config_backend_h__
+#define INCLUDE_sys_git_config_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/config.h"
+
+/**
+ * @file git2/sys/config.h
+ * @brief Git config backend routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Every iterator must have this struct as its first element, so the
+ * API can talk to it. You'd define your iterator as
+ *
+ * struct my_iterator {
+ * git_config_iterator parent;
+ * ...
+ * }
+ *
+ * and assign `iter->parent.backend` to your `git_config_backend`.
+ */
+struct git_config_iterator {
+ git_config_backend *backend;
+ unsigned int flags;
+
+ /**
+ * Return the current entry and advance the iterator. The
+ * memory belongs to the library.
+ */
+ int GIT_CALLBACK(next)(git_config_entry **entry, git_config_iterator *iter);
+
+ /**
+ * Free the iterator
+ */
+ void GIT_CALLBACK(free)(git_config_iterator *iter);
+};
+
+/**
+ * Generic backend that implements the interface to
+ * access a configuration file
+ */
+struct git_config_backend {
+ unsigned int version;
+ /** True if this backend is for a snapshot */
+ int readonly;
+ struct git_config *cfg;
+
+ /* Open means open the file/database and parse if necessary */
+ int GIT_CALLBACK(open)(struct git_config_backend *, git_config_level_t level, const git_repository *repo);
+ int GIT_CALLBACK(get)(struct git_config_backend *, const char *key, git_config_entry **entry);
+ int GIT_CALLBACK(set)(struct git_config_backend *, const char *key, const char *value);
+ int GIT_CALLBACK(set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
+ int GIT_CALLBACK(del)(struct git_config_backend *, const char *key);
+ int GIT_CALLBACK(del_multivar)(struct git_config_backend *, const char *key, const char *regexp);
+ int GIT_CALLBACK(iterator)(git_config_iterator **, struct git_config_backend *);
+ /** Produce a read-only version of this backend */
+ int GIT_CALLBACK(snapshot)(struct git_config_backend **, struct git_config_backend *);
+ /**
+ * Lock this backend.
+ *
+ * Prevent any writes to the data store backing this
+ * backend. Any updates must not be visible to any other
+ * readers.
+ */
+ int GIT_CALLBACK(lock)(struct git_config_backend *);
+ /**
+ * Unlock the data store backing this backend. If success is
+ * true, the changes should be committed, otherwise rolled
+ * back.
+ */
+ int GIT_CALLBACK(unlock)(struct git_config_backend *, int success);
+ void GIT_CALLBACK(free)(struct git_config_backend *);
+};
+#define GIT_CONFIG_BACKEND_VERSION 1
+#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_config_backend` with default values. Equivalent to
+ * creating an instance with GIT_CONFIG_BACKEND_INIT.
+ *
+ * @param backend the `git_config_backend` struct to initialize.
+ * @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_config_init_backend(
+ git_config_backend *backend,
+ unsigned int version);
+
+/**
+ * Add a generic config file instance to an existing config
+ *
+ * Note that the configuration object will free the file
+ * automatically.
+ *
+ * Further queries on this config object will access each
+ * of the config file instances in order (instances with
+ * a higher priority level will be accessed first).
+ *
+ * @param cfg the configuration to add the file to
+ * @param file the configuration file (backend) to add
+ * @param level the priority level of the backend
+ * @param repo optional repository to allow parsing of
+ * conditional includes
+ * @param force if a config file already exists for the given
+ * priority level, replace it
+ * @return 0 on success, GIT_EEXISTS when adding more than one file
+ * for a given priority level (and force_replace set to 0), or error code
+ */
+GIT_EXTERN(int) git_config_add_backend(
+ git_config *cfg,
+ git_config_backend *file,
+ git_config_level_t level,
+ const git_repository *repo,
+ int force);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/cred.h b/include/git2/sys/cred.h
new file mode 100644
index 0000000..4d2a59a
--- /dev/null
+++ b/include/git2/sys/cred.h
@@ -0,0 +1,15 @@
+/*
+ * 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_sys_git_cred_h__
+#define INCLUDE_sys_git_cred_h__
+
+/* These declarations have moved. */
+#ifndef GIT_DEPRECATE_HARD
+# include "git2/sys/credential.h"
+#endif
+
+#endif
diff --git a/include/git2/sys/credential.h b/include/git2/sys/credential.h
new file mode 100644
index 0000000..bb4c9f9
--- /dev/null
+++ b/include/git2/sys/credential.h
@@ -0,0 +1,90 @@
+/*
+ * 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_sys_git_credential_h__
+#define INCLUDE_sys_git_credential_h__
+
+#include "git2/common.h"
+#include "git2/credential.h"
+
+/**
+ * @file git2/sys/cred.h
+ * @brief Git credentials low-level implementation
+ * @defgroup git_credential Git credentials low-level implementation
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The base structure for all credential types
+ */
+struct git_credential {
+ git_credential_t credtype; /**< A type of credential */
+
+ /** The deallocator for this type of credentials */
+ void GIT_CALLBACK(free)(git_credential *cred);
+};
+
+/** A plaintext username and password */
+struct git_credential_userpass_plaintext {
+ git_credential parent; /**< The parent credential */
+ char *username; /**< The username to authenticate as */
+ char *password; /**< The password to use */
+};
+
+/** Username-only credential information */
+struct git_credential_username {
+ git_credential parent; /**< The parent credential */
+ char username[1]; /**< The username to authenticate as */
+};
+
+/**
+ * A ssh key from disk
+ */
+struct git_credential_ssh_key {
+ git_credential parent; /**< The parent credential */
+ char *username; /**< The username to authenticate as */
+ char *publickey; /**< The path to a public key */
+ char *privatekey; /**< The path to a private key */
+ char *passphrase; /**< Passphrase to decrypt the private key */
+};
+
+/**
+ * Keyboard-interactive based ssh authentication
+ */
+struct git_credential_ssh_interactive {
+ git_credential parent; /**< The parent credential */
+ char *username; /**< The username to authenticate as */
+
+ /**
+ * Callback used for authentication.
+ */
+ git_credential_ssh_interactive_cb prompt_callback;
+
+ void *payload; /**< Payload passed to prompt_callback */
+};
+
+/**
+ * A key with a custom signature function
+ */
+struct git_credential_ssh_custom {
+ git_credential parent; /**< The parent credential */
+ char *username; /**< The username to authenticate as */
+ char *publickey; /**< The public key data */
+ size_t publickey_len; /**< Length of the public key */
+
+ /**
+ * Callback used to sign the data.
+ */
+ git_credential_sign_cb sign_callback;
+
+ void *payload; /**< Payload passed to prompt_callback */
+};
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/diff.h b/include/git2/sys/diff.h
new file mode 100644
index 0000000..aefd7b9
--- /dev/null
+++ b/include/git2/sys/diff.h
@@ -0,0 +1,94 @@
+/*
+ * 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_sys_git_diff_h__
+#define INCLUDE_sys_git_diff_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/diff.h"
+#include "git2/status.h"
+
+/**
+ * @file git2/sys/diff.h
+ * @brief Low-level Git diff utilities
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Diff print callback that writes to a git_buf.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a `git_buf` buffer. You
+ * must pass a `git_buf *` value as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. The data will be appended to the
+ * buffer (after any existing content).
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_buf(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /**< payload must be a `git_buf *` */
+
+/**
+ * Diff print callback that writes to stdio FILE handle.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a stdio FILE handle. You
+ * must pass a `FILE *` value (such as `stdout` or `stderr` or the return
+ * value from `fopen()`) as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. If you pass NULL, this will write
+ * data to `stdout`.
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /**< payload must be a `FILE *` */
+
+
+/**
+ * Performance data from diffing
+ */
+typedef struct {
+ unsigned int version;
+ size_t stat_calls; /**< Number of stat() calls performed */
+ size_t oid_calculations; /**< Number of ID calculations */
+} git_diff_perfdata;
+
+#define GIT_DIFF_PERFDATA_VERSION 1
+#define GIT_DIFF_PERFDATA_INIT {GIT_DIFF_PERFDATA_VERSION,0,0}
+
+/**
+ * Get performance data for a diff object.
+ *
+ * @param out Structure to be filled with diff performance data
+ * @param diff Diff to read performance data from
+ * @return 0 for success, <0 for error
+ */
+GIT_EXTERN(int) git_diff_get_perfdata(
+ git_diff_perfdata *out, const git_diff *diff);
+
+/**
+ * Get performance data for diffs from a git_status_list
+ */
+GIT_EXTERN(int) git_status_list_get_perfdata(
+ git_diff_perfdata *out, const git_status_list *status);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/email.h b/include/git2/sys/email.h
new file mode 100644
index 0000000..6f4a286
--- /dev/null
+++ b/include/git2/sys/email.h
@@ -0,0 +1,45 @@
+/*
+ * 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_sys_git_email_h__
+#define INCLUDE_sys_git_email_h__
+
+/**
+ * @file git2/sys/email.h
+ * @brief Advanced git email creation routines
+ * @defgroup git_email Advanced git email creation routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a diff for a commit in mbox format for sending via email.
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param diff the changes to include in the email
+ * @param patch_idx the patch index
+ * @param patch_count the total number of patches that will be included
+ * @param commit_id the commit id for this change
+ * @param summary the commit message for this change
+ * @param body optional text to include above the diffstat
+ * @param author the person who authored this commit
+ * @param opts email creation options
+ */
+GIT_EXTERN(int) git_email_create_from_diff(
+ git_buf *out,
+ git_diff *diff,
+ size_t patch_idx,
+ size_t patch_count,
+ const git_oid *commit_id,
+ const char *summary,
+ const char *body,
+ const git_signature *author,
+ const git_email_create_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h
new file mode 100644
index 0000000..b375941
--- /dev/null
+++ b/include/git2/sys/filter.h
@@ -0,0 +1,353 @@
+/*
+ * 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_sys_git_filter_h__
+#define INCLUDE_sys_git_filter_h__
+
+#include "git2/filter.h"
+
+/**
+ * @file git2/sys/filter.h
+ * @brief Git filter backend and plugin routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Look up a filter by name
+ *
+ * @param name The name of the filter
+ * @return Pointer to the filter object or NULL if not found
+ */
+GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
+
+#define GIT_FILTER_CRLF "crlf"
+#define GIT_FILTER_IDENT "ident"
+
+/**
+ * This is priority that the internal CRLF filter will be registered with
+ */
+#define GIT_FILTER_CRLF_PRIORITY 0
+
+/**
+ * This is priority that the internal ident filter will be registered with
+ */
+#define GIT_FILTER_IDENT_PRIORITY 100
+
+/**
+ * This is priority to use with a custom filter to imitate a core Git
+ * filter driver, so that it will be run last on checkout and first on
+ * checkin. You do not have to use this, but it helps compatibility.
+ */
+#define GIT_FILTER_DRIVER_PRIORITY 200
+
+/**
+ * Create a new empty filter list
+ *
+ * Normally you won't use this because `git_filter_list_load` will create
+ * the filter list for you, but you can use this in combination with the
+ * `git_filter_lookup` and `git_filter_list_push` functions to assemble
+ * your own chains of filters.
+ */
+GIT_EXTERN(int) git_filter_list_new(
+ git_filter_list **out,
+ git_repository *repo,
+ git_filter_mode_t mode,
+ uint32_t options);
+
+/**
+ * Add a filter to a filter list with the given payload.
+ *
+ * Normally you won't have to do this because the filter list is created
+ * by calling the "check" function on registered filters when the filter
+ * attributes are set, but this does allow more direct manipulation of
+ * filter lists when desired.
+ *
+ * Note that normally the "check" function can set up a payload for the
+ * filter. Using this function, you can either pass in a payload if you
+ * know the expected payload format, or you can pass NULL. Some filters
+ * may fail with a NULL payload. Good luck!
+ */
+GIT_EXTERN(int) git_filter_list_push(
+ git_filter_list *fl, git_filter *filter, void *payload);
+
+/**
+ * Look up how many filters are in the list
+ *
+ * We will attempt to apply all of these filters to any data passed in,
+ * but note that the filter apply action still has the option of skipping
+ * data that is passed in (for example, the CRLF filter will skip data
+ * that appears to be binary).
+ *
+ * @param fl A filter list
+ * @return The number of filters in the list
+ */
+GIT_EXTERN(size_t) git_filter_list_length(const git_filter_list *fl);
+
+/**
+ * A filter source represents a file/blob to be processed
+ */
+typedef struct git_filter_source git_filter_source;
+
+/**
+ * Get the repository that the source data is coming from.
+ */
+GIT_EXTERN(git_repository *) git_filter_source_repo(const git_filter_source *src);
+
+/**
+ * Get the path that the source data is coming from.
+ */
+GIT_EXTERN(const char *) git_filter_source_path(const git_filter_source *src);
+
+/**
+ * Get the file mode of the source file
+ * If the mode is unknown, this will return 0
+ */
+GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
+
+/**
+ * Get the OID of the source
+ * If the OID is unknown (often the case with GIT_FILTER_CLEAN) then
+ * this will return NULL.
+ */
+GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
+
+/**
+ * Get the git_filter_mode_t to be used
+ */
+GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
+
+/**
+ * Get the combination git_filter_flag_t options to be applied
+ */
+GIT_EXTERN(uint32_t) git_filter_source_flags(const git_filter_source *src);
+
+/**
+ * Initialize callback on filter
+ *
+ * Specified as `filter.initialize`, this is an optional callback invoked
+ * before a filter is first used. It will be called once at most.
+ *
+ * If non-NULL, the filter's `initialize` callback will be invoked right
+ * before the first use of the filter, so you can defer expensive
+ * initialization operations (in case libgit2 is being used in a way that
+ * doesn't need the filter).
+ */
+typedef int GIT_CALLBACK(git_filter_init_fn)(git_filter *self);
+
+/**
+ * Shutdown callback on filter
+ *
+ * Specified as `filter.shutdown`, this is an optional callback invoked
+ * when the filter is unregistered or when libgit2 is shutting down. It
+ * will be called once at most and should release resources as needed.
+ * This may be called even if the `initialize` callback was not made.
+ *
+ * Typically this function will free the `git_filter` object itself.
+ */
+typedef void GIT_CALLBACK(git_filter_shutdown_fn)(git_filter *self);
+
+/**
+ * Callback to decide if a given source needs this filter
+ *
+ * Specified as `filter.check`, this is an optional callback that checks
+ * if filtering is needed for a given source.
+ *
+ * It should return 0 if the filter should be applied (i.e. success),
+ * GIT_PASSTHROUGH if the filter should not be applied, or an error code
+ * to fail out of the filter processing pipeline and return to the caller.
+ *
+ * The `attr_values` will be set to the values of any attributes given in
+ * the filter definition. See `git_filter` below for more detail.
+ *
+ * The `payload` will be a pointer to a reference payload for the filter.
+ * This will start as NULL, but `check` can assign to this pointer for
+ * later use by the `stream` callback. Note that the value should be heap
+ * allocated (not stack), so that it doesn't go away before the `stream`
+ * callback can use it. If a filter allocates and assigns a value to the
+ * `payload`, it will need a `cleanup` callback to free the payload.
+ */
+typedef int GIT_CALLBACK(git_filter_check_fn)(
+ git_filter *self,
+ void **payload, /* NULL on entry, may be set */
+ const git_filter_source *src,
+ const char **attr_values);
+
+#ifndef GIT_DEPRECATE_HARD
+/**
+ * Callback to actually perform the data filtering
+ *
+ * Specified as `filter.apply`, this is the callback that actually filters
+ * data. If it successfully writes the output, it should return 0. Like
+ * `check`, it can return GIT_PASSTHROUGH to indicate that the filter
+ * doesn't want to run. Other error codes will stop filter processing and
+ * return to the caller.
+ *
+ * The `payload` value will refer to any payload that was set by the
+ * `check` callback. It may be read from or written to as needed.
+ *
+ * @deprecated use git_filter_stream_fn
+ */
+typedef int GIT_CALLBACK(git_filter_apply_fn)(
+ git_filter *self,
+ void **payload, /* may be read and/or set */
+ git_buf *to,
+ const git_buf *from,
+ const git_filter_source *src);
+#endif
+
+/**
+ * Callback to perform the data filtering.
+ *
+ * Specified as `filter.stream`, this is a callback that filters data
+ * in a streaming manner. This function will provide a
+ * `git_writestream` that will the original data will be written to;
+ * with that data, the `git_writestream` will then perform the filter
+ * translation and stream the filtered data out to the `next` location.
+ */
+typedef int GIT_CALLBACK(git_filter_stream_fn)(
+ git_writestream **out,
+ git_filter *self,
+ void **payload,
+ const git_filter_source *src,
+ git_writestream *next);
+
+/**
+ * Callback to clean up after filtering has been applied
+ *
+ * Specified as `filter.cleanup`, this is an optional callback invoked
+ * after the filter has been applied. If the `check`, `apply`, or
+ * `stream` callbacks allocated a `payload` to keep per-source filter
+ * state, use this callback to free that payload and release resources
+ * as required.
+ */
+typedef void GIT_CALLBACK(git_filter_cleanup_fn)(
+ git_filter *self,
+ void *payload);
+
+/**
+ * Filter structure used to register custom filters.
+ *
+ * To associate extra data with a filter, allocate extra data and put the
+ * `git_filter` struct at the start of your data buffer, then cast the
+ * `self` pointer to your larger structure when your callback is invoked.
+ */
+struct git_filter {
+ /** The `version` field should be set to `GIT_FILTER_VERSION`. */
+ unsigned int version;
+
+ /**
+ * A whitespace-separated list of attribute names to check for this
+ * filter (e.g. "eol crlf text"). If the attribute name is bare, it
+ * will be simply loaded and passed to the `check` callback. If it
+ * has a value (i.e. "name=value"), the attribute must match that
+ * value for the filter to be applied. The value may be a wildcard
+ * (eg, "name=*"), in which case the filter will be invoked for any
+ * value for the given attribute name. See the attribute parameter
+ * of the `check` callback for the attribute value that was specified.
+ */
+ const char *attributes;
+
+ /** Called when the filter is first used for any file. */
+ git_filter_init_fn initialize;
+
+ /** Called when the filter is removed or unregistered from the system. */
+ git_filter_shutdown_fn shutdown;
+
+ /**
+ * Called to determine whether the filter should be invoked for a
+ * given file. If this function returns `GIT_PASSTHROUGH` then the
+ * `stream` or `apply` functions will not be invoked and the
+ * contents will be passed through unmodified.
+ */
+ git_filter_check_fn check;
+
+#ifdef GIT_DEPRECATE_HARD
+ void *reserved;
+#else
+ /**
+ * Provided for backward compatibility; this will apply the
+ * filter to the given contents in a `git_buf`. Callers should
+ * provide a `stream` function instead.
+ */
+ git_filter_apply_fn apply;
+#endif
+
+ /**
+ * Called to apply the filter, this function will provide a
+ * `git_writestream` that will the original data will be
+ * written to; with that data, the `git_writestream` will then
+ * perform the filter translation and stream the filtered data
+ * out to the `next` location.
+ */
+ git_filter_stream_fn stream;
+
+ /** Called when the system is done filtering for a file. */
+ git_filter_cleanup_fn cleanup;
+};
+
+#define GIT_FILTER_VERSION 1
+#define GIT_FILTER_INIT {GIT_FILTER_VERSION}
+
+/**
+ * Initializes a `git_filter` with default values. Equivalent to
+ * creating an instance with GIT_FILTER_INIT.
+ *
+ * @param filter the `git_filter` struct to initialize.
+ * @param version Version the struct; pass `GIT_FILTER_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_filter_init(git_filter *filter, unsigned int version);
+
+/**
+ * Register a filter under a given name with a given priority.
+ *
+ * As mentioned elsewhere, the initialize callback will not be invoked
+ * immediately. It is deferred until the filter is used in some way.
+ *
+ * A filter's attribute checks and `check` and `stream` (or `apply`)
+ * callbacks will be issued in order of `priority` on smudge (to
+ * workdir), and in reverse order of `priority` on clean (to odb).
+ *
+ * Two filters are preregistered with libgit2:
+ * - GIT_FILTER_CRLF with priority 0
+ * - GIT_FILTER_IDENT with priority 100
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name A name by which the filter can be referenced. Attempting
+ * to register with an in-use name will return GIT_EEXISTS.
+ * @param filter The filter definition. This pointer will be stored as is
+ * by libgit2 so it must be a durable allocation (either static
+ * or on the heap).
+ * @param priority The priority for filter application
+ * @return 0 on successful registry, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_register(
+ const char *name, git_filter *filter, int priority);
+
+/**
+ * Remove the filter with the given name
+ *
+ * Attempting to remove the builtin libgit2 filters is not permitted and
+ * will return an error.
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name The name under which the filter was registered
+ * @return 0 on success, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_unregister(const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/hashsig.h b/include/git2/sys/hashsig.h
new file mode 100644
index 0000000..09c19ae
--- /dev/null
+++ b/include/git2/sys/hashsig.h
@@ -0,0 +1,106 @@
+/*
+ * 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_sys_hashsig_h__
+#define INCLUDE_sys_hashsig_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Similarity signature of arbitrary text content based on line hashes
+ */
+typedef struct git_hashsig git_hashsig;
+
+/**
+ * Options for hashsig computation
+ *
+ * The options GIT_HASHSIG_NORMAL, GIT_HASHSIG_IGNORE_WHITESPACE,
+ * GIT_HASHSIG_SMART_WHITESPACE are exclusive and should not be combined.
+ */
+typedef enum {
+ /**
+ * Use all data
+ */
+ GIT_HASHSIG_NORMAL = 0,
+
+ /**
+ * Ignore whitespace
+ */
+ GIT_HASHSIG_IGNORE_WHITESPACE = (1 << 0),
+
+ /**
+ * Ignore \r and all space after \n
+ */
+ GIT_HASHSIG_SMART_WHITESPACE = (1 << 1),
+
+ /**
+ * Allow hashing of small files
+ */
+ GIT_HASHSIG_ALLOW_SMALL_FILES = (1 << 2)
+} git_hashsig_option_t;
+
+/**
+ * Compute a similarity signature for a text buffer
+ *
+ * If you have passed the option GIT_HASHSIG_IGNORE_WHITESPACE, then the
+ * whitespace will be removed from the buffer while it is being processed,
+ * modifying the buffer in place. Sorry about that!
+ *
+ * @param out The computed similarity signature.
+ * @param buf The input buffer.
+ * @param buflen The input buffer size.
+ * @param opts The signature computation options (see above).
+ * @return 0 on success, GIT_EBUFS if the buffer doesn't contain enough data to
+ * compute a valid signature (unless GIT_HASHSIG_ALLOW_SMALL_FILES is set), or
+ * error code.
+ */
+GIT_EXTERN(int) git_hashsig_create(
+ git_hashsig **out,
+ const char *buf,
+ size_t buflen,
+ git_hashsig_option_t opts);
+
+/**
+ * Compute a similarity signature for a text file
+ *
+ * This walks through the file, only loading a maximum of 4K of file data at
+ * a time. Otherwise, it acts just like `git_hashsig_create`.
+ *
+ * @param out The computed similarity signature.
+ * @param path The path to the input file.
+ * @param opts The signature computation options (see above).
+ * @return 0 on success, GIT_EBUFS if the buffer doesn't contain enough data to
+ * compute a valid signature (unless GIT_HASHSIG_ALLOW_SMALL_FILES is set), or
+ * error code.
+ */
+GIT_EXTERN(int) git_hashsig_create_fromfile(
+ git_hashsig **out,
+ const char *path,
+ git_hashsig_option_t opts);
+
+/**
+ * Release memory for a content similarity signature
+ *
+ * @param sig The similarity signature to free.
+ */
+GIT_EXTERN(void) git_hashsig_free(git_hashsig *sig);
+
+/**
+ * Measure similarity score between two similarity signatures
+ *
+ * @param a The first similarity signature to compare.
+ * @param b The second similarity signature to compare.
+ * @return [0 to 100] on success as the similarity score, or error code.
+ */
+GIT_EXTERN(int) git_hashsig_compare(
+ const git_hashsig *a,
+ const git_hashsig *b);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/index.h b/include/git2/sys/index.h
new file mode 100644
index 0000000..1f6d93f
--- /dev/null
+++ b/include/git2/sys/index.h
@@ -0,0 +1,182 @@
+/*
+ * 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_sys_git_index_h__
+#define INCLUDE_sys_git_index_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/index.h
+ * @brief Low-level Git index manipulation routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Representation of a rename conflict entry in the index. */
+typedef struct git_index_name_entry {
+ char *ancestor;
+ char *ours;
+ char *theirs;
+} git_index_name_entry;
+
+/** Representation of a resolve undo entry in the index. */
+typedef struct git_index_reuc_entry {
+ uint32_t mode[3];
+ git_oid oid[3];
+ char *path;
+} git_index_reuc_entry;
+
+/** @name Conflict Name entry functions
+ *
+ * These functions work on rename conflict entries.
+ */
+/**@{*/
+
+/**
+ * Get the count of filename conflict entries currently in the index.
+ *
+ * @param index an existing index object
+ * @return integer of count of current filename conflict entries
+ */
+GIT_EXTERN(size_t) git_index_name_entrycount(git_index *index);
+
+/**
+ * Get a filename conflict entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the filename conflict entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_name_entry *) git_index_name_get_byindex(
+ git_index *index, size_t n);
+
+/**
+ * Record the filenames involved in a rename conflict.
+ *
+ * @param index an existing index object
+ * @param ancestor the path of the file as it existed in the ancestor
+ * @param ours the path of the file as it existed in our tree
+ * @param theirs the path of the file as it existed in their tree
+ */
+GIT_EXTERN(int) git_index_name_add(git_index *index,
+ const char *ancestor, const char *ours, const char *theirs);
+
+/**
+ * Remove all filename conflict entries.
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_name_clear(git_index *index);
+
+/**@}*/
+
+/** @name Resolve Undo (REUC) index entry manipulation.
+ *
+ * These functions work on the Resolve Undo index extension and contains
+ * data about the original files that led to a merge conflict.
+ */
+/**@{*/
+
+/**
+ * Get the count of resolve undo entries currently in the index.
+ *
+ * @param index an existing index object
+ * @return integer of count of current resolve undo entries
+ */
+GIT_EXTERN(size_t) git_index_reuc_entrycount(git_index *index);
+
+/**
+ * Finds the resolve undo entry that points to the given path in the Git
+ * index.
+ *
+ * @param at_pos the address to which the position of the reuc entry is written (optional)
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 if found, < 0 otherwise (GIT_ENOTFOUND)
+ */
+GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path);
+
+/**
+ * Get a resolve undo entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @return the resolve undo entry; NULL if not found
+ */
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path);
+
+/**
+ * Get a resolve undo entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the resolve undo entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n);
+
+/**
+ * Adds a resolve undo entry for a file based on the given parameters.
+ *
+ * The resolve undo entry contains the OIDs of files that were involved
+ * in a merge conflict after the conflict has been resolved. This allows
+ * conflicts to be re-resolved later.
+ *
+ * If there exists a resolve undo entry for the given path in the index,
+ * it will be removed.
+ *
+ * This method will fail in bare index instances.
+ *
+ * @param index an existing index object
+ * @param path filename to add
+ * @param ancestor_mode mode of the ancestor file
+ * @param ancestor_id oid of the ancestor file
+ * @param our_mode mode of our file
+ * @param our_id oid of our file
+ * @param their_mode mode of their file
+ * @param their_id oid of their file
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path,
+ int ancestor_mode, const git_oid *ancestor_id,
+ int our_mode, const git_oid *our_id,
+ int their_mode, const git_oid *their_id);
+
+/**
+ * Remove an resolve undo entry from the index
+ *
+ * @param index an existing index object
+ * @param n position of the resolve undo entry to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n);
+
+/**
+ * Remove all resolve undo entries from the index
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_reuc_clear(git_index *index);
+
+/**@}*/
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/mempack.h b/include/git2/sys/mempack.h
new file mode 100644
index 0000000..17da590
--- /dev/null
+++ b/include/git2/sys/mempack.h
@@ -0,0 +1,87 @@
+/*
+ * 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_sys_git_odb_mempack_h__
+#define INCLUDE_sys_git_odb_mempack_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+#include "git2/buffer.h"
+
+/**
+ * @file git2/sys/mempack.h
+ * @brief Custom ODB backend that permits packing objects in-memory
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Instantiate a new mempack backend.
+ *
+ * The backend must be added to an existing ODB with the highest
+ * priority.
+ *
+ * git_mempack_new(&mempacker);
+ * git_repository_odb(&odb, repository);
+ * git_odb_add_backend(odb, mempacker, 999);
+ *
+ * Once the backend has been loaded, all writes to the ODB will
+ * instead be queued in memory, and can be finalized with
+ * `git_mempack_dump`.
+ *
+ * Subsequent reads will also be served from the in-memory store
+ * to ensure consistency, until the memory store is dumped.
+ *
+ * @param out Pointer where to store the ODB backend
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_mempack_new(git_odb_backend **out);
+
+/**
+ * Dump all the queued in-memory writes to a packfile.
+ *
+ * The contents of the packfile will be stored in the given buffer.
+ * It is the caller's responsibility to ensure that the generated
+ * packfile is available to the repository (e.g. by writing it
+ * to disk, or doing something crazy like distributing it across
+ * several copies of the repository over a network).
+ *
+ * Once the generated packfile is available to the repository,
+ * call `git_mempack_reset` to cleanup the memory store.
+ *
+ * Calling `git_mempack_reset` before the packfile has been
+ * written to disk will result in an inconsistent repository
+ * (the objects in the memory store won't be accessible).
+ *
+ * @param pack Buffer where to store the raw packfile
+ * @param repo The active repository where the backend is loaded
+ * @param backend The mempack backend
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backend);
+
+/**
+ * Reset the memory packer by clearing all the queued objects.
+ *
+ * This assumes that `git_mempack_dump` has been called before to
+ * store all the queued objects into a single packfile.
+ *
+ * Alternatively, call `reset` without a previous dump to "undo"
+ * all the recently written objects, giving transaction-like
+ * semantics to the Git repository.
+ *
+ * @param backend The mempack backend
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_mempack_reset(git_odb_backend *backend);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/merge.h b/include/git2/sys/merge.h
new file mode 100644
index 0000000..ef4bc5a
--- /dev/null
+++ b/include/git2/sys/merge.h
@@ -0,0 +1,182 @@
+/*
+ * 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_sys_git_merge_h__
+#define INCLUDE_sys_git_merge_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/index.h"
+#include "git2/merge.h"
+
+/**
+ * @file git2/sys/merge.h
+ * @brief Git merge driver backend and plugin routines
+ * @defgroup git_merge Git merge driver APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef struct git_merge_driver git_merge_driver;
+
+/**
+ * Look up a merge driver by name
+ *
+ * @param name The name of the merge driver
+ * @return Pointer to the merge driver object or NULL if not found
+ */
+GIT_EXTERN(git_merge_driver *) git_merge_driver_lookup(const char *name);
+
+#define GIT_MERGE_DRIVER_TEXT "text"
+#define GIT_MERGE_DRIVER_BINARY "binary"
+#define GIT_MERGE_DRIVER_UNION "union"
+
+/**
+ * A merge driver source represents the file to be merged
+ */
+typedef struct git_merge_driver_source git_merge_driver_source;
+
+/** Get the repository that the source data is coming from. */
+GIT_EXTERN(git_repository *) git_merge_driver_source_repo(
+ const git_merge_driver_source *src);
+
+/** Gets the ancestor of the file to merge. */
+GIT_EXTERN(const git_index_entry *) git_merge_driver_source_ancestor(
+ const git_merge_driver_source *src);
+
+/** Gets the ours side of the file to merge. */
+GIT_EXTERN(const git_index_entry *) git_merge_driver_source_ours(
+ const git_merge_driver_source *src);
+
+/** Gets the theirs side of the file to merge. */
+GIT_EXTERN(const git_index_entry *) git_merge_driver_source_theirs(
+ const git_merge_driver_source *src);
+
+/** Gets the merge file options that the merge was invoked with */
+GIT_EXTERN(const git_merge_file_options *) git_merge_driver_source_file_options(
+ const git_merge_driver_source *src);
+
+
+/**
+ * Initialize callback on merge driver
+ *
+ * Specified as `driver.initialize`, this is an optional callback invoked
+ * before a merge driver is first used. It will be called once at most
+ * per library lifetime.
+ *
+ * If non-NULL, the merge driver's `initialize` callback will be invoked
+ * right before the first use of the driver, so you can defer expensive
+ * initialization operations (in case libgit2 is being used in a way that
+ * doesn't need the merge driver).
+ */
+typedef int GIT_CALLBACK(git_merge_driver_init_fn)(git_merge_driver *self);
+
+/**
+ * Shutdown callback on merge driver
+ *
+ * Specified as `driver.shutdown`, this is an optional callback invoked
+ * when the merge driver is unregistered or when libgit2 is shutting down.
+ * It will be called once at most and should release resources as needed.
+ * This may be called even if the `initialize` callback was not made.
+ *
+ * Typically this function will free the `git_merge_driver` object itself.
+ */
+typedef void GIT_CALLBACK(git_merge_driver_shutdown_fn)(git_merge_driver *self);
+
+/**
+ * Callback to perform the merge.
+ *
+ * Specified as `driver.apply`, this is the callback that actually does the
+ * merge. If it can successfully perform a merge, it should populate
+ * `path_out` with a pointer to the filename to accept, `mode_out` with
+ * the resultant mode, and `merged_out` with the buffer of the merged file
+ * and then return 0. If the driver returns `GIT_PASSTHROUGH`, then the
+ * default merge driver should instead be run. It can also return
+ * `GIT_EMERGECONFLICT` if the driver is not able to produce a merge result,
+ * and the file will remain conflicted. Any other errors will fail and
+ * return to the caller.
+ *
+ * The `filter_name` contains the name of the filter that was invoked, as
+ * specified by the file's attributes.
+ *
+ * The `src` contains the data about the file to be merged.
+ */
+typedef int GIT_CALLBACK(git_merge_driver_apply_fn)(
+ git_merge_driver *self,
+ const char **path_out,
+ uint32_t *mode_out,
+ git_buf *merged_out,
+ const char *filter_name,
+ const git_merge_driver_source *src);
+
+/**
+ * Merge driver structure used to register custom merge drivers.
+ *
+ * To associate extra data with a driver, allocate extra data and put the
+ * `git_merge_driver` struct at the start of your data buffer, then cast
+ * the `self` pointer to your larger structure when your callback is invoked.
+ */
+struct git_merge_driver {
+ /** The `version` should be set to `GIT_MERGE_DRIVER_VERSION`. */
+ unsigned int version;
+
+ /** Called when the merge driver is first used for any file. */
+ git_merge_driver_init_fn initialize;
+
+ /** Called when the merge driver is unregistered from the system. */
+ git_merge_driver_shutdown_fn shutdown;
+
+ /**
+ * Called to merge the contents of a conflict. If this function
+ * returns `GIT_PASSTHROUGH` then the default (`text`) merge driver
+ * will instead be invoked. If this function returns
+ * `GIT_EMERGECONFLICT` then the file will remain conflicted.
+ */
+ git_merge_driver_apply_fn apply;
+};
+
+#define GIT_MERGE_DRIVER_VERSION 1
+
+/**
+ * Register a merge driver under a given name.
+ *
+ * As mentioned elsewhere, the initialize callback will not be invoked
+ * immediately. It is deferred until the driver is used in some way.
+ *
+ * Currently the merge driver registry is not thread safe, so any
+ * registering or deregistering of merge drivers must be done outside of
+ * any possible usage of the drivers (i.e. during application setup or
+ * shutdown).
+ *
+ * @param name The name of this driver to match an attribute. Attempting
+ * to register with an in-use name will return GIT_EEXISTS.
+ * @param driver The merge driver definition. This pointer will be stored
+ * as is by libgit2 so it must be a durable allocation (either
+ * static or on the heap).
+ * @return 0 on successful registry, error code <0 on failure
+ */
+GIT_EXTERN(int) git_merge_driver_register(
+ const char *name, git_merge_driver *driver);
+
+/**
+ * Remove the merge driver with the given name.
+ *
+ * Attempting to remove the builtin libgit2 merge drivers is not permitted
+ * and will return an error.
+ *
+ * Currently the merge driver registry is not thread safe, so any
+ * registering or deregistering of drivers must be done outside of any
+ * possible usage of the drivers (i.e. during application setup or shutdown).
+ *
+ * @param name The name under which the merge driver was registered
+ * @return 0 on success, error code <0 on failure
+ */
+GIT_EXTERN(int) git_merge_driver_unregister(const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/midx.h b/include/git2/sys/midx.h
new file mode 100644
index 0000000..3a87484
--- /dev/null
+++ b/include/git2/sys/midx.h
@@ -0,0 +1,78 @@
+/*
+ * 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_sys_git_midx_h__
+#define INCLUDE_sys_git_midx_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/midx.h
+ * @brief Git multi-pack-index routines
+ * @defgroup git_midx Git multi-pack-index routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new writer for `multi-pack-index` files.
+ *
+ * @param out location to store the writer pointer.
+ * @param pack_dir the directory where the `.pack` and `.idx` files are. The
+ * `multi-pack-index` file will be written in this directory, too.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_midx_writer_new(
+ git_midx_writer **out,
+ const char *pack_dir
+#ifdef GIT_EXPERIMENTAL_SHA256
+ , git_oid_t oid_type
+#endif
+ );
+
+/**
+ * Free the multi-pack-index writer and its resources.
+ *
+ * @param w the writer to free. If NULL no action is taken.
+ */
+GIT_EXTERN(void) git_midx_writer_free(git_midx_writer *w);
+
+/**
+ * Add an `.idx` file to the writer.
+ *
+ * @param w the writer
+ * @param idx_path the path of an `.idx` file.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_midx_writer_add(
+ git_midx_writer *w,
+ const char *idx_path);
+
+/**
+ * Write a `multi-pack-index` file to a file.
+ *
+ * @param w the writer
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_midx_writer_commit(
+ git_midx_writer *w);
+
+/**
+ * Dump the contents of the `multi-pack-index` to an in-memory buffer.
+ *
+ * @param midx Buffer where to store the contents of the `multi-pack-index`.
+ * @param w the writer
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_midx_writer_dump(
+ git_buf *midx,
+ git_midx_writer *w);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h
new file mode 100644
index 0000000..c42abd3
--- /dev/null
+++ b/include/git2/sys/odb_backend.h
@@ -0,0 +1,172 @@
+/*
+ * 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_sys_git_odb_backend_h__
+#define INCLUDE_sys_git_odb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+/**
+ * @file git2/sys/backend.h
+ * @brief Git custom backend implementors functions
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * An instance for a custom backend
+ */
+struct git_odb_backend {
+ unsigned int version;
+ git_odb *odb;
+
+ /* read and read_prefix each return to libgit2 a buffer which
+ * will be freed later. The buffer should be allocated using
+ * the function git_odb_backend_data_alloc to ensure that libgit2
+ * can safely free it later. */
+ int GIT_CALLBACK(read)(
+ void **, size_t *, git_object_t *, git_odb_backend *, const git_oid *);
+
+ /* To find a unique object given a prefix of its oid. The oid given
+ * must be so that the remaining (GIT_OID_SHA1_HEXSIZE - len)*4 bits are 0s.
+ */
+ int GIT_CALLBACK(read_prefix)(
+ git_oid *, void **, size_t *, git_object_t *,
+ git_odb_backend *, const git_oid *, size_t);
+
+ int GIT_CALLBACK(read_header)(
+ size_t *, git_object_t *, git_odb_backend *, const git_oid *);
+
+ /**
+ * Write an object into the backend. The id of the object has
+ * already been calculated and is passed in.
+ */
+ int GIT_CALLBACK(write)(
+ git_odb_backend *, const git_oid *, const void *, size_t, git_object_t);
+
+ int GIT_CALLBACK(writestream)(
+ git_odb_stream **, git_odb_backend *, git_object_size_t, git_object_t);
+
+ int GIT_CALLBACK(readstream)(
+ git_odb_stream **, size_t *, git_object_t *,
+ git_odb_backend *, const git_oid *);
+
+ int GIT_CALLBACK(exists)(
+ git_odb_backend *, const git_oid *);
+
+ int GIT_CALLBACK(exists_prefix)(
+ git_oid *, git_odb_backend *, const git_oid *, size_t);
+
+ /**
+ * If the backend implements a refreshing mechanism, it should be exposed
+ * through this endpoint. Each call to `git_odb_refresh()` will invoke it.
+ *
+ * The odb layer will automatically call this when needed on failed
+ * lookups (ie. `exists()`, `read()`, `read_header()`).
+ */
+ int GIT_CALLBACK(refresh)(git_odb_backend *);
+
+ int GIT_CALLBACK(foreach)(
+ git_odb_backend *, git_odb_foreach_cb cb, void *payload);
+
+ int GIT_CALLBACK(writepack)(
+ git_odb_writepack **, git_odb_backend *, git_odb *odb,
+ git_indexer_progress_cb progress_cb, void *progress_payload);
+
+ /**
+ * If the backend supports pack files, this will create a
+ * `multi-pack-index` file which will contain an index of all objects
+ * across all the `.pack` files.
+ */
+ int GIT_CALLBACK(writemidx)(git_odb_backend *);
+
+ /**
+ * "Freshens" an already existing object, updating its last-used
+ * time. This occurs when `git_odb_write` was called, but the
+ * object already existed (and will not be re-written). The
+ * underlying implementation may want to update last-used timestamps.
+ *
+ * If callers implement this, they should return `0` if the object
+ * exists and was freshened, and non-zero otherwise.
+ */
+ int GIT_CALLBACK(freshen)(git_odb_backend *, const git_oid *);
+
+ /**
+ * Frees any resources held by the odb (including the `git_odb_backend`
+ * itself). An odb backend implementation must provide this function.
+ */
+ void GIT_CALLBACK(free)(git_odb_backend *);
+};
+
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_odb_backend` with default values. Equivalent to
+ * creating an instance with GIT_ODB_BACKEND_INIT.
+ *
+ * @param backend the `git_odb_backend` struct to initialize.
+ * @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_odb_init_backend(
+ git_odb_backend *backend,
+ unsigned int version);
+
+/**
+ * Allocate data for an ODB object. Custom ODB backends may use this
+ * to provide data back to the ODB from their read function. This
+ * memory should not be freed once it is returned to libgit2. If a
+ * custom ODB uses this function but encounters an error and does not
+ * return this data to libgit2, then they should use the corresponding
+ * git_odb_backend_data_free function.
+ *
+ * @param backend the ODB backend that is allocating this memory
+ * @param len the number of bytes to allocate
+ * @return the allocated buffer on success or NULL if out of memory
+ */
+GIT_EXTERN(void *) git_odb_backend_data_alloc(git_odb_backend *backend, size_t len);
+
+/**
+ * Frees custom allocated ODB data. This should only be called when
+ * memory allocated using git_odb_backend_data_alloc is not returned
+ * to libgit2 because the backend encountered an error in the read
+ * function after allocation and did not return this data to libgit2.
+ *
+ * @param backend the ODB backend that is freeing this memory
+ * @param data the buffer to free
+ */
+GIT_EXTERN(void) git_odb_backend_data_free(git_odb_backend *backend, void *data);
+
+
+/*
+ * Users can avoid deprecated functions by defining `GIT_DEPRECATE_HARD`.
+ */
+#ifndef GIT_DEPRECATE_HARD
+
+/**
+ * Allocate memory for an ODB object from a custom backend. This is
+ * an alias of `git_odb_backend_data_alloc` and is preserved for
+ * backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated git_odb_backend_data_alloc
+ * @see git_odb_backend_data_alloc
+ */
+GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
+
+#endif
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/openssl.h b/include/git2/sys/openssl.h
new file mode 100644
index 0000000..b41c55c
--- /dev/null
+++ b/include/git2/sys/openssl.h
@@ -0,0 +1,38 @@
+/*
+ * 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_openssl_h__
+#define INCLUDE_git_openssl_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Initialize the OpenSSL locks
+ *
+ * OpenSSL requires the application to determine how it performs
+ * locking.
+ *
+ * This is a last-resort convenience function which libgit2 provides for
+ * allocating and initializing the locks as well as setting the
+ * locking function to use the system's native locking functions.
+ *
+ * The locking function will be cleared and the memory will be freed
+ * when you call git_threads_sutdown().
+ *
+ * If your programming language has an OpenSSL package/bindings, it
+ * likely sets up locking. You should very strongly prefer that over
+ * this function.
+ *
+ * @return 0 on success, -1 if there are errors or if libgit2 was not
+ * built with OpenSSL and threading support.
+ */
+GIT_EXTERN(int) git_openssl_set_locking(void);
+
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/sys/path.h b/include/git2/sys/path.h
new file mode 100644
index 0000000..2a0c7e0
--- /dev/null
+++ b/include/git2/sys/path.h
@@ -0,0 +1,64 @@
+/*
+ * 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_sys_git_path_h__
+#define INCLUDE_sys_git_path_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * The kinds of git-specific files we know about.
+ *
+ * The order needs to stay the same to not break the `gitfiles`
+ * array in path.c
+ */
+typedef enum {
+ /** Check for the .gitignore file */
+ GIT_PATH_GITFILE_GITIGNORE,
+ /** Check for the .gitmodules file */
+ GIT_PATH_GITFILE_GITMODULES,
+ /** Check for the .gitattributes file */
+ GIT_PATH_GITFILE_GITATTRIBUTES
+} git_path_gitfile;
+
+/**
+ * The kinds of checks to perform according to which filesystem we are trying to
+ * protect.
+ */
+typedef enum {
+ /** Do both NTFS- and HFS-specific checks */
+ GIT_PATH_FS_GENERIC,
+ /** Do NTFS-specific checks only */
+ GIT_PATH_FS_NTFS,
+ /** Do HFS-specific checks only */
+ GIT_PATH_FS_HFS
+} git_path_fs;
+
+/**
+ * Check whether a path component corresponds to a .git$SUFFIX
+ * file.
+ *
+ * As some filesystems do special things to filenames when
+ * writing files to disk, you cannot always do a plain string
+ * comparison to verify whether a file name matches an expected
+ * path or not. This function can do the comparison for you,
+ * depending on the filesystem you're on.
+ *
+ * @param path the path component to check
+ * @param pathlen the length of `path` that is to be checked
+ * @param gitfile which file to check against
+ * @param fs which filesystem-specific checks to use
+ * @return 0 in case the file does not match, a positive value if
+ * it does; -1 in case of an error
+ */
+GIT_EXTERN(int) git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs);
+
+GIT_END_DECL
+
+#endif /* INCLUDE_sys_git_path */
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
new file mode 100644
index 0000000..c31e26d
--- /dev/null
+++ b/include/git2/sys/refdb_backend.h
@@ -0,0 +1,361 @@
+/*
+ * 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_sys_git_refdb_backend_h__
+#define INCLUDE_sys_git_refdb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/refdb_backend.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb_backend Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+
+/**
+ * Every backend's iterator must have a pointer to itself as the first
+ * element, so the API can talk to it. You'd define your iterator as
+ *
+ * struct my_iterator {
+ * git_reference_iterator parent;
+ * ...
+ * }
+ *
+ * and assign `iter->parent.backend` to your `git_refdb_backend`.
+ */
+struct git_reference_iterator {
+ git_refdb *db;
+
+ /**
+ * Return the current reference and advance the iterator.
+ */
+ int GIT_CALLBACK(next)(
+ git_reference **ref,
+ git_reference_iterator *iter);
+
+ /**
+ * Return the name of the current reference and advance the iterator
+ */
+ int GIT_CALLBACK(next_name)(
+ const char **ref_name,
+ git_reference_iterator *iter);
+
+ /**
+ * Free the iterator
+ */
+ void GIT_CALLBACK(free)(
+ git_reference_iterator *iter);
+};
+
+/** An instance for a custom backend */
+struct git_refdb_backend {
+ unsigned int version; /**< The backend API version */
+
+ /**
+ * Queries the refdb backend for the existence of a reference.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg exists The implementation shall set this to `0` if a ref does
+ * not exist, otherwise to `1`.
+ * @arg ref_name The reference's name that should be checked for
+ * existence.
+ * @return `0` on success, a negative error value code.
+ */
+ int GIT_CALLBACK(exists)(
+ int *exists,
+ git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Queries the refdb backend for a given reference.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the allocated
+ * reference, if it could be found, otherwise to `NULL`.
+ * @arg ref_name The reference's name that should be checked for
+ * existence.
+ * @return `0` on success, `GIT_ENOTFOUND` if the reference does
+ * exist, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(lookup)(
+ git_reference **out,
+ git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Allocate an iterator object for the backend.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the allocated
+ * reference iterator. A custom structure may be used with an
+ * embedded `git_reference_iterator` structure. Both `next`
+ * and `next_name` functions of `git_reference_iterator` need
+ * to be populated.
+ * @arg glob A pattern to filter references by. If given, the iterator
+ * shall only return references that match the glob when
+ * passed to `wildmatch`.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(iterator)(
+ git_reference_iterator **iter,
+ struct git_refdb_backend *backend,
+ const char *glob);
+
+ /**
+ * Writes the given reference to the refdb.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg ref The reference to persist. May either be a symbolic or
+ * direct reference.
+ * @arg force Whether to write the reference if a reference with the
+ * same name already exists.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry.
+ * @arg old If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the reference is currently at
+ * the given OID before writing the new value. If both `old`
+ * and `old_target` are `NULL`, then the reference should not
+ * exist at the point of writing.
+ * @arg old_target If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the symbolic
+ * reference is currently at the given target before
+ * writing the new value. If both `old` and
+ * `old_target` are `NULL`, then the reference should
+ * not exist at the point of writing.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(write)(git_refdb_backend *backend,
+ const git_reference *ref, int force,
+ const git_signature *who, const char *message,
+ const git_oid *old, const char *old_target);
+
+ /**
+ * Rename a reference in the refdb.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg out The implementation shall set this to the newly created
+ * reference or `NULL` on error.
+ * @arg old_name The current name of the reference that is to be renamed.
+ * @arg new_name The new name that the old reference shall be renamed to.
+ * @arg force Whether to write the reference if a reference with the
+ * target name already exists.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(rename)(
+ git_reference **out, git_refdb_backend *backend,
+ const char *old_name, const char *new_name, int force,
+ const git_signature *who, const char *message);
+
+ /**
+ * Deletes the given reference from the refdb.
+ *
+ * If it exists, its reflog should be deleted as well.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg ref_name The name of the reference name that shall be deleted.
+ * @arg old_id If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the reference is currently at
+ * the given OID before writing the new value.
+ * @arg old_target If not `NULL` and `force` is not set, then the
+ * implementation needs to ensure that the symbolic
+ * reference is currently at the given target before
+ * writing the new value.
+ * @return `0` on success, otherwise a negative error code.
+ */
+ int GIT_CALLBACK(del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
+
+ /**
+ * Suggests that the given refdb compress or optimize its references.
+ *
+ * This mechanism is implementation specific. For on-disk reference
+ * databases, this may pack all loose references.
+ *
+ * A refdb implementation may provide this function; if it is not
+ * provided, nothing will be done.
+ *
+ * @return `0` on success a negative error code otherwise
+ */
+ int GIT_CALLBACK(compress)(git_refdb_backend *backend);
+
+ /**
+ * Query whether a particular reference has a log (may be empty)
+ *
+ * Shall return 1 if it has a reflog, 0 it it doesn't and negative in
+ * case an error occurred.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, `1` if the reflog for the given reference
+ * exists, a negative error code otherwise
+ */
+ int GIT_CALLBACK(has_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Make sure a particular reference will have a reflog which
+ * will be appended to on writes.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(ensure_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Frees any resources held by the refdb (including the `git_refdb_backend`
+ * itself).
+ *
+ * A refdb backend implementation must provide this function.
+ */
+ void GIT_CALLBACK(free)(git_refdb_backend *backend);
+
+ /**
+ * Read the reflog for the given reference name.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
+
+ /**
+ * Write a reflog to disk.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg reflog The complete reference log for a given reference. Note
+ * that this may contain entries that have already been
+ * written to disk.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
+
+ /**
+ * Rename a reflog.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg old_name The name of old reference whose reflog shall be renamed from.
+ * @arg new_name The name of new reference whose reflog shall be renamed to.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
+
+ /**
+ * Remove a reflog.
+ *
+ * A refdb implementation must provide this function.
+ *
+ * @arg name The name of the reference whose reflog shall be deleted.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(reflog_delete)(git_refdb_backend *backend, const char *name);
+
+ /**
+ * Lock a reference.
+ *
+ * A refdb implementation may provide this function; if it is not
+ * provided, the transaction API will fail to work.
+ *
+ * @arg payload_out Opaque parameter that will be passed verbosely to
+ * `unlock`.
+ * @arg refname Reference that shall be locked.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(lock)(void **payload_out, git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Unlock a reference.
+ *
+ * Only one of target or symbolic_target will be set.
+ * `success` will be true if the reference should be update, false if
+ * the lock must be discarded.
+ *
+ * A refdb implementation must provide this function if a `lock`
+ * implementation is provided.
+ *
+ * @arg payload The payload returned by `lock`.
+ * @arg success `1` if a reference should be updated, `2` if
+ * a reference should be deleted, `0` if the lock must be
+ * discarded.
+ * @arg update_reflog `1` in case the reflog should be updated, `0`
+ * otherwise.
+ * @arg ref The reference which should be unlocked.
+ * @arg who The person updating the reference. Shall be used to create
+ * a reflog entry in case `update_reflog` is set.
+ * @arg message The message detailing what kind of reference update is
+ * performed. Shall be used to create a reflog entry in
+ * case `update_reflog` is set.
+ * @return `0` on success, a negative error code otherwise
+ */
+ int GIT_CALLBACK(unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog,
+ const git_reference *ref, const git_signature *sig, const char *message);
+};
+
+#define GIT_REFDB_BACKEND_VERSION 1
+#define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_refdb_backend` with default values. Equivalent to
+ * creating an instance with GIT_REFDB_BACKEND_INIT.
+ *
+ * @param backend the `git_refdb_backend` struct to initialize
+ * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_refdb_init_backend(
+ git_refdb_backend *backend,
+ unsigned int version);
+
+/**
+ * Constructors for default filesystem-based refdb backend
+ *
+ * Under normal usage, this is called for you when the repository is
+ * opened / created, but you can use this to explicitly construct a
+ * filesystem refdb backend for a repository.
+ *
+ * @param backend_out Output pointer to the git_refdb_backend object
+ * @param repo Git repository to access
+ * @return 0 on success, <0 error code on failure
+ */
+GIT_EXTERN(int) git_refdb_backend_fs(
+ git_refdb_backend **backend_out,
+ git_repository *repo);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * The `git_refdb` will take ownership of the `git_refdb_backend` so you
+ * should NOT free it after calling this function.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_refdb_set_backend(
+ git_refdb *refdb,
+ git_refdb_backend *backend);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/reflog.h b/include/git2/sys/reflog.h
new file mode 100644
index 0000000..c9d0041
--- /dev/null
+++ b/include/git2/sys/reflog.h
@@ -0,0 +1,21 @@
+/*
+ * 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_sys_git_reflog_h__
+#define INCLUDE_sys_git_reflog_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+GIT_BEGIN_DECL
+
+GIT_EXTERN(git_reflog_entry *) git_reflog_entry__alloc(void);
+GIT_EXTERN(void) git_reflog_entry__free(git_reflog_entry *entry);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/refs.h b/include/git2/sys/refs.h
new file mode 100644
index 0000000..d2ce2e0
--- /dev/null
+++ b/include/git2/sys/refs.h
@@ -0,0 +1,49 @@
+/*
+ * 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_sys_git_refdb_h__
+#define INCLUDE_sys_git_refdb_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/refs.h
+ * @brief Low-level Git ref creation
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new direct reference from an OID.
+ *
+ * @param name the reference name
+ * @param oid the object id for a direct reference
+ * @param peel the first non-tag object's OID, or NULL
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc(
+ const char *name,
+ const git_oid *oid,
+ const git_oid *peel);
+
+/**
+ * Create a new symbolic reference.
+ *
+ * @param name the reference name
+ * @param target the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
+ const char *name,
+ const char *target);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/remote.h b/include/git2/sys/remote.h
new file mode 100644
index 0000000..0eae923
--- /dev/null
+++ b/include/git2/sys/remote.h
@@ -0,0 +1,46 @@
+/*
+ * 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_sys_git_remote_h
+#define INCLUDE_sys_git_remote_h
+
+#include "git2/remote.h"
+
+/**
+ * @file git2/sys/remote.h
+ * @brief Low-level remote functionality for custom transports
+ * @defgroup git_remote Low-level remote functionality
+ * @ingroup Git
+ * @{
+*/
+
+GIT_BEGIN_DECL
+
+typedef enum {
+ /** Remote supports fetching an advertised object by ID. */
+ GIT_REMOTE_CAPABILITY_TIP_OID = (1 << 0),
+
+ /** Remote supports fetching an individual reachable object. */
+ GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1),
+} git_remote_capability_t;
+
+/**
+ * Disposes libgit2-initialized fields from a git_remote_connect_options.
+ * This should only be used for git_remote_connect_options returned by
+ * git_transport_remote_connect_options.
+ *
+ * Note that this does not free the `git_remote_connect_options` itself, just
+ * the memory pointed to by it.
+ *
+ * @param opts The `git_remote_connect_options` struct to dispose.
+ */
+GIT_EXTERN(void) git_remote_connect_options_dispose(
+ git_remote_connect_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h
new file mode 100644
index 0000000..892be66
--- /dev/null
+++ b/include/git2/sys/repository.h
@@ -0,0 +1,180 @@
+/*
+ * 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_sys_git_repository_h__
+#define INCLUDE_sys_git_repository_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/repository.h
+ * @brief Git repository custom implementation routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new repository with neither backends nor config object
+ *
+ * Note that this is only useful if you wish to associate the repository
+ * with a non-filesystem-backed object database and config store.
+ *
+ * Caveats: since this repository has no physical location, some systems
+ * can fail to function properly: locations under $GIT_DIR, $GIT_COMMON_DIR,
+ * or $GIT_INFO_DIR are impacted.
+ *
+ * @param out The blank repository
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_new(git_repository **out);
+
+/**
+ * Reset all the internal state in a repository.
+ *
+ * This will free all the mapped memory and internal objects
+ * of the repository and leave it in a "blank" state.
+ *
+ * There's no need to call this function directly unless you're
+ * trying to aggressively cleanup the repo before its
+ * deallocation. `git_repository_free` already performs this operation
+ * before deallocating the repo.
+ *
+ * @param repo The repository to clean up
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository__cleanup(git_repository *repo);
+
+/**
+ * Update the filesystem config settings for an open repository
+ *
+ * When a repository is initialized, config values are set based on the
+ * properties of the filesystem that the repository is on, such as
+ * "core.ignorecase", "core.filemode", "core.symlinks", etc. If the
+ * repository is moved to a new filesystem, these properties may no
+ * longer be correct and API calls may not behave as expected. This
+ * call reruns the phase of repository initialization that sets those
+ * properties to compensate for the current filesystem of the repo.
+ *
+ * @param repo A repository object
+ * @param recurse_submodules Should submodules be updated recursively
+ * @return 0 on success, < 0 on error
+ */
+GIT_EXTERN(int) git_repository_reinit_filesystem(
+ git_repository *repo,
+ int recurse_submodules);
+
+/**
+ * Set the configuration file for this repository
+ *
+ * This configuration file will be used for all configuration
+ * queries involving this repository.
+ *
+ * The repository will keep a reference to the config file;
+ * the user must still free the config after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param config A Config object
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_config(git_repository *repo, git_config *config);
+
+/**
+ * Set the Object Database for this repository
+ *
+ * The ODB will be used for all object-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the ODB; the user
+ * must still free the ODB object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param odb An ODB object
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_odb(git_repository *repo, git_odb *odb);
+
+/**
+ * Set the Reference Database Backend for this repository
+ *
+ * The refdb will be used for all reference related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the refdb; the user
+ * must still free the refdb object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param refdb An refdb object
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_refdb(git_repository *repo, git_refdb *refdb);
+
+/**
+ * Set the index file for this repository
+ *
+ * This index will be used for all index-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the index file;
+ * the user must still free the index after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param index An index object
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_index(git_repository *repo, git_index *index);
+
+/**
+ * Set a repository to be bare.
+ *
+ * Clear the working directory and set core.bare to true. You may also
+ * want to call `git_repository_set_index(repo, NULL)` since a bare repo
+ * typically does not have an index, but this function will not do that
+ * for you.
+ *
+ * @param repo Repo to make bare
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_repository_set_bare(git_repository *repo);
+
+/**
+ * Load and cache all submodules.
+ *
+ * Because the `.gitmodules` file is unstructured, loading submodules is an
+ * O(N) operation. Any operation (such as `git_rebase_init`) that requires
+ * accessing all submodules is O(N^2) in the number of submodules, if it
+ * has to look each one up individually. This function loads all submodules
+ * and caches them so that subsequent calls to `git_submodule_lookup` are O(1).
+ *
+ * @param repo the repository whose submodules will be cached.
+ */
+GIT_EXTERN(int) git_repository_submodule_cache_all(
+ git_repository *repo);
+
+/**
+ * Clear the submodule cache.
+ *
+ * Clear the submodule cache populated by `git_repository_submodule_cache_all`.
+ * If there is no cache, do nothing.
+ *
+ * The cache incorporates data from the repository's configuration, as well
+ * as the state of the working tree, the index, and HEAD. So any time any
+ * of these has changed, the cache might become invalid.
+ *
+ * @param repo the repository whose submodule cache will be cleared
+ */
+GIT_EXTERN(int) git_repository_submodule_cache_clear(
+ git_repository *repo);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/stream.h b/include/git2/sys/stream.h
new file mode 100644
index 0000000..3d28d09
--- /dev/null
+++ b/include/git2/sys/stream.h
@@ -0,0 +1,152 @@
+/*
+ * 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_sys_git_stream_h__
+#define INCLUDE_sys_git_stream_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/proxy.h"
+
+GIT_BEGIN_DECL
+
+#define GIT_STREAM_VERSION 1
+
+/**
+ * Every stream must have this struct as its first element, so the
+ * API can talk to it. You'd define your stream as
+ *
+ * struct my_stream {
+ * git_stream parent;
+ * ...
+ * }
+ *
+ * and fill the functions
+ */
+typedef struct git_stream {
+ int version;
+
+ int encrypted : 1,
+ proxy_support : 1;
+
+ /**
+ * Timeout for read and write operations; can be set to `0` to
+ * block indefinitely.
+ */
+ int timeout;
+
+ /**
+ * Timeout to connect to the remote server; can be set to `0`
+ * to use the system defaults. This can be shorter than the
+ * system default - often 75 seconds - but cannot be longer.
+ */
+ int connect_timeout;
+
+ int GIT_CALLBACK(connect)(struct git_stream *);
+ int GIT_CALLBACK(certificate)(git_cert **, struct git_stream *);
+ int GIT_CALLBACK(set_proxy)(struct git_stream *, const git_proxy_options *proxy_opts);
+ ssize_t GIT_CALLBACK(read)(struct git_stream *, void *, size_t);
+ ssize_t GIT_CALLBACK(write)(struct git_stream *, const char *, size_t, int);
+ int GIT_CALLBACK(close)(struct git_stream *);
+ void GIT_CALLBACK(free)(struct git_stream *);
+} git_stream;
+
+typedef struct {
+ /** The `version` field should be set to `GIT_STREAM_VERSION`. */
+ int version;
+
+ /**
+ * Called to create a new connection to a given host.
+ *
+ * @param out The created stream
+ * @param host The hostname to connect to; may be a hostname or
+ * IP address
+ * @param port The port to connect to; may be a port number or
+ * service name
+ * @return 0 or an error code
+ */
+ int GIT_CALLBACK(init)(git_stream **out, const char *host, const char *port);
+
+ /**
+ * Called to create a new connection on top of the given stream. If
+ * this is a TLS stream, then this function may be used to proxy a
+ * TLS stream over an HTTP CONNECT session. If this is unset, then
+ * HTTP CONNECT proxies will not be supported.
+ *
+ * @param out The created stream
+ * @param in An existing stream to add TLS to
+ * @param host The hostname that the stream is connected to,
+ * for certificate validation
+ * @return 0 or an error code
+ */
+ int GIT_CALLBACK(wrap)(git_stream **out, git_stream *in, const char *host);
+} git_stream_registration;
+
+/**
+ * The type of stream to register.
+ */
+typedef enum {
+ /** A standard (non-TLS) socket. */
+ GIT_STREAM_STANDARD = 1,
+
+ /** A TLS-encrypted socket. */
+ GIT_STREAM_TLS = 2
+} git_stream_t;
+
+/**
+ * Register stream constructors for the library to use
+ *
+ * If a registration structure is already set, it will be overwritten.
+ * Pass `NULL` in order to deregister the current constructor and return
+ * to the system defaults.
+ *
+ * The type parameter may be a bitwise AND of types.
+ *
+ * @param type the type or types of stream to register
+ * @param registration the registration data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_stream_register(
+ git_stream_t type, git_stream_registration *registration);
+
+#ifndef GIT_DEPRECATE_HARD
+
+/** @name Deprecated TLS Stream Registration Functions
+ *
+ * These functions are retained for backward compatibility. The newer
+ * versions of these values should be preferred in all new code.
+ *
+ * There is no plan to remove these backward compatibility values at
+ * this time.
+ */
+/**@{*/
+
+/**
+ * @deprecated Provide a git_stream_registration to git_stream_register
+ * @see git_stream_registration
+ */
+typedef int GIT_CALLBACK(git_stream_cb)(git_stream **out, const char *host, const char *port);
+
+/**
+ * Register a TLS stream constructor for the library to use. This stream
+ * will not support HTTP CONNECT proxies. This internally calls
+ * `git_stream_register` and is preserved for backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated Provide a git_stream_registration to git_stream_register
+ * @see git_stream_register
+ */
+GIT_EXTERN(int) git_stream_register_tls(git_stream_cb ctor);
+
+/**@}*/
+
+#endif
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h
new file mode 100644
index 0000000..370ca45
--- /dev/null
+++ b/include/git2/sys/transport.h
@@ -0,0 +1,465 @@
+/*
+ * 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_sys_git_transport_h
+#define INCLUDE_sys_git_transport_h
+
+#include "git2/net.h"
+#include "git2/oidarray.h"
+#include "git2/proxy.h"
+#include "git2/remote.h"
+#include "git2/strarray.h"
+#include "git2/transport.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/transport.h
+ * @brief Git custom transport registration interfaces and functions
+ * @defgroup git_transport Git custom transport registration
+ * @ingroup Git
+ * @{
+ */
+
+GIT_BEGIN_DECL
+
+typedef struct {
+ const git_remote_head * const *refs;
+ size_t refs_len;
+ git_oid *shallow_roots;
+ size_t shallow_roots_len;
+ int depth;
+} git_fetch_negotiation;
+
+struct git_transport {
+ unsigned int version; /**< The struct version */
+
+ /**
+ * Connect the transport to the remote repository, using the given
+ * direction.
+ */
+ int GIT_CALLBACK(connect)(
+ git_transport *transport,
+ const char *url,
+ int direction,
+ const git_remote_connect_options *connect_opts);
+
+ /**
+ * Resets the connect options for the given transport. This
+ * is useful for updating settings or callbacks for an already
+ * connected transport.
+ */
+ int GIT_CALLBACK(set_connect_opts)(
+ git_transport *transport,
+ const git_remote_connect_options *connect_opts);
+
+ /**
+ * Gets the capabilities for this remote repository.
+ *
+ * This function may be called after a successful call to
+ * `connect()`.
+ */
+ int GIT_CALLBACK(capabilities)(
+ unsigned int *capabilities,
+ git_transport *transport);
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ /**
+ * Gets the object type for the remote repository.
+ *
+ * This function may be called after a successful call to
+ * `connect()`.
+ */
+ int GIT_CALLBACK(oid_type)(
+ git_oid_t *object_type,
+ git_transport *transport);
+#endif
+
+ /**
+ * Get the list of available references in the remote repository.
+ *
+ * This function may be called after a successful call to
+ * `connect()`. The array returned is owned by the transport and
+ * must be kept valid until the next call to one of its functions.
+ */
+ int GIT_CALLBACK(ls)(
+ const git_remote_head ***out,
+ size_t *size,
+ git_transport *transport);
+
+ /** Executes the push whose context is in the git_push object. */
+ int GIT_CALLBACK(push)(
+ git_transport *transport,
+ git_push *push);
+
+ /**
+ * Negotiate a fetch with the remote repository.
+ *
+ * This function may be called after a successful call to `connect()`,
+ * when the direction is GIT_DIRECTION_FETCH. The function performs a
+ * negotiation to calculate the `wants` list for the fetch.
+ */
+ int GIT_CALLBACK(negotiate_fetch)(
+ git_transport *transport,
+ git_repository *repo,
+ const git_fetch_negotiation *fetch_data);
+
+ /**
+ * Return the shallow roots of the remote.
+ *
+ * This function may be called after a successful call to
+ * `negotiate_fetch`.
+ */
+ int GIT_CALLBACK(shallow_roots)(
+ git_oidarray *out,
+ git_transport *transport);
+
+ /**
+ * Start downloading the packfile from the remote repository.
+ *
+ * This function may be called after a successful call to
+ * negotiate_fetch(), when the direction is GIT_DIRECTION_FETCH.
+ */
+ int GIT_CALLBACK(download_pack)(
+ git_transport *transport,
+ git_repository *repo,
+ git_indexer_progress *stats);
+
+ /** Checks to see if the transport is connected */
+ int GIT_CALLBACK(is_connected)(git_transport *transport);
+
+ /** Cancels any outstanding transport operation */
+ void GIT_CALLBACK(cancel)(git_transport *transport);
+
+ /**
+ * Close the connection to the remote repository.
+ *
+ * This function is the reverse of connect() -- it terminates the
+ * connection to the remote end.
+ */
+ int GIT_CALLBACK(close)(git_transport *transport);
+
+ /** Frees/destructs the git_transport object. */
+ void GIT_CALLBACK(free)(git_transport *transport);
+};
+
+#define GIT_TRANSPORT_VERSION 1
+#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
+
+/**
+ * Initializes a `git_transport` with default values. Equivalent to
+ * creating an instance with GIT_TRANSPORT_INIT.
+ *
+ * @param opts the `git_transport` struct to initialize
+ * @param version Version of struct; pass `GIT_TRANSPORT_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_transport_init(
+ git_transport *opts,
+ unsigned int version);
+
+/**
+ * Function to use to create a transport from a URL. The transport database
+ * is scanned to find a transport that implements the scheme of the URI (i.e.
+ * git:// or http://) and a transport object is returned to the caller.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param url The URL to connect to
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url);
+
+/**
+ * Create an ssh transport with custom git command paths
+ *
+ * This is a factory function suitable for setting as the transport
+ * callback in a remote (or for a clone in the options).
+ *
+ * The payload argument must be a strarray pointer with the paths for
+ * the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
+ *
+ * @param out the resulting transport
+ * @param owner the owning remote
+ * @param payload a strarray with the paths
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload);
+
+/**
+ * Add a custom transport definition, to be used in addition to the built-in
+ * set of transports that come with libgit2.
+ *
+ * The caller is responsible for synchronizing calls to git_transport_register
+ * and git_transport_unregister with other calls to the library that
+ * instantiate transports.
+ *
+ * @param prefix The scheme (ending in "://") to match, i.e. "git://"
+ * @param cb The callback used to create an instance of the transport
+ * @param param A fixed parameter to pass to cb at creation time
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_register(
+ const char *prefix,
+ git_transport_cb cb,
+ void *param);
+
+/**
+ * Unregister a custom transport definition which was previously registered
+ * with git_transport_register.
+ *
+ * The caller is responsible for synchronizing calls to git_transport_register
+ * and git_transport_unregister with other calls to the library that
+ * instantiate transports.
+ *
+ * @param prefix From the previous call to git_transport_register
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_unregister(
+ const char *prefix);
+
+/* Transports which come with libgit2 (match git_transport_cb). The expected
+ * value for "param" is listed in-line below. */
+
+/**
+ * Create an instance of the dummy transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload You must pass NULL for this parameter.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_dummy(
+ git_transport **out,
+ git_remote *owner,
+ /* NULL */ void *payload);
+
+/**
+ * Create an instance of the local transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload You must pass NULL for this parameter.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_local(
+ git_transport **out,
+ git_remote *owner,
+ /* NULL */ void *payload);
+
+/**
+ * Create an instance of the smart transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload A pointer to a git_smart_subtransport_definition
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_smart(
+ git_transport **out,
+ git_remote *owner,
+ /* (git_smart_subtransport_definition *) */ void *payload);
+
+/**
+ * Call the certificate check for this transport.
+ *
+ * @param transport a smart transport
+ * @param cert the certificate to pass to the caller
+ * @param valid whether we believe the certificate is valid
+ * @param hostname the hostname we connected to
+ * @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
+ * to indicate that there is no callback registered (or the callback
+ * refused to validate the certificate and callers should behave as
+ * if no callback was set), or < 0 for an error
+ */
+GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport, git_cert *cert, int valid, const char *hostname);
+
+/**
+ * Call the credentials callback for this transport
+ *
+ * @param out the pointer where the creds are to be stored
+ * @param transport a smart transport
+ * @param user the user we saw on the url (if any)
+ * @param methods available methods for authentication
+ * @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
+ * to indicate that there is no callback registered (or the callback
+ * refused to provide credentials and callers should behave as if no
+ * callback was set), or < 0 for an error
+ */
+GIT_EXTERN(int) git_transport_smart_credentials(git_credential **out, git_transport *transport, const char *user, int methods);
+
+/**
+ * Get a copy of the remote connect options
+ *
+ * All data is copied and must be freed by the caller by calling
+ * `git_remote_connect_options_dispose`.
+ *
+ * @param out options struct to fill
+ * @param transport the transport to extract the data from.
+ */
+GIT_EXTERN(int) git_transport_remote_connect_options(
+ git_remote_connect_options *out,
+ git_transport *transport);
+
+/*
+ *** End of base transport interface ***
+ *** Begin interface for subtransports for the smart transport ***
+ */
+
+/** Actions that the smart transport can ask a subtransport to perform */
+typedef enum {
+ GIT_SERVICE_UPLOADPACK_LS = 1,
+ GIT_SERVICE_UPLOADPACK = 2,
+ GIT_SERVICE_RECEIVEPACK_LS = 3,
+ GIT_SERVICE_RECEIVEPACK = 4
+} git_smart_service_t;
+
+typedef struct git_smart_subtransport git_smart_subtransport;
+typedef struct git_smart_subtransport_stream git_smart_subtransport_stream;
+
+/**
+ * A stream used by the smart transport to read and write data
+ * from a subtransport.
+ *
+ * This provides a customization point in case you need to
+ * support some other communication method.
+ */
+struct git_smart_subtransport_stream {
+ git_smart_subtransport *subtransport; /**< The owning subtransport */
+
+ /**
+ * Read available data from the stream.
+ *
+ * The implementation may read less than requested.
+ */
+ int GIT_CALLBACK(read)(
+ git_smart_subtransport_stream *stream,
+ char *buffer,
+ size_t buf_size,
+ size_t *bytes_read);
+
+ /**
+ * Write data to the stream
+ *
+ * The implementation must write all data or return an error.
+ */
+ int GIT_CALLBACK(write)(
+ git_smart_subtransport_stream *stream,
+ const char *buffer,
+ size_t len);
+
+ /** Free the stream */
+ void GIT_CALLBACK(free)(
+ git_smart_subtransport_stream *stream);
+};
+
+/**
+ * An implementation of a subtransport which carries data for the
+ * smart transport
+ */
+struct git_smart_subtransport {
+ /**
+ * Setup a subtransport stream for the requested action.
+ */
+ int GIT_CALLBACK(action)(
+ git_smart_subtransport_stream **out,
+ git_smart_subtransport *transport,
+ const char *url,
+ git_smart_service_t action);
+
+ /**
+ * Close the subtransport.
+ *
+ * Subtransports are guaranteed a call to close() between
+ * calls to action(), except for the following two "natural" progressions
+ * of actions against a constant URL:
+ *
+ * - UPLOADPACK_LS -> UPLOADPACK
+ * - RECEIVEPACK_LS -> RECEIVEPACK
+ */
+ int GIT_CALLBACK(close)(git_smart_subtransport *transport);
+
+ /** Free the subtransport */
+ void GIT_CALLBACK(free)(git_smart_subtransport *transport);
+};
+
+/** A function which creates a new subtransport for the smart transport */
+typedef int GIT_CALLBACK(git_smart_subtransport_cb)(
+ git_smart_subtransport **out,
+ git_transport *owner,
+ void *param);
+
+/**
+ * Definition for a "subtransport"
+ *
+ * The smart transport knows how to speak the git protocol, but it has no
+ * knowledge of how to establish a connection between it and another endpoint,
+ * or how to move data back and forth. For this, a subtransport interface is
+ * declared, and the smart transport delegates this work to the subtransports.
+ *
+ * Three subtransports are provided by libgit2: ssh, git, http(s).
+ *
+ * Subtransports can either be RPC = 0 (persistent connection) or RPC = 1
+ * (request/response). The smart transport handles the differences in its own
+ * logic. The git subtransport is RPC = 0, while http is RPC = 1.
+ */
+typedef struct git_smart_subtransport_definition {
+ /** The function to use to create the git_smart_subtransport */
+ git_smart_subtransport_cb callback;
+
+ /**
+ * True if the protocol is stateless; false otherwise. For example,
+ * http:// is stateless, but git:// is not.
+ */
+ unsigned rpc;
+
+ /** User-specified parameter passed to the callback */
+ void *param;
+} git_smart_subtransport_definition;
+
+/* Smart transport subtransports that come with libgit2 */
+
+/**
+ * Create an instance of the http subtransport.
+ *
+ * This subtransport also supports https.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_http(
+ git_smart_subtransport **out,
+ git_transport *owner,
+ void *param);
+
+/**
+ * Create an instance of the git subtransport.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_git(
+ git_smart_subtransport **out,
+ git_transport *owner,
+ void *param);
+
+/**
+ * Create an instance of the ssh subtransport.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_ssh(
+ git_smart_subtransport **out,
+ git_transport *owner,
+ void *param);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/tag.h b/include/git2/tag.h
new file mode 100644
index 0000000..9830536
--- /dev/null
+++ b/include/git2/tag.h
@@ -0,0 +1,383 @@
+/*
+ * 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_tag_h__
+#define INCLUDE_git_tag_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+#include "strarray.h"
+
+/**
+ * @file git2/tag.h
+ * @brief Git tag parsing routines
+ * @defgroup git_tag Git tag management
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a tag object from the repository.
+ *
+ * @param out pointer to the looked up tag
+ * @param repo the repo to use when locating the tag.
+ * @param id identity of the tag to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_lookup(
+ git_tag **out, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a tag object from the repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param out pointer to the looked up tag
+ * @param repo the repo to use when locating the tag.
+ * @param id identity of the tag to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_lookup_prefix(
+ git_tag **out, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open tag
+ *
+ * You can no longer use the git_tag pointer after this call.
+ *
+ * IMPORTANT: You MUST call this method when you are through with a tag to
+ * release memory. Failure to do so will cause a memory leak.
+ *
+ * @param tag the tag to close
+ */
+GIT_EXTERN(void) git_tag_free(git_tag *tag);
+
+/**
+ * Get the id of a tag.
+ *
+ * @param tag a previously loaded tag.
+ * @return object identity for the tag.
+ */
+GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag);
+
+/**
+ * Get the repository that contains the tag.
+ *
+ * @param tag A previously loaded tag.
+ * @return Repository that contains this tag.
+ */
+GIT_EXTERN(git_repository *) git_tag_owner(const git_tag *tag);
+
+/**
+ * Get the tagged object of a tag
+ *
+ * This method performs a repository lookup for the
+ * given object and returns it
+ *
+ * @param target_out pointer where to store the target
+ * @param tag a previously loaded tag.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag);
+
+/**
+ * Get the OID of the tagged object of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return pointer to the OID
+ */
+GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag);
+
+/**
+ * Get the type of a tag's tagged object
+ *
+ * @param tag a previously loaded tag.
+ * @return type of the tagged object
+ */
+GIT_EXTERN(git_object_t) git_tag_target_type(const git_tag *tag);
+
+/**
+ * Get the name of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return name of the tag
+ */
+GIT_EXTERN(const char *) git_tag_name(const git_tag *tag);
+
+/**
+ * Get the tagger (author) of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return reference to the tag's author or NULL when unspecified
+ */
+GIT_EXTERN(const git_signature *) git_tag_tagger(const git_tag *tag);
+
+/**
+ * Get the message of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return message of the tag or NULL when unspecified
+ */
+GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
+
+
+/**
+ * Create a new tag in the repository from an object
+ *
+ * A new reference will also be created pointing to
+ * this tag object. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The message will not be cleaned up. This can be achieved
+ * through `git_message_prettify()`.
+ *
+ * The tag name will be checked for validity. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * @param oid Pointer where to store the OID of the
+ * newly created tag. If the tag already exists, this parameter
+ * will be the oid of the existing tag, and the function will
+ * return a GIT_EEXISTS error code.
+ *
+ * @param repo Repository where to store the tag
+ *
+ * @param tag_name Name for the tag; this name is validated
+ * for consistency. It should also not conflict with an
+ * already existing tag name
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param tagger Signature of the tagger for this tag, and
+ * of the tagging time
+ *
+ * @param message Full message for this tag
+ *
+ * @param force Overwrite existing references
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ * A tag object is written to the ODB, and a proper reference
+ * is written in the /refs/tags folder, pointing to it
+ */
+GIT_EXTERN(int) git_tag_create(
+ git_oid *oid,
+ git_repository *repo,
+ const char *tag_name,
+ const git_object *target,
+ const git_signature *tagger,
+ const char *message,
+ int force);
+
+/**
+ * Create a new tag in the object database pointing to a git_object
+ *
+ * The message will not be cleaned up. This can be achieved
+ * through `git_message_prettify()`.
+ *
+ * @param oid Pointer where to store the OID of the
+ * newly created tag
+ *
+ * @param repo Repository where to store the tag
+ *
+ * @param tag_name Name for the tag
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param tagger Signature of the tagger for this tag, and
+ * of the tagging time
+ *
+ * @param message Full message for this tag
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_tag_annotation_create(
+ git_oid *oid,
+ git_repository *repo,
+ const char *tag_name,
+ const git_object *target,
+ const git_signature *tagger,
+ const char *message);
+
+/**
+ * Create a new tag in the repository from a buffer
+ *
+ * @param oid Pointer where to store the OID of the newly created tag
+ * @param repo Repository where to store the tag
+ * @param buffer Raw tag data
+ * @param force Overwrite existing tags
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_tag_create_from_buffer(
+ git_oid *oid,
+ git_repository *repo,
+ const char *buffer,
+ int force);
+
+/**
+ * Create a new lightweight tag pointing at a target object
+ *
+ * A new direct reference will be created pointing to
+ * this target object. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param oid Pointer where to store the OID of the provided
+ * target object. If the tag already exists, this parameter
+ * will be filled with the oid of the existing pointed object
+ * and the function will return a GIT_EEXISTS error code.
+ *
+ * @param repo Repository where to store the lightweight tag
+ *
+ * @param tag_name Name for the tag; this name is validated
+ * for consistency. It should also not conflict with an
+ * already existing tag name
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param force Overwrite existing references
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ * A proper reference is written in the /refs/tags folder,
+ * pointing to the provided target object
+ */
+GIT_EXTERN(int) git_tag_create_lightweight(
+ git_oid *oid,
+ git_repository *repo,
+ const char *tag_name,
+ const git_object *target,
+ int force);
+
+/**
+ * Delete an existing tag reference.
+ *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param repo Repository where lives the tag
+ *
+ * @param tag_name Name of the tag to be deleted;
+ * this name is validated for consistency.
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_tag_delete(
+ git_repository *repo,
+ const char *tag_name);
+
+/**
+ * Fill a list with all the tags in the Repository
+ *
+ * The string array will be filled with the names of the
+ * matching tags; these values are owned by the user and
+ * should be free'd manually when no longer needed, using
+ * `git_strarray_free`.
+ *
+ * @param tag_names Pointer to a git_strarray structure where
+ * the tag names will be stored
+ * @param repo Repository where to find the tags
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_list(
+ git_strarray *tag_names,
+ git_repository *repo);
+
+/**
+ * Fill a list with all the tags in the Repository
+ * which name match a defined pattern
+ *
+ * If an empty pattern is provided, all the tags
+ * will be returned.
+ *
+ * The string array will be filled with the names of the
+ * matching tags; these values are owned by the user and
+ * should be free'd manually when no longer needed, using
+ * `git_strarray_free`.
+ *
+ * @param tag_names Pointer to a git_strarray structure where
+ * the tag names will be stored
+ * @param pattern Standard fnmatch pattern
+ * @param repo Repository where to find the tags
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_list_match(
+ git_strarray *tag_names,
+ const char *pattern,
+ git_repository *repo);
+
+/**
+ * Callback used to iterate over tag names
+ *
+ * @see git_tag_foreach
+ *
+ * @param name The tag name
+ * @param oid The tag's OID
+ * @param payload Payload passed to git_tag_foreach
+ * @return non-zero to terminate the iteration
+ */
+typedef int GIT_CALLBACK(git_tag_foreach_cb)(const char *name, git_oid *oid, void *payload);
+
+/**
+ * Call callback `cb' for each tag in the repository
+ *
+ * @param repo Repository
+ * @param callback Callback function
+ * @param payload Pointer to callback data (optional)
+ */
+GIT_EXTERN(int) git_tag_foreach(
+ git_repository *repo,
+ git_tag_foreach_cb callback,
+ void *payload);
+
+
+/**
+ * Recursively peel a tag until a non tag git_object is found
+ *
+ * The retrieved `tag_target` object is owned by the repository
+ * and should be closed with the `git_object_free` method.
+ *
+ * @param tag_target_out Pointer to the peeled git_object
+ * @param tag The tag to be processed
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_peel(
+ git_object **tag_target_out,
+ const git_tag *tag);
+
+/**
+ * Create an in-memory copy of a tag. The copy must be explicitly
+ * free'd or it will leak.
+ *
+ * @param out Pointer to store the copy of the tag
+ * @param source Original tag to copy
+ * @return 0
+ */
+GIT_EXTERN(int) git_tag_dup(git_tag **out, git_tag *source);
+
+/**
+ * Determine whether a tag name is valid, meaning that (when prefixed
+ * with `refs/tags/`) that it is a valid reference name, and that any
+ * additional tag name restrictions are imposed (eg, it cannot start
+ * with a `-`).
+ *
+ * @param valid output pointer to set with validity of given tag name
+ * @param name a tag name to test
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_tag_name_is_valid(int *valid, const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/trace.h b/include/git2/trace.h
new file mode 100644
index 0000000..8cee3a9
--- /dev/null
+++ b/include/git2/trace.h
@@ -0,0 +1,67 @@
+/*
+ * 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_trace_h__
+#define INCLUDE_git_trace_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/trace.h
+ * @brief Git tracing configuration routines
+ * @defgroup git_trace Git tracing configuration routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Available tracing levels. When tracing is set to a particular level,
+ * callers will be provided tracing at the given level and all lower levels.
+ */
+typedef enum {
+ /** No tracing will be performed. */
+ GIT_TRACE_NONE = 0,
+
+ /** Severe errors that may impact the program's execution */
+ GIT_TRACE_FATAL = 1,
+
+ /** Errors that do not impact the program's execution */
+ GIT_TRACE_ERROR = 2,
+
+ /** Warnings that suggest abnormal data */
+ GIT_TRACE_WARN = 3,
+
+ /** Informational messages about program execution */
+ GIT_TRACE_INFO = 4,
+
+ /** Detailed data that allows for debugging */
+ GIT_TRACE_DEBUG = 5,
+
+ /** Exceptionally detailed debugging data */
+ GIT_TRACE_TRACE = 6
+} git_trace_level_t;
+
+/**
+ * An instance for a tracing function
+ */
+typedef void GIT_CALLBACK(git_trace_cb)(git_trace_level_t level, const char *msg);
+
+/**
+ * Sets the system tracing configuration to the specified level with the
+ * specified callback. When system events occur at a level equal to, or
+ * lower than, the given level they will be reported to the given callback.
+ *
+ * @param level Level to set tracing to
+ * @param cb Function to call with trace data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_trace_set(git_trace_level_t level, git_trace_cb cb);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/transaction.h b/include/git2/transaction.h
new file mode 100644
index 0000000..4938570
--- /dev/null
+++ b/include/git2/transaction.h
@@ -0,0 +1,121 @@
+/*
+ * 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_transaction_h__
+#define INCLUDE_git_transaction_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/transaction.h
+ * @brief Git transactional reference routines
+ * @defgroup git_transaction Git transactional reference routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new transaction object
+ *
+ * This does not lock anything, but sets up the transaction object to
+ * know from which repository to lock.
+ *
+ * @param out the resulting transaction
+ * @param repo the repository in which to lock
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transaction_new(git_transaction **out, git_repository *repo);
+
+/**
+ * Lock a reference
+ *
+ * Lock the specified reference. This is the first step to updating a
+ * reference.
+ *
+ * @param tx the transaction
+ * @param refname the reference to lock
+ * @return 0 or an error message
+ */
+GIT_EXTERN(int) git_transaction_lock_ref(git_transaction *tx, const char *refname);
+
+/**
+ * Set the target of a reference
+ *
+ * Set the target of the specified reference. This reference must be
+ * locked.
+ *
+ * @param tx the transaction
+ * @param refname reference to update
+ * @param target target to set the reference to
+ * @param sig signature to use in the reflog; pass NULL to read the identity from the config
+ * @param msg message to use in the reflog
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_target(git_transaction *tx, const char *refname, const git_oid *target, const git_signature *sig, const char *msg);
+
+/**
+ * Set the target of a reference
+ *
+ * Set the target of the specified reference. This reference must be
+ * locked.
+ *
+ * @param tx the transaction
+ * @param refname reference to update
+ * @param target target to set the reference to
+ * @param sig signature to use in the reflog; pass NULL to read the identity from the config
+ * @param msg message to use in the reflog
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_symbolic_target(git_transaction *tx, const char *refname, const char *target, const git_signature *sig, const char *msg);
+
+/**
+ * Set the reflog of a reference
+ *
+ * Set the specified reference's reflog. If this is combined with
+ * setting the target, that update won't be written to the reflog.
+ *
+ * @param tx the transaction
+ * @param refname the reference whose reflog to set
+ * @param reflog the reflog as it should be written out
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_reflog(git_transaction *tx, const char *refname, const git_reflog *reflog);
+
+/**
+ * Remove a reference
+ *
+ * @param tx the transaction
+ * @param refname the reference to remove
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_remove(git_transaction *tx, const char *refname);
+
+/**
+ * Commit the changes from the transaction
+ *
+ * Perform the changes that have been queued. The updates will be made
+ * one by one, and the first failure will stop the processing.
+ *
+ * @param tx the transaction
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transaction_commit(git_transaction *tx);
+
+/**
+ * Free the resources allocated by this transaction
+ *
+ * If any references remain locked, they will be unlocked without any
+ * changes made to them.
+ *
+ * @param tx the transaction
+ */
+GIT_EXTERN(void) git_transaction_free(git_transaction *tx);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/transport.h b/include/git2/transport.h
new file mode 100644
index 0000000..5a27de9
--- /dev/null
+++ b/include/git2/transport.h
@@ -0,0 +1,42 @@
+/*
+ * 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_transport_h__
+#define INCLUDE_git_transport_h__
+
+#include "indexer.h"
+#include "net.h"
+#include "types.h"
+#include "cert.h"
+#include "credential.h"
+
+/**
+ * @file git2/transport.h
+ * @brief Git transport interfaces and functions
+ * @defgroup git_transport interfaces and functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Callback for messages received by the transport.
+ *
+ * Return a negative value to cancel the network operation.
+ *
+ * @param str The message from the transport
+ * @param len The length of the message
+ * @param payload Payload provided by the caller
+ */
+typedef int GIT_CALLBACK(git_transport_message_cb)(const char *str, int len, void *payload);
+
+/** Signature of a function which creates a transport */
+typedef int GIT_CALLBACK(git_transport_cb)(git_transport **out, git_remote *owner, void *param);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/tree.h b/include/git2/tree.h
new file mode 100644
index 0000000..ce0a609
--- /dev/null
+++ b/include/git2/tree.h
@@ -0,0 +1,475 @@
+/*
+ * 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_tree_h__
+#define INCLUDE_git_tree_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+
+/**
+ * @file git2/tree.h
+ * @brief Git tree parsing, loading routines
+ * @defgroup git_tree Git tree parsing, loading routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a tree object from the repository.
+ *
+ * @param out Pointer to the looked up tree
+ * @param repo The repo to use when locating the tree.
+ * @param id Identity of the tree to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_lookup(
+ git_tree **out, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a tree object from the repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param out pointer to the looked up tree
+ * @param repo the repo to use when locating the tree.
+ * @param id identity of the tree to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_lookup_prefix(
+ git_tree **out,
+ git_repository *repo,
+ const git_oid *id,
+ size_t len);
+
+/**
+ * Close an open tree
+ *
+ * You can no longer use the git_tree pointer after this call.
+ *
+ * IMPORTANT: You MUST call this method when you stop using a tree to
+ * release memory. Failure to do so will cause a memory leak.
+ *
+ * @param tree The tree to close
+ */
+GIT_EXTERN(void) git_tree_free(git_tree *tree);
+
+/**
+ * Get the id of a tree.
+ *
+ * @param tree a previously loaded tree.
+ * @return object identity for the tree.
+ */
+GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree);
+
+/**
+ * Get the repository that contains the tree.
+ *
+ * @param tree A previously loaded tree.
+ * @return Repository that contains this tree.
+ */
+GIT_EXTERN(git_repository *) git_tree_owner(const git_tree *tree);
+
+/**
+ * Get the number of entries listed in a tree
+ *
+ * @param tree a previously loaded tree.
+ * @return the number of entries in the tree
+ */
+GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree);
+
+/**
+ * Lookup a tree entry by its filename
+ *
+ * This returns a git_tree_entry that is owned by the git_tree. You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * @param tree a previously loaded tree.
+ * @param filename the filename of the desired entry
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
+ const git_tree *tree, const char *filename);
+
+/**
+ * Lookup a tree entry by its position in the tree
+ *
+ * This returns a git_tree_entry that is owned by the git_tree. You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * @param tree a previously loaded tree.
+ * @param idx the position in the entry list
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
+ const git_tree *tree, size_t idx);
+
+/**
+ * Lookup a tree entry by SHA value.
+ *
+ * This returns a git_tree_entry that is owned by the git_tree. You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * Warning: this must examine every entry in the tree, so it is not fast.
+ *
+ * @param tree a previously loaded tree.
+ * @param id the sha being looked for
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byid(
+ const git_tree *tree, const git_oid *id);
+
+/**
+ * Retrieve a tree entry contained in a tree or in any of its subtrees,
+ * given its relative path.
+ *
+ * Unlike the other lookup functions, the returned tree entry is owned by
+ * the user and must be freed explicitly with `git_tree_entry_free()`.
+ *
+ * @param out Pointer where to store the tree entry
+ * @param root Previously loaded tree which is the root of the relative path
+ * @param path Path to the contained entry
+ * @return 0 on success; GIT_ENOTFOUND if the path does not exist
+ */
+GIT_EXTERN(int) git_tree_entry_bypath(
+ git_tree_entry **out,
+ const git_tree *root,
+ const char *path);
+
+/**
+ * Duplicate a tree entry
+ *
+ * Create a copy of a tree entry. The returned copy is owned by the user,
+ * and must be freed explicitly with `git_tree_entry_free()`.
+ *
+ * @param dest pointer where to store the copy
+ * @param source tree entry to duplicate
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source);
+
+/**
+ * Free a user-owned tree entry
+ *
+ * IMPORTANT: This function is only needed for tree entries owned by the
+ * user, such as the ones returned by `git_tree_entry_dup()` or
+ * `git_tree_entry_bypath()`.
+ *
+ * @param entry The entry to free
+ */
+GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry);
+
+/**
+ * Get the filename of a tree entry
+ *
+ * @param entry a tree entry
+ * @return the name of the file
+ */
+GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry);
+
+/**
+ * Get the id of the object pointed by the entry
+ *
+ * @param entry a tree entry
+ * @return the oid of the object
+ */
+GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry);
+
+/**
+ * Get the type of the object pointed by the entry
+ *
+ * @param entry a tree entry
+ * @return the type of the pointed object
+ */
+GIT_EXTERN(git_object_t) git_tree_entry_type(const git_tree_entry *entry);
+
+/**
+ * Get the UNIX file attributes of a tree entry
+ *
+ * @param entry a tree entry
+ * @return filemode as an integer
+ */
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
+
+/**
+ * Get the raw UNIX file attributes of a tree entry
+ *
+ * This function does not perform any normalization and is only useful
+ * if you need to be able to recreate the original tree object.
+ *
+ * @param entry a tree entry
+ * @return filemode as an integer
+ */
+
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode_raw(const git_tree_entry *entry);
+/**
+ * Compare two tree entries
+ *
+ * @param e1 first tree entry
+ * @param e2 second tree entry
+ * @return <0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2
+ */
+GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2);
+
+/**
+ * Convert a tree entry to the git_object it points to.
+ *
+ * You must call `git_object_free()` on the object when you are done with it.
+ *
+ * @param object_out pointer to the converted object
+ * @param repo repository where to lookup the pointed object
+ * @param entry a tree entry
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_entry_to_object(
+ git_object **object_out,
+ git_repository *repo,
+ const git_tree_entry *entry);
+
+/**
+ * Create a new tree builder.
+ *
+ * The tree builder can be used to create or modify trees in memory and
+ * write them as tree objects to the database.
+ *
+ * If the `source` parameter is not NULL, the tree builder will be
+ * initialized with the entries of the given tree.
+ *
+ * If the `source` parameter is NULL, the tree builder will start with no
+ * entries and will have to be filled manually.
+ *
+ * @param out Pointer where to store the tree builder
+ * @param repo Repository in which to store the object
+ * @param source Source tree to initialize the builder (optional)
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_treebuilder_new(
+ git_treebuilder **out, git_repository *repo, const git_tree *source);
+
+/**
+ * Clear all the entries in the builder
+ *
+ * @param bld Builder to clear
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_treebuilder_clear(git_treebuilder *bld);
+
+/**
+ * Get the number of entries listed in a treebuilder
+ *
+ * @param bld a previously loaded treebuilder.
+ * @return the number of entries in the treebuilder
+ */
+GIT_EXTERN(size_t) git_treebuilder_entrycount(git_treebuilder *bld);
+
+/**
+ * Free a tree builder
+ *
+ * This will clear all the entries and free to builder.
+ * Failing to free the builder after you're done using it
+ * will result in a memory leak
+ *
+ * @param bld Builder to free
+ */
+GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld);
+
+/**
+ * Get an entry from the builder from its filename
+ *
+ * The returned entry is owned by the builder and should
+ * not be freed manually.
+ *
+ * @param bld Tree builder
+ * @param filename Name of the entry
+ * @return pointer to the entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
+ git_treebuilder *bld, const char *filename);
+
+/**
+ * Add or update an entry to the builder
+ *
+ * Insert a new entry for `filename` in the builder with the
+ * given attributes.
+ *
+ * If an entry named `filename` already exists, its attributes
+ * will be updated with the given ones.
+ *
+ * The optional pointer `out` can be used to retrieve a pointer to the
+ * newly created/updated entry. Pass NULL if you do not need it. The
+ * pointer may not be valid past the next operation in this
+ * builder. Duplicate the entry if you want to keep it.
+ *
+ * By default the entry that you are inserting will be checked for
+ * validity; that it exists in the object database and is of the
+ * correct type. If you do not want this behavior, set the
+ * `GIT_OPT_ENABLE_STRICT_OBJECT_CREATION` library option to false.
+ *
+ * @param out Pointer to store the entry (optional)
+ * @param bld Tree builder
+ * @param filename Filename of the entry
+ * @param id SHA1 oid of the entry
+ * @param filemode Folder attributes of the entry. This parameter must
+ * be valued with one of the following entries: 0040000, 0100644,
+ * 0100755, 0120000 or 0160000.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_treebuilder_insert(
+ const git_tree_entry **out,
+ git_treebuilder *bld,
+ const char *filename,
+ const git_oid *id,
+ git_filemode_t filemode);
+
+/**
+ * Remove an entry from the builder by its filename
+ *
+ * @param bld Tree builder
+ * @param filename Filename of the entry to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_treebuilder_remove(
+ git_treebuilder *bld, const char *filename);
+
+/**
+ * Callback for git_treebuilder_filter
+ *
+ * The return value is treated as a boolean, with zero indicating that the
+ * entry should be left alone and any non-zero value meaning that the
+ * entry should be removed from the treebuilder list (i.e. filtered out).
+ */
+typedef int GIT_CALLBACK(git_treebuilder_filter_cb)(
+ const git_tree_entry *entry, void *payload);
+
+/**
+ * Selectively remove entries in the tree
+ *
+ * The `filter` callback will be called for each entry in the tree with a
+ * pointer to the entry and the provided `payload`; if the callback returns
+ * non-zero, the entry will be filtered (removed from the builder).
+ *
+ * @param bld Tree builder
+ * @param filter Callback to filter entries
+ * @param payload Extra data to pass to filter callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_treebuilder_filter(
+ git_treebuilder *bld,
+ git_treebuilder_filter_cb filter,
+ void *payload);
+
+/**
+ * Write the contents of the tree builder as a tree object
+ *
+ * The tree builder will be written to the given `repo`, and its
+ * identifying SHA1 hash will be stored in the `id` pointer.
+ *
+ * @param id Pointer to store the OID of the newly written tree
+ * @param bld Tree builder to write
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_treebuilder_write(
+ git_oid *id, git_treebuilder *bld);
+
+/** Callback for the tree traversal method */
+typedef int GIT_CALLBACK(git_treewalk_cb)(
+ const char *root, const git_tree_entry *entry, void *payload);
+
+/** Tree traversal modes */
+typedef enum {
+ GIT_TREEWALK_PRE = 0, /* Pre-order */
+ GIT_TREEWALK_POST = 1 /* Post-order */
+} git_treewalk_mode;
+
+/**
+ * Traverse the entries in a tree and its subtrees in post or pre order.
+ *
+ * The entries will be traversed in the specified order, children subtrees
+ * will be automatically loaded as required, and the `callback` will be
+ * called once per entry with the current (relative) root for the entry and
+ * the entry data itself.
+ *
+ * If the callback returns a positive value, the passed entry will be
+ * skipped on the traversal (in pre mode). A negative value stops the walk.
+ *
+ * @param tree The tree to walk
+ * @param mode Traversal mode (pre or post-order)
+ * @param callback Function to call on each tree entry
+ * @param payload Opaque pointer to be passed on each callback
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_walk(
+ const git_tree *tree,
+ git_treewalk_mode mode,
+ git_treewalk_cb callback,
+ void *payload);
+
+/**
+ * Create an in-memory copy of a tree. The copy must be explicitly
+ * free'd or it will leak.
+ *
+ * @param out Pointer to store the copy of the tree
+ * @param source Original tree to copy
+ * @return 0
+ */
+GIT_EXTERN(int) git_tree_dup(git_tree **out, git_tree *source);
+
+/**
+ * The kind of update to perform
+ */
+typedef enum {
+ /** Update or insert an entry at the specified path */
+ GIT_TREE_UPDATE_UPSERT,
+ /** Remove an entry from the specified path */
+ GIT_TREE_UPDATE_REMOVE
+} git_tree_update_t;
+
+/**
+ * An action to perform during the update of a tree
+ */
+typedef struct {
+ /** Update action. If it's an removal, only the path is looked at */
+ git_tree_update_t action;
+ /** The entry's id */
+ git_oid id;
+ /** The filemode/kind of object */
+ git_filemode_t filemode;
+ /** The full path from the root tree */
+ const char *path;
+} git_tree_update;
+
+/**
+ * Create a tree based on another one with the specified modifications
+ *
+ * Given the `baseline` perform the changes described in the list of
+ * `updates` and create a new tree.
+ *
+ * This function is optimized for common file/directory addition, removal and
+ * replacement in trees. It is much more efficient than reading the tree into a
+ * `git_index` and modifying that, but in exchange it is not as flexible.
+ *
+ * Deleting and adding the same entry is undefined behaviour, changing
+ * a tree to a blob or viceversa is not supported.
+ *
+ * @param out id of the new tree
+ * @param repo the repository in which to create the tree, must be the
+ * same as for `baseline`
+ * @param baseline the tree to base these changes on
+ * @param nupdates the number of elements in the update list
+ * @param updates the list of updates to perform
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseline, size_t nupdates, const git_tree_update *updates);
+
+/** @} */
+
+GIT_END_DECL
+#endif
diff --git a/include/git2/types.h b/include/git2/types.h
new file mode 100644
index 0000000..d4b033d
--- /dev/null
+++ b/include/git2/types.h
@@ -0,0 +1,371 @@
+/*
+ * 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_types_h__
+#define INCLUDE_git_types_h__
+
+#include "common.h"
+
+/**
+ * @file git2/types.h
+ * @brief libgit2 base & compatibility types
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Cross-platform compatibility types for off_t / time_t
+ *
+ * NOTE: This needs to be in a public header so that both the library
+ * implementation and client applications both agree on the same types.
+ * Otherwise we get undefined behavior.
+ *
+ * Use the "best" types that each platform provides. Currently we truncate
+ * these intermediate representations for compatibility with the git ABI, but
+ * if and when it changes to support 64 bit types, our code will naturally
+ * adapt.
+ * NOTE: These types should match those that are returned by our internal
+ * stat() functions, for all platforms.
+ */
+#include <sys/types.h>
+#ifdef __amigaos4__
+#include <stdint.h>
+#endif
+
+#if defined(_MSC_VER)
+
+typedef __int64 git_off_t;
+typedef __time64_t git_time_t;
+
+#elif defined(__MINGW32__)
+
+typedef off64_t git_off_t;
+typedef __time64_t git_time_t;
+
+#elif defined(__HAIKU__)
+
+typedef __haiku_std_int64 git_off_t;
+typedef __haiku_std_int64 git_time_t;
+
+#else /* POSIX */
+
+/*
+ * Note: Can't use off_t since if a client program includes <sys/types.h>
+ * before us (directly or indirectly), they'll get 32 bit off_t in their client
+ * app, even though /we/ define _FILE_OFFSET_BITS=64.
+ */
+typedef int64_t git_off_t;
+typedef int64_t git_time_t; /**< time in seconds from epoch */
+
+#endif
+
+/** The maximum size of an object */
+typedef uint64_t git_object_size_t;
+
+#include "buffer.h"
+#include "oid.h"
+
+/** Basic type (loose or packed) of any Git object. */
+typedef enum {
+ GIT_OBJECT_ANY = -2, /**< Object can be any of the following */
+ GIT_OBJECT_INVALID = -1, /**< Object is invalid. */
+ GIT_OBJECT_COMMIT = 1, /**< A commit object. */
+ GIT_OBJECT_TREE = 2, /**< A tree (directory listing) object. */
+ GIT_OBJECT_BLOB = 3, /**< A file revision object. */
+ GIT_OBJECT_TAG = 4, /**< An annotated tag object. */
+ GIT_OBJECT_OFS_DELTA = 6, /**< A delta, base is given by an offset. */
+ GIT_OBJECT_REF_DELTA = 7 /**< A delta, base is given by object id. */
+} git_object_t;
+
+/** An open object database handle. */
+typedef struct git_odb git_odb;
+
+/** A custom backend in an ODB */
+typedef struct git_odb_backend git_odb_backend;
+
+/** An object read from the ODB */
+typedef struct git_odb_object git_odb_object;
+
+/** A stream to read/write from the ODB */
+typedef struct git_odb_stream git_odb_stream;
+
+/** A stream to write a packfile to the ODB */
+typedef struct git_odb_writepack git_odb_writepack;
+
+/** a writer for multi-pack-index files. */
+typedef struct git_midx_writer git_midx_writer;
+
+/** An open refs database handle. */
+typedef struct git_refdb git_refdb;
+
+/** A custom backend for refs */
+typedef struct git_refdb_backend git_refdb_backend;
+
+/** A git commit-graph */
+typedef struct git_commit_graph git_commit_graph;
+
+/** a writer for commit-graph files. */
+typedef struct git_commit_graph_writer git_commit_graph_writer;
+
+/**
+ * Representation of an existing git repository,
+ * including all its object contents
+ */
+typedef struct git_repository git_repository;
+
+/** Representation of a working tree */
+typedef struct git_worktree git_worktree;
+
+/** Representation of a generic object in a repository */
+typedef struct git_object git_object;
+
+/** Representation of an in-progress walk through the commits in a repo */
+typedef struct git_revwalk git_revwalk;
+
+/** Parsed representation of a tag object. */
+typedef struct git_tag git_tag;
+
+/** In-memory representation of a blob object. */
+typedef struct git_blob git_blob;
+
+/** Parsed representation of a commit object. */
+typedef struct git_commit git_commit;
+
+/** Representation of each one of the entries in a tree object. */
+typedef struct git_tree_entry git_tree_entry;
+
+/** Representation of a tree object. */
+typedef struct git_tree git_tree;
+
+/** Constructor for in-memory trees */
+typedef struct git_treebuilder git_treebuilder;
+
+/** Memory representation of an index file. */
+typedef struct git_index git_index;
+
+/** An iterator for entries in the index. */
+typedef struct git_index_iterator git_index_iterator;
+
+/** An iterator for conflicts in the index. */
+typedef struct git_index_conflict_iterator git_index_conflict_iterator;
+
+/** Memory representation of a set of config files */
+typedef struct git_config git_config;
+
+/** Interface to access a configuration file */
+typedef struct git_config_backend git_config_backend;
+
+/** Representation of a reference log entry */
+typedef struct git_reflog_entry git_reflog_entry;
+
+/** Representation of a reference log */
+typedef struct git_reflog git_reflog;
+
+/** Representation of a git note */
+typedef struct git_note git_note;
+
+/** Representation of a git packbuilder */
+typedef struct git_packbuilder git_packbuilder;
+
+/** Time in a signature */
+typedef struct git_time {
+ git_time_t time; /**< time in seconds from epoch */
+ int offset; /**< timezone offset, in minutes */
+ char sign; /**< indicator for questionable '-0000' offsets in signature */
+} git_time;
+
+/** An action signature (e.g. for committers, taggers, etc) */
+typedef struct git_signature {
+ char *name; /**< full name of the author */
+ char *email; /**< email of the author */
+ git_time when; /**< time when the action happened */
+} git_signature;
+
+/** In-memory representation of a reference. */
+typedef struct git_reference git_reference;
+
+/** Iterator for references */
+typedef struct git_reference_iterator git_reference_iterator;
+
+/** Transactional interface to references */
+typedef struct git_transaction git_transaction;
+
+/** Annotated commits, the input to merge and rebase. */
+typedef struct git_annotated_commit git_annotated_commit;
+
+/** Representation of a status collection */
+typedef struct git_status_list git_status_list;
+
+/** Representation of a rebase */
+typedef struct git_rebase git_rebase;
+
+/** Basic type of any Git reference. */
+typedef enum {
+ GIT_REFERENCE_INVALID = 0, /**< Invalid reference */
+ GIT_REFERENCE_DIRECT = 1, /**< A reference that points at an object id */
+ GIT_REFERENCE_SYMBOLIC = 2, /**< A reference that points at another reference */
+ GIT_REFERENCE_ALL = GIT_REFERENCE_DIRECT | GIT_REFERENCE_SYMBOLIC
+} git_reference_t;
+
+/** Basic type of any Git branch. */
+typedef enum {
+ GIT_BRANCH_LOCAL = 1,
+ GIT_BRANCH_REMOTE = 2,
+ GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE
+} git_branch_t;
+
+/** Valid modes for index and tree entries. */
+typedef enum {
+ GIT_FILEMODE_UNREADABLE = 0000000,
+ GIT_FILEMODE_TREE = 0040000,
+ GIT_FILEMODE_BLOB = 0100644,
+ GIT_FILEMODE_BLOB_EXECUTABLE = 0100755,
+ GIT_FILEMODE_LINK = 0120000,
+ GIT_FILEMODE_COMMIT = 0160000
+} git_filemode_t;
+
+/**
+ * A refspec specifies the mapping between remote and local reference
+ * names when fetch or pushing.
+ */
+typedef struct git_refspec git_refspec;
+
+/**
+ * Git's idea of a remote repository. A remote can be anonymous (in
+ * which case it does not have backing configuration entries).
+ */
+typedef struct git_remote git_remote;
+
+/**
+ * Interface which represents a transport to communicate with a
+ * remote.
+ */
+typedef struct git_transport git_transport;
+
+/**
+ * Preparation for a push operation. Can be used to configure what to
+ * push and the level of parallelism of the packfile builder.
+ */
+typedef struct git_push git_push;
+
+/* documentation in the definition */
+typedef struct git_remote_head git_remote_head;
+typedef struct git_remote_callbacks git_remote_callbacks;
+
+/**
+ * Parent type for `git_cert_hostkey` and `git_cert_x509`.
+ */
+typedef struct git_cert git_cert;
+
+/**
+ * Opaque structure representing a submodule.
+ */
+typedef struct git_submodule git_submodule;
+
+/**
+ * Submodule update values
+ *
+ * These values represent settings for the `submodule.$name.update`
+ * configuration value which says how to handle `git submodule update` for
+ * this submodule. The value is usually set in the ".gitmodules" file and
+ * copied to ".git/config" when the submodule is initialized.
+ *
+ * You can override this setting on a per-submodule basis with
+ * `git_submodule_set_update()` and write the changed value to disk using
+ * `git_submodule_save()`. If you have overwritten the value, you can
+ * revert it by passing `GIT_SUBMODULE_UPDATE_RESET` to the set function.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_UPDATE_CHECKOUT: the default; when a submodule is
+ * updated, checkout the new detached HEAD to the submodule directory.
+ * - GIT_SUBMODULE_UPDATE_REBASE: update by rebasing the current checked
+ * out branch onto the commit from the superproject.
+ * - GIT_SUBMODULE_UPDATE_MERGE: update by merging the commit in the
+ * superproject into the current checkout out branch of the submodule.
+ * - GIT_SUBMODULE_UPDATE_NONE: do not update this submodule even when
+ * the commit in the superproject is updated.
+ * - GIT_SUBMODULE_UPDATE_DEFAULT: not used except as static initializer
+ * when we don't want any particular update rule to be specified.
+ */
+typedef enum {
+ GIT_SUBMODULE_UPDATE_CHECKOUT = 1,
+ GIT_SUBMODULE_UPDATE_REBASE = 2,
+ GIT_SUBMODULE_UPDATE_MERGE = 3,
+ GIT_SUBMODULE_UPDATE_NONE = 4,
+
+ GIT_SUBMODULE_UPDATE_DEFAULT = 0
+} git_submodule_update_t;
+
+/**
+ * Submodule ignore values
+ *
+ * These values represent settings for the `submodule.$name.ignore`
+ * configuration value which says how deeply to look at the working
+ * directory when getting submodule status.
+ *
+ * You can override this value in memory on a per-submodule basis with
+ * `git_submodule_set_ignore()` and can write the changed value to disk
+ * with `git_submodule_save()`. If you have overwritten the value, you
+ * can revert to the on disk value by using `GIT_SUBMODULE_IGNORE_RESET`.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_IGNORE_UNSPECIFIED: use the submodule's configuration
+ * - GIT_SUBMODULE_IGNORE_NONE: don't ignore any change - i.e. even an
+ * untracked file, will mark the submodule as dirty. Ignored files are
+ * still ignored, of course.
+ * - GIT_SUBMODULE_IGNORE_UNTRACKED: ignore untracked files; only changes
+ * to tracked files, or the index or the HEAD commit will matter.
+ * - GIT_SUBMODULE_IGNORE_DIRTY: ignore changes in the working directory,
+ * only considering changes if the HEAD of submodule has moved from the
+ * value in the superproject.
+ * - GIT_SUBMODULE_IGNORE_ALL: never check if the submodule is dirty
+ * - GIT_SUBMODULE_IGNORE_DEFAULT: not used except as static initializer
+ * when we don't want any particular ignore rule to be specified.
+ */
+typedef enum {
+ GIT_SUBMODULE_IGNORE_UNSPECIFIED = -1, /**< use the submodule's configuration */
+
+ GIT_SUBMODULE_IGNORE_NONE = 1, /**< any change or untracked == dirty */
+ GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /**< dirty if tracked files change */
+ GIT_SUBMODULE_IGNORE_DIRTY = 3, /**< only dirty if HEAD moved */
+ GIT_SUBMODULE_IGNORE_ALL = 4 /**< never dirty */
+} git_submodule_ignore_t;
+
+/**
+ * Options for submodule recurse.
+ *
+ * Represent the value of `submodule.$name.fetchRecurseSubmodules`
+ *
+ * * GIT_SUBMODULE_RECURSE_NO - do no recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_YES - recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_ONDEMAND - recurse into submodules only when
+ * commit not already in local clone
+ */
+typedef enum {
+ GIT_SUBMODULE_RECURSE_NO = 0,
+ GIT_SUBMODULE_RECURSE_YES = 1,
+ GIT_SUBMODULE_RECURSE_ONDEMAND = 2
+} git_submodule_recurse_t;
+
+typedef struct git_writestream git_writestream;
+
+/** A type to write in a streaming fashion, for example, for filters. */
+struct git_writestream {
+ int GIT_CALLBACK(write)(git_writestream *stream, const char *buffer, size_t len);
+ int GIT_CALLBACK(close)(git_writestream *stream);
+ void GIT_CALLBACK(free)(git_writestream *stream);
+};
+
+/** Representation of .mailmap file state. */
+typedef struct git_mailmap git_mailmap;
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/version.h b/include/git2/version.h
new file mode 100644
index 0000000..d6aba3b
--- /dev/null
+++ b/include/git2/version.h
@@ -0,0 +1,39 @@
+/*
+ * 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_version_h__
+#define INCLUDE_git_version_h__
+
+/**
+ * The version string for libgit2. This string follows semantic
+ * versioning (v2) guidelines.
+ */
+#define LIBGIT2_VERSION "1.7.2"
+
+/** The major version number for this version of libgit2. */
+#define LIBGIT2_VER_MAJOR 1
+
+/** The minor version number for this version of libgit2. */
+#define LIBGIT2_VER_MINOR 7
+
+/** The revision ("teeny") version number for this version of libgit2. */
+#define LIBGIT2_VER_REVISION 2
+
+/** The Windows DLL patch number for this version of libgit2. */
+#define LIBGIT2_VER_PATCH 0
+
+/**
+ * The prerelease string for this version of libgit2. For development
+ * (nightly) builds, this will be "alpha". For prereleases, this will be
+ * a prerelease name like "beta" or "rc1". For final releases, this will
+ * be `NULL`.
+ */
+#define LIBGIT2_VER_PRERELEASE NULL
+
+/** The library ABI soversion for this version of libgit2. */
+#define LIBGIT2_SOVERSION "1.7"
+
+#endif
diff --git a/include/git2/worktree.h b/include/git2/worktree.h
new file mode 100644
index 0000000..9193eaf
--- /dev/null
+++ b/include/git2/worktree.h
@@ -0,0 +1,268 @@
+/*
+ * 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_worktree_h__
+#define INCLUDE_git_worktree_h__
+
+#include "common.h"
+#include "buffer.h"
+#include "types.h"
+#include "strarray.h"
+
+/**
+ * @file git2/worktrees.h
+ * @brief Git worktree related functions
+ * @defgroup git_commit Git worktree related functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * List names of linked working trees
+ *
+ * The returned list should be released with `git_strarray_free`
+ * when no longer needed.
+ *
+ * @param out pointer to the array of working tree names
+ * @param repo the repo to use when listing working trees
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
+
+/**
+ * Lookup a working tree by its name for a given repository
+ *
+ * @param out Output pointer to looked up worktree or `NULL`
+ * @param repo The repository containing worktrees
+ * @param name Name of the working tree to look up
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name);
+
+/**
+ * Open a worktree of a given repository
+ *
+ * If a repository is not the main tree but a worktree, this
+ * function will look up the worktree inside the parent
+ * repository and create a new `git_worktree` structure.
+ *
+ * @param out Out-pointer for the newly allocated worktree
+ * @param repo Repository to look up worktree for
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_worktree_open_from_repository(git_worktree **out, git_repository *repo);
+
+/**
+ * Free a previously allocated worktree
+ *
+ * @param wt worktree handle to close. If NULL nothing occurs.
+ */
+GIT_EXTERN(void) git_worktree_free(git_worktree *wt);
+
+/**
+ * Check if worktree is valid
+ *
+ * A valid worktree requires both the git data structures inside
+ * the linked parent repository and the linked working copy to be
+ * present.
+ *
+ * @param wt Worktree to check
+ * @return 0 when worktree is valid, error-code otherwise
+ */
+GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt);
+
+/**
+ * Worktree add options structure
+ *
+ * Initialize with `GIT_WORKTREE_ADD_OPTIONS_INIT`. Alternatively, you can
+ * use `git_worktree_add_options_init`.
+ *
+ */
+typedef struct git_worktree_add_options {
+ unsigned int version;
+
+ int lock; /**< lock newly created worktree */
+ git_reference *ref; /**< reference to use for the new worktree HEAD */
+
+ /**
+ * Options for the checkout.
+ */
+ git_checkout_options checkout_options;
+} git_worktree_add_options;
+
+#define GIT_WORKTREE_ADD_OPTIONS_VERSION 1
+#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL,GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initialize git_worktree_add_options structure
+ *
+ * Initializes a `git_worktree_add_options` with default values. Equivalent to
+ * creating an instance with `GIT_WORKTREE_ADD_OPTIONS_INIT`.
+ *
+ * @param opts The `git_worktree_add_options` struct to initialize.
+ * @param version The struct version; pass `GIT_WORKTREE_ADD_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_worktree_add_options_init(git_worktree_add_options *opts,
+ unsigned int version);
+
+/**
+ * Add a new working tree
+ *
+ * Add a new working tree for the repository, that is create the
+ * required data structures inside the repository and check out
+ * the current HEAD at `path`
+ *
+ * @param out Output pointer containing new working tree
+ * @param repo Repository to create working tree for
+ * @param name Name of the working tree
+ * @param path Path to create working tree at
+ * @param opts Options to modify default behavior. May be NULL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_worktree_add(git_worktree **out, git_repository *repo,
+ const char *name, const char *path,
+ const git_worktree_add_options *opts);
+
+/**
+ * Lock worktree if not already locked
+ *
+ * Lock a worktree, optionally specifying a reason why the linked
+ * working tree is being locked.
+ *
+ * @param wt Worktree to lock
+ * @param reason Reason why the working tree is being locked
+ * @return 0 on success, non-zero otherwise
+ */
+GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, const char *reason);
+
+/**
+ * Unlock a locked worktree
+ *
+ * @param wt Worktree to unlock
+ * @return 0 on success, 1 if worktree was not locked, error-code
+ * otherwise
+ */
+GIT_EXTERN(int) git_worktree_unlock(git_worktree *wt);
+
+/**
+ * Check if worktree is locked
+ *
+ * A worktree may be locked if the linked working tree is stored
+ * on a portable device which is not available.
+ *
+ * @param reason Buffer to store reason in. If NULL no reason is stored.
+ * @param wt Worktree to check
+ * @return 0 when the working tree not locked, a value greater
+ * than zero if it is locked, less than zero if there was an
+ * error
+ */
+GIT_EXTERN(int) git_worktree_is_locked(git_buf *reason, const git_worktree *wt);
+
+/**
+ * Retrieve the name of the worktree
+ *
+ * @param wt Worktree to get the name for
+ * @return The worktree's name. The pointer returned is valid for the
+ * lifetime of the git_worktree
+ */
+GIT_EXTERN(const char *) git_worktree_name(const git_worktree *wt);
+
+/**
+ * Retrieve the filesystem path for the worktree
+ *
+ * @param wt Worktree to get the path for
+ * @return The worktree's filesystem path. The pointer returned
+ * is valid for the lifetime of the git_worktree.
+ */
+GIT_EXTERN(const char *) git_worktree_path(const git_worktree *wt);
+
+/**
+ * Flags which can be passed to git_worktree_prune to alter its
+ * behavior.
+ */
+typedef enum {
+ /* Prune working tree even if working tree is valid */
+ GIT_WORKTREE_PRUNE_VALID = 1u << 0,
+ /* Prune working tree even if it is locked */
+ GIT_WORKTREE_PRUNE_LOCKED = 1u << 1,
+ /* Prune checked out working tree */
+ GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2
+} git_worktree_prune_t;
+
+/**
+ * Worktree prune options structure
+ *
+ * Initialize with `GIT_WORKTREE_PRUNE_OPTIONS_INIT`. Alternatively, you can
+ * use `git_worktree_prune_options_init`.
+ *
+ */
+typedef struct git_worktree_prune_options {
+ unsigned int version;
+
+ /** A combination of `git_worktree_prune_t` */
+ uint32_t flags;
+} git_worktree_prune_options;
+
+#define GIT_WORKTREE_PRUNE_OPTIONS_VERSION 1
+#define GIT_WORKTREE_PRUNE_OPTIONS_INIT {GIT_WORKTREE_PRUNE_OPTIONS_VERSION,0}
+
+/**
+ * Initialize git_worktree_prune_options structure
+ *
+ * Initializes a `git_worktree_prune_options` with default values. Equivalent to
+ * creating an instance with `GIT_WORKTREE_PRUNE_OPTIONS_INIT`.
+ *
+ * @param opts The `git_worktree_prune_options` struct to initialize.
+ * @param version The struct version; pass `GIT_WORKTREE_PRUNE_OPTIONS_VERSION`.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_worktree_prune_options_init(
+ git_worktree_prune_options *opts,
+ unsigned int version);
+
+/**
+ * Is the worktree prunable with the given options?
+ *
+ * A worktree is not prunable in the following scenarios:
+ *
+ * - the worktree is linking to a valid on-disk worktree. The
+ * `valid` member will cause this check to be ignored.
+ * - the worktree is locked. The `locked` flag will cause this
+ * check to be ignored.
+ *
+ * If the worktree is not valid and not locked or if the above
+ * flags have been passed in, this function will return a
+ * positive value. If the worktree is not prunable, an error
+ * message will be set (visible in `giterr_last`) with details about
+ * why.
+ *
+ * @param wt Worktree to check.
+ * @param opts The prunable options.
+ * @return 1 if the worktree is prunable, 0 otherwise, or an error code.
+ */
+GIT_EXTERN(int) git_worktree_is_prunable(git_worktree *wt,
+ git_worktree_prune_options *opts);
+
+/**
+ * Prune working tree
+ *
+ * Prune the working tree, that is remove the git data
+ * structures on disk. The repository will only be pruned of
+ * `git_worktree_is_prunable` succeeds.
+ *
+ * @param wt Worktree to prune
+ * @param opts Specifies which checks to override. See
+ * `git_worktree_is_prunable`. May be NULL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_worktree_prune(git_worktree *wt,
+ git_worktree_prune_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif