Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/git2.h15
-rw-r--r--include/git2/attr.h63
-rw-r--r--include/git2/blob.h87
-rw-r--r--include/git2/branch.h228
-rw-r--r--include/git2/checkout.h285
-rw-r--r--include/git2/clone.h107
-rw-r--r--include/git2/commit.h62
-rw-r--r--include/git2/common.h102
-rw-r--r--include/git2/config.h322
-rw-r--r--include/git2/cred_helpers.h53
-rw-r--r--include/git2/diff.h863
-rw-r--r--include/git2/errors.h90
-rw-r--r--include/git2/graph.h41
-rw-r--r--include/git2/ignore.h78
-rw-r--r--include/git2/index.h448
-rw-r--r--include/git2/indexer.h89
-rw-r--r--include/git2/inttypes.h4
-rw-r--r--include/git2/merge.h24
-rw-r--r--include/git2/message.h49
-rw-r--r--include/git2/net.h16
-rw-r--r--include/git2/notes.h151
-rw-r--r--include/git2/object.h40
-rw-r--r--include/git2/odb.h124
-rw-r--r--include/git2/odb_backend.h61
-rw-r--r--include/git2/oid.h75
-rw-r--r--include/git2/pack.h143
-rw-r--r--include/git2/push.h131
-rw-r--r--include/git2/refdb.h98
-rw-r--r--include/git2/refdb_backend.h109
-rw-r--r--include/git2/reflog.h83
-rw-r--r--include/git2/refs.h425
-rw-r--r--include/git2/refspec.h32
-rw-r--r--include/git2/remote.h293
-rw-r--r--include/git2/repository.h424
-rw-r--r--include/git2/reset.h81
-rw-r--r--include/git2/revparse.h80
-rw-r--r--include/git2/revwalk.h49
-rw-r--r--include/git2/signature.h35
-rw-r--r--include/git2/stash.h121
-rw-r--r--include/git2/status.h205
-rw-r--r--include/git2/strarray.h60
-rw-r--r--include/git2/submodule.h533
-rw-r--r--include/git2/tag.h141
-rw-r--r--include/git2/threads.h6
-rw-r--r--include/git2/trace.h68
-rw-r--r--include/git2/transport.h328
-rw-r--r--include/git2/tree.h278
-rw-r--r--include/git2/types.h35
-rw-r--r--include/git2/version.h6
-rw-r--r--include/git2/windows.h59
50 files changed, 6113 insertions, 1187 deletions
diff --git a/include/git2.h b/include/git2.h
index d75387318..5f9fc4824 100644
--- a/include/git2.h
+++ b/include/git2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -23,8 +23,10 @@
#include "git2/repository.h"
#include "git2/revwalk.h"
#include "git2/merge.h"
+#include "git2/graph.h"
#include "git2/refs.h"
#include "git2/reflog.h"
+#include "git2/revparse.h"
#include "git2/object.h"
#include "git2/blob.h"
@@ -35,13 +37,24 @@
#include "git2/index.h"
#include "git2/config.h"
+#include "git2/transport.h"
#include "git2/remote.h"
+#include "git2/clone.h"
+#include "git2/checkout.h"
+#include "git2/push.h"
+#include "git2/attr.h"
+#include "git2/ignore.h"
+#include "git2/branch.h"
#include "git2/refspec.h"
#include "git2/net.h"
#include "git2/status.h"
#include "git2/indexer.h"
#include "git2/submodule.h"
#include "git2/notes.h"
+#include "git2/reset.h"
+#include "git2/message.h"
+#include "git2/pack.h"
+#include "git2/stash.h"
#endif
diff --git a/include/git2/attr.h b/include/git2/attr.h
index 28ca3bc1c..dea44f0e3 100644
--- a/include/git2/attr.h
+++ b/include/git2/attr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -30,7 +30,7 @@ GIT_BEGIN_DECL
* Then for file `xyz.c` looking up attribute "foo" gives a value for
* which `GIT_ATTR_TRUE(value)` is true.
*/
-#define GIT_ATTR_TRUE(attr) ((attr) == git_attr__true)
+#define GIT_ATTR_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_TRUE_T)
/**
* GIT_ATTR_FALSE checks if an attribute is set off. In core git
@@ -44,7 +44,7 @@ GIT_BEGIN_DECL
* Then for file `zyx.h` looking up attribute "foo" gives a value for
* which `GIT_ATTR_FALSE(value)` is true.
*/
-#define GIT_ATTR_FALSE(attr) ((attr) == git_attr__false)
+#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T)
/**
* GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This
@@ -62,11 +62,11 @@ GIT_BEGIN_DECL
* file `onefile.rb` or looking up "bar" on any file will all give
* `GIT_ATTR_UNSPECIFIED(value)` of true.
*/
-#define GIT_ATTR_UNSPECIFIED(attr) (!(attr) || (attr) == git_attr__unset)
+#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T)
/**
* GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
- * opposied to TRUE, FALSE or UNSPECIFIED). This would be the case if
+ * opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if
* for a file with something like:
*
* *.txt eol=lf
@@ -74,13 +74,29 @@ GIT_BEGIN_DECL
* 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) \
- ((attr) && (attr) != git_attr__unset && \
- (attr) != git_attr__true && (attr) != git_attr__false)
+#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
-GIT_EXTERN(const char *) git_attr__true;
-GIT_EXTERN(const char *) git_attr__false;
-GIT_EXTERN(const char *) git_attr__unset;
+typedef enum {
+ GIT_ATTR_UNSPECIFIED_T = 0,
+ GIT_ATTR_TRUE_T,
+ GIT_ATTR_FALSE_T,
+ GIT_ATTR_VALUE_T,
+} git_attr_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_t) git_attr_value(const char *attr);
/**
* Check attribute flags: Reading values from index and working directory.
@@ -167,29 +183,30 @@ GIT_EXTERN(int) git_attr_get_many(
size_t num_attr,
const char **names);
+typedef int (*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 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 callback The function that will be invoked on each attribute
- * and attribute value. The name parameter will be the name
- * of the attribute and the value will be the value it is
- * set to, including possibly NULL if the attribute is
- * explicitly set to UNSPECIFIED using the ! sign. This
- * 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.
+ * @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. The
+ * value may be NULL is the attribute is explicitly set to
+ * UNSPECIFIED using the '!' sign. 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. Return a non-zero value from this to stop looping.
* @param payload Passed on as extra parameter to callback function.
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_attr_foreach(
git_repository *repo,
uint32_t flags,
const char *path,
- int (*callback)(const char *name, const char *value, void *payload),
+ git_attr_foreach_cb callback,
void *payload);
/**
diff --git a/include/git2/blob.h b/include/git2/blob.h
index 551770678..0a2aa9d36 100644
--- a/include/git2/blob.h
+++ b/include/git2/blob.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -46,7 +46,7 @@ GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git
* @param len the length of the short identifier
* @return 0 or an error code
*/
-GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, unsigned int len)
+GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len)
{
return git_object_lookup_prefix((git_object **)blob, repo, id, len, GIT_OBJ_BLOB);
}
@@ -68,6 +68,17 @@ GIT_INLINE(void) git_blob_free(git_blob *blob)
git_object_free((git_object *) blob);
}
+/**
+ * Get the id of a blob.
+ *
+ * @param blob a previously loaded blob.
+ * @return SHA1 hash for this blob.
+ */
+GIT_INLINE(const git_oid *) git_blob_id(const git_blob *blob)
+{
+ return git_object_id((const git_object *)blob);
+}
+
/**
* Get a read-only buffer with the raw content of a blob.
@@ -80,7 +91,7 @@ GIT_INLINE(void) git_blob_free(git_blob *blob)
* @param blob pointer to the blob
* @return the pointer; NULL if the blob has no contents
*/
-GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob);
+GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
/**
* Get the size in bytes of the contents of a blob
@@ -88,34 +99,79 @@ GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob);
* @param blob pointer to the blob
* @return size on bytes
*/
-GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob);
+GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob);
/**
* Read a file from the working folder of a repository
* and write it to the Object Database as a loose blob
*
- * @param oid return the id of the written 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 path file from which the blob will be created,
+ * @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_fromfile(git_oid *oid, git_repository *repo, const char *path);
+GIT_EXTERN(int) git_blob_create_fromworkdir(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 oid return the id of the written 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_fromdisk(git_oid *oid, git_repository *repo, const char *path);
+GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path);
+typedef int (*git_blob_chunk_cb)(char *content, size_t max_length, void *payload);
+
+/**
+ * Write a loose blob to the Object Database from a
+ * provider of chunks of data.
+ *
+ * Provided the `hintpath` parameter is filled, its value
+ * will help to determine what git filters should be applied
+ * to the object before it can be placed to the object database.
+ *
+ *
+ * The implementation of the callback has to respect the
+ * following rules:
+ *
+ * - `content` will have to be filled by the consumer. The maximum number
+ * of bytes that the buffer can accept per call is defined by the
+ * `max_length` parameter. Allocation and freeing of the buffer will be taken
+ * care of by the function.
+ *
+ * - The callback is expected to return the number of bytes
+ * that `content` have been filled with.
+ *
+ * - When there is no more data to stream, the callback should
+ * return 0. This will prevent it from being invoked anymore.
+ *
+ * - When an error occurs, the callback should return -1.
+ *
+ *
+ * @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 hintpath if not NULL, will help selecting the filters
+ * to apply onto the content of the blob to be created.
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_fromchunks(
+ git_oid *id,
+ git_repository *repo,
+ const char *hintpath,
+ git_blob_chunk_cb callback,
+ void *payload);
+
/**
* Write an in-memory buffer to the ODB as a blob
*
@@ -127,6 +183,19 @@ GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, con
*/
GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, 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 4000 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(git_blob *blob);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/branch.h b/include/git2/branch.h
index e2432bcfc..b15171360 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -8,6 +8,7 @@
#define INCLUDE_git_branch_h__
#include "common.h"
+#include "oid.h"
#include "types.h"
/**
@@ -26,61 +27,53 @@ GIT_BEGIN_DECL
* this target commit. If `force` is true and a reference
* already exists with the given name, it'll be replaced.
*
- * @param oid_out Pointer where to store the OID of the target commit.
+ * The returned reference must be freed by the user.
*
- * @param repo Repository where to store the branch.
+ * 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 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 Object to which this branch should point. 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 dereferencable
- * to a git_commit which oid will be used as the target of the branch.
+ * @param target Commit to which this branch should point. This object
+ * must belong to the given `repo`.
*
* @param force Overwrite existing branch.
*
- * @return 0 or an error code.
+ * @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_oid *oid_out,
- git_repository *repo,
- const char *branch_name,
- const git_object *target,
- int force);
+ git_reference **out,
+ git_repository *repo,
+ const char *branch_name,
+ const git_commit *target,
+ int force);
/**
* Delete an existing branch reference.
*
- * @param repo Repository where lives the branch.
- *
- * @param branch_name Name of the branch to be deleted;
- * 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.
+ * If the branch is successfully deleted, the passed reference
+ * object will be freed and invalidated.
*
- * @return 0 on success, GIT_ENOTFOUND if the branch
- * doesn't exist or an error code.
+ * @param branch A valid reference representing a branch
+ * @return 0 on success, or an error code.
*/
-GIT_EXTERN(int) git_branch_delete(
- git_repository *repo,
- const char *branch_name,
- git_branch_t branch_type);
+GIT_EXTERN(int) git_branch_delete(git_reference *branch);
+
+typedef int (*git_branch_foreach_cb)(
+ const char *branch_name,
+ git_branch_t branch_type,
+ void *payload);
/**
- * Fill a list with all the branches in the Repository
- *
- * The string array will be filled with the names of the
- * matching branches; these values are owned by the user and
- * should be free'd manually when no longer needed, using
- * `git_strarray_free`.
+ * Loop over all the branches and issue a callback for each one.
*
- * @param branch_names Pointer to a git_strarray structure
- * where the branch names will be stored.
+ * If the callback returns a non-zero value, this will stop looping.
*
* @param repo Repository where to find the branches.
*
@@ -88,34 +81,171 @@ GIT_EXTERN(int) git_branch_delete(
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
* or a combination of the two.
*
- * @return 0 or an error code.
+ * @param branch_cb Callback to invoke per found branch.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
-GIT_EXTERN(int) git_branch_list(
- git_strarray *branch_names,
- git_repository *repo,
- unsigned int list_flags);
+GIT_EXTERN(int) git_branch_foreach(
+ git_repository *repo,
+ unsigned int list_flags,
+ git_branch_foreach_cb branch_cb,
+ void *payload);
/**
- * Move/rename an existing branch reference.
+ * Move/rename an existing local branch reference.
*
- * @param repo Repository where lives the branch.
+ * The new branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
*
- * @param old_branch_name Current name of the branch to be moved;
- * this name is validated for consistency.
+ * @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_ENOTFOUND if the branch
- * doesn't exist or an error code.
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code.
*/
GIT_EXTERN(int) git_branch_move(
- git_repository *repo,
- const char *old_branch_name,
- const char *new_branch_name,
- int force);
+ 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);
+
+/**
+ * Return the name of the given local or remote branch.
+ *
+ * The name of the branch matches the definition of the name
+ * for git_branch_lookup. That is, if the returned name is given
+ * to git_branch_lookup() then the reference is returned that
+ * was given to this function.
+ *
+ * @param out where the pointer of branch name is stored;
+ * this is valid as long as the ref is not freed.
+ * @param ref the reference ideally pointing to a branch
+ *
+ * @return 0 on success; otherwise an error code (e.g., if the
+ * ref is no local or remote branch).
+ */
+GIT_EXTERN(int) git_branch_name(const char **out,
+ git_reference *ref);
+
+/**
+ * Return the reference supporting the remote tracking branch,
+ * given a local branch reference.
+ *
+ * @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,
+ git_reference *branch);
+
+/**
+ * Set the upstream configuration for a given local branch
+ *
+ * @param branch the branch to configure
+ *
+ * @param upstream_name remote-tracking or local branch to set as
+ * upstream. Pass NULL to unset.
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_branch_set_upstream(git_reference *branch, const char *upstream_name);
+
+/**
+ * Return the name of the reference supporting the remote tracking branch,
+ * given the name of a local branch reference.
+ *
+ * @param tracking_branch_name_out The user-allocated buffer which will be
+ * filled with the name of the reference. Pass NULL if you just want to
+ * get the needed size of the name of the reference as the output value.
+ *
+ * @param buffer_size Size of the `out` buffer in bytes.
+ *
+ * @param repo the repository where the branches live
+ *
+ * @param canonical_branch_name name of the local branch.
+ *
+ * @return number of characters in the reference name
+ * including the trailing NUL byte; GIT_ENOTFOUND when no remote tracking
+ * reference exists, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_upstream_name(
+ char *tracking_branch_name_out,
+ size_t buffer_size,
+ git_repository *repo,
+ const char *canonical_branch_name);
+
+/**
+ * Determine if the current local branch is pointed at by HEAD.
+ *
+ * @param branch Current underlying reference of the branch.
+ *
+ * @return 1 if HEAD points at the branch, 0 if it isn't,
+ * error code otherwise.
+ */
+GIT_EXTERN(int) git_branch_is_head(
+ git_reference *branch);
+
+/**
+ * Return the name of remote that the remote tracking branch belongs to.
+ *
+ * @param remote_name_out The user-allocated buffer which will be
+ * filled with the name of the remote. Pass NULL if you just want to
+ * get the needed size of the name of the remote as the output value.
+ *
+ * @param buffer_size Size of the `out` buffer in bytes.
+ *
+ * @param repo The repository where the branch lives.
+ *
+ * @param canonical_branch_name name of the remote tracking branch.
+ *
+ * @return Number of characters in the reference name
+ * including the trailing NUL byte; GIT_ENOTFOUND
+ * when no remote matching remote was gound,
+ * GIT_EAMBIGUOUS when the branch maps to several remotes,
+ * otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_remote_name(
+ char *remote_name_out,
+ size_t buffer_size,
+ git_repository *repo,
+ const char *canonical_branch_name);
/** @} */
GIT_END_DECL
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
new file mode 100644
index 000000000..d3e971b43
--- /dev/null
+++ b/include/git2/checkout.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_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 four 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).
+ *
+ * In between those are `GIT_CHECKOUT_SAFE` and `GIT_CHECKOUT_SAFE_CREATE`
+ * both of which 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, | create if SAFE_CREATE | create file |
+ * baseline present | notify dirty DELETED | |
+ * ---------------------|-----------------------|----------------------|
+ *
+ * The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE
+ * will cause a file to be checked out if it is missing from the working
+ * directory even if it is not modified between the target and baseline.
+ *
+ *
+ * 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_CREATE` 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`.
+ *
+ * To emulate `git clone` use `GIT_CHECKOUT_SAFE_CREATE` in the options.
+ *
+ *
+ * There are some additional flags to modified 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.
+ */
+typedef enum {
+ GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */
+
+ /** Allow safe updates that cannot overwrite uncommitted data */
+ GIT_CHECKOUT_SAFE = (1u << 0),
+
+ /** Allow safe updates plus creation of missing files */
+ GIT_CHECKOUT_SAFE_CREATE = (1u << 1),
+
+ /** Allow all updates to force working directory to look like index */
+ GIT_CHECKOUT_FORCE = (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 */
+ GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
+
+ /** Don't refresh index/config/etc before doing checkout */
+ GIT_CHECKOUT_NO_REFRESH = (1u << 9),
+
+ /** Treat pathspec as simple list of exact match file paths */
+ GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
+
+ /**
+ * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
+ */
+
+ /** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */
+ GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
+ /** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */
+ GIT_CHECKOUT_USE_OURS = (1u << 11),
+ /** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */
+ GIT_CHECKOUT_USE_THEIRS = (1u << 12),
+
+ /** 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`:
+ *
+ * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths.
+ *
+ * - GIT_CHECKOUT_NOTIFY_DIRTY 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_UPDATED sends notification for any file changed.
+ *
+ * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files.
+ *
+ * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files.
+ *
+ * Returning a non-zero value from this callback will cancel the checkout.
+ * Notification callbacks are made prior to modifying any files on disk.
+ */
+typedef enum {
+ GIT_CHECKOUT_NOTIFY_NONE = 0,
+ GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0),
+ GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1),
+ GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2),
+ GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
+ GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4),
+} git_checkout_notify_t;
+
+/** Checkout notification callback function */
+typedef int (*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_checkout_progress_cb)(
+ const char *path,
+ size_t completed_steps,
+ size_t total_steps,
+ void *payload);
+
+/**
+ * Checkout options structure
+ *
+ * Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTS_INIT` macro to
+ * correctly set the `version` field. E.g.
+ *
+ * git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
+ */
+typedef struct git_checkout_opts {
+ unsigned int version;
+
+ unsigned int checkout_strategy; /** default will be a dry run */
+
+ 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 */
+ git_checkout_notify_cb notify_cb;
+ void *notify_payload;
+
+ /* Optional callback to notify the consumer of checkout progress. */
+ git_checkout_progress_cb progress_cb;
+ void *progress_payload;
+
+ /** When not zeroed out, array of fnmatch patterns specifying which
+ * paths should be taken into account, otherwise all files. Use
+ * GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list.
+ */
+ git_strarray paths;
+
+ git_tree *baseline; /** expected content of workdir, defaults to HEAD */
+} git_checkout_opts;
+
+#define GIT_CHECKOUT_OPTS_VERSION 1
+#define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION}
+
+/**
+ * Updates files in the index and the working tree to match the content of
+ * the commit pointed at by HEAD.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
+ * branch, GIT_ERROR otherwise (use giterr_last for information
+ * about the error)
+ */
+GIT_EXTERN(int) git_checkout_head(
+ git_repository *repo,
+ git_checkout_opts *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, GIT_ERROR otherwise (use giterr_last for information
+ * about the error)
+ */
+GIT_EXTERN(int) git_checkout_index(
+ git_repository *repo,
+ git_index *index,
+ git_checkout_opts *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
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
+ * about the error)
+ */
+GIT_EXTERN(int) git_checkout_tree(
+ git_repository *repo,
+ const git_object *treeish,
+ git_checkout_opts *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/clone.h b/include/git2/clone.h
new file mode 100644
index 000000000..20df49104
--- /dev/null
+++ b/include/git2/clone.h
@@ -0,0 +1,107 @@
+/*
+ * 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"
+
+
+/**
+ * @file git2/clone.h
+ * @brief Git cloning routines
+ * @defgroup git_clone Git cloning routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Clone options structure
+ *
+ * Use zeros to indicate default settings. It's easiest to use the
+ * `GIT_CLONE_OPTIONS_INIT` macro:
+ *
+ * git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ *
+ * - `checkout_opts` is options for the checkout step. To disable checkout,
+ * set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT.
+ * - `bare` should be set to zero to create a standard repo, non-zero for
+ * a bare repo
+ * - `fetch_progress_cb` is optional callback for fetch progress. Be aware that
+ * this is called inline with network and indexing operations, so performance
+ * may be affected.
+ * - `fetch_progress_payload` is payload for fetch_progress_cb
+ *
+ * ** "origin" remote options: **
+ * - `remote_name` is the name given to the "origin" remote. The default is
+ * "origin".
+ * - `pushurl` is a URL to be used for pushing. NULL means use the fetch url.
+ * - `fetch_spec` is the fetch specification to be used for fetching. NULL
+ * results in the same behavior as GIT_REMOTE_DEFAULT_FETCH.
+ * - `push_spec` is the fetch specification to be used for pushing. NULL means
+ * use the same spec as for fetching.
+ * - `cred_acquire_cb` is a callback to be used if credentials are required
+ * during the initial fetch.
+ * - `cred_acquire_payload` is the payload for the above callback.
+ * - `transport` is a custom transport to be used for the initial fetch. NULL
+ * means use the transport autodetected from the URL.
+ * - `remote_callbacks` may be used to specify custom progress callbacks for
+ * the origin remote before the fetch is initiated.
+ * - `remote_autotag` may be used to specify the autotag setting before the
+ * initial fetch. The default is GIT_REMOTE_DOWNLOAD_TAGS_ALL.
+ * - `checkout_branch` gives the name of the branch to checkout. NULL means
+ * use the remote's HEAD.
+ */
+
+typedef struct git_clone_options {
+ unsigned int version;
+
+ git_checkout_opts checkout_opts;
+ int bare;
+ git_transfer_progress_callback fetch_progress_cb;
+ void *fetch_progress_payload;
+
+ const char *remote_name;
+ const char *pushurl;
+ const char *fetch_spec;
+ const char *push_spec;
+ git_cred_acquire_cb cred_acquire_cb;
+ void *cred_acquire_payload;
+ git_transport *transport;
+ git_remote_callbacks *remote_callbacks;
+ git_remote_autotag_option_t remote_autotag;
+ const char* checkout_branch;
+} git_clone_options;
+
+#define GIT_CLONE_OPTIONS_VERSION 1
+#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE_CREATE}}
+
+/**
+ * Clone a remote repository, and checkout the branch pointed to by the remote
+ * HEAD.
+ *
+ * @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, GIT_ERROR otherwise (use giterr_last for information
+ * about the error)
+ */
+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
index a6d9bb0e3..764053eaa 100644
--- a/include/git2/commit.h
+++ b/include/git2/commit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -48,7 +48,7 @@ GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, con
* @param len the length of the short identifier
* @return 0 or an error code
*/
-GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, unsigned len)
+GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len)
{
return git_object_lookup_prefix((git_object **)commit, repo, id, len, GIT_OBJ_COMMIT);
}
@@ -76,7 +76,10 @@ GIT_INLINE(void) git_commit_free(git_commit *commit)
* @param commit a previously loaded commit.
* @return object identity for the commit.
*/
-GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
+GIT_INLINE(const git_oid *) git_commit_id(const git_commit *commit)
+{
+ return git_object_id((const git_object *)commit);
+}
/**
* Get the encoding for the message of a commit,
@@ -88,7 +91,7 @@ GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
* @param commit a previously loaded commit.
* @return NULL, or the encoding
*/
-GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
+GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit);
/**
* Get the full message of a commit.
@@ -96,7 +99,7 @@ GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
* @param commit a previously loaded commit.
* @return the message of a commit
*/
-GIT_EXTERN(const char *) git_commit_message(git_commit *commit);
+GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
/**
* Get the commit time (i.e. committer time) of a commit.
@@ -104,7 +107,7 @@ GIT_EXTERN(const char *) git_commit_message(git_commit *commit);
* @param commit a previously loaded commit.
* @return the time of a commit
*/
-GIT_EXTERN(git_time_t) git_commit_time(git_commit *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.
@@ -112,7 +115,7 @@ GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit);
* @param commit a previously loaded commit.
* @return positive or negative timezone offset, in minutes from UTC
*/
-GIT_EXTERN(int) git_commit_time_offset(git_commit *commit);
+GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit);
/**
* Get the committer of a commit.
@@ -120,7 +123,7 @@ GIT_EXTERN(int) git_commit_time_offset(git_commit *commit);
* @param commit a previously loaded commit.
* @return the committer of a commit
*/
-GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit);
+GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit);
/**
* Get the author of a commit.
@@ -128,7 +131,7 @@ GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit);
* @param commit a previously loaded commit.
* @return the author of a commit
*/
-GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
+GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
/**
* Get the tree pointed to by a commit.
@@ -137,7 +140,7 @@ GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
* @param commit a previously loaded commit.
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
+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
@@ -147,7 +150,7 @@ GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
* @param commit a previously loaded commit.
* @return the id of tree pointed to by commit.
*/
-GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit);
+GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit);
/**
* Get the number of parents of this commit
@@ -155,17 +158,17 @@ GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit);
* @param commit a previously loaded commit.
* @return integer of count of parents
*/
-GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit);
+GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit);
/**
* Get the specified parent of the commit.
*
- * @param parent Pointer where to store the parent 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 **parent, git_commit *commit, unsigned int n);
+GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n);
/**
* Get the oid of a specified parent for a commit. This is different from
@@ -176,16 +179,35 @@ GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsig
* @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_oid(git_commit *commit, unsigned int n);
+GIT_EXTERN(const git_oid *) git_commit_parent_id(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);
/**
* Create a new commit in the repository using `git_object`
* instances as parameters.
*
- * The message will be cleaned up from excess whitespace
- * it will be made sure that the last line ends with a '\n'.
+ * 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
+ * @param id Pointer where to store the OID of the
* newly created commit
*
* @param repo Repository where to store the commit
@@ -226,7 +248,7 @@ GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned i
* the given reference will be updated to point to it
*/
GIT_EXTERN(int) git_commit_create(
- git_oid *oid,
+ git_oid *id,
git_repository *repo,
const char *update_ref,
const git_signature *author,
@@ -254,7 +276,7 @@ GIT_EXTERN(int) git_commit_create(
* @see git_commit_create
*/
GIT_EXTERN(int) git_commit_create_v(
- git_oid *oid,
+ git_oid *id,
git_repository *repo,
const char *update_ref,
const git_signature *author,
diff --git a/include/git2/common.h b/include/git2/common.h
index 0e9379804..5318e66b7 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -55,6 +55,10 @@
#define GIT_WIN32 1
#endif
+#ifdef __amigaos4__
+#include <netinet/in.h>
+#endif
+
/**
* @file git2/common.h
* @brief Git common platform definitions
@@ -81,13 +85,10 @@ GIT_BEGIN_DECL
*/
#define GIT_PATH_MAX 4096
-typedef struct {
- char **strings;
- size_t count;
-} git_strarray;
-
-GIT_EXTERN(void) git_strarray_free(git_strarray *array);
-GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
+/**
+ * The string representation of the null object ID.
+ */
+#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000"
/**
* Return the version of the libgit2 library
@@ -99,6 +100,91 @@ GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
*/
GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
+/**
+ * Combinations of these values describe the capabilities of libgit2.
+ */
+enum {
+ GIT_CAP_THREADS = ( 1 << 0 ),
+ GIT_CAP_HTTPS = ( 1 << 1 )
+};
+
+/**
+ * Query compile time options for libgit2.
+ *
+ * @return A combination of GIT_CAP_* values.
+ *
+ * - GIT_CAP_THREADS
+ * Libgit2 was compiled with thread support. Note that thread support is still to be seen as a
+ * 'work in progress'.
+ *
+ * - GIT_CAP_HTTPS
+ * Libgit2 supports the https:// protocol. This requires the open ssl library to be
+ * found when compiling libgit2.
+ */
+GIT_EXTERN(int) git_libgit2_capabilities(void);
+
+
+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_GET_ODB_CACHE_SIZE,
+ GIT_OPT_SET_ODB_CACHE_SIZE,
+};
+
+/**
+ * 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_SEARCH_PATH, int level, char *out, size_t len)
+ * Get the search path for a given level of config data. "level" must
+ * be one of GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, or
+ * GIT_CONFIG_LEVEL_XDG. The search path is written to the `out`
+ * buffer up to size `len`. Returns GIT_EBUFS if buffer is too small.
+ *
+ * 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,
+ * or GIT_CONFIG_LEVEL_XDG.
+ *
+ * opts(GIT_OPT_GET_ODB_CACHE_SIZE):
+ * Get the size of the libgit2 odb cache.
+ *
+ * opts(GIT_OPT_SET_ODB_CACHE_SIZE):
+ * Set the size of the of the libgit2 odb cache. This needs
+ * to be done before git_repository_open is called, since
+ * git_repository_open initializes the odb layer. Defaults
+ * to 128.
+ *
+ * @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
index 36946c4a5..19d4cb78d 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -20,22 +20,51 @@
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.
+ */
+enum {
+ GIT_CONFIG_LEVEL_SYSTEM = 1, /**< System-wide configuration file. */
+ GIT_CONFIG_LEVEL_XDG = 2, /**< XDG compatible configuration file (.config/git/config). */
+ GIT_CONFIG_LEVEL_GLOBAL = 3, /**< User-specific configuration file, also called Global configuration file. */
+ GIT_CONFIG_LEVEL_LOCAL = 4, /**< Repository specific configuration file. */
+ GIT_CONFIG_HIGHEST_LEVEL = -1, /**< Represents the highest level of a config file. */
+};
+
+typedef struct {
+ const char *name;
+ const char *value;
+ unsigned int level;
+} git_config_entry;
+
+typedef int (*git_config_foreach_cb)(const git_config_entry *, void *);
+
+
+/**
* Generic backend that implements the interface to
* access a configuration file
*/
-struct git_config_file {
+struct git_config_backend {
+ unsigned int version;
struct git_config *cfg;
/* Open means open the file/database and parse if necessary */
- int (*open)(struct git_config_file *);
- int (*get)(struct git_config_file *, const char *key, const char **value);
- int (*get_multivar)(struct git_config_file *, const char *key, const char *regexp, int (*fn)(const char *, void *), void *data);
- int (*set)(struct git_config_file *, const char *key, const char *value);
- int (*set_multivar)(git_config_file *cfg, const char *name, const char *regexp, const char *value);
- int (*del)(struct git_config_file *, const char *key);
- int (*foreach)(struct git_config_file *, int (*fn)(const char *, const char *, void *), void *data);
- void (*free)(struct git_config_file *);
+ int (*open)(struct git_config_backend *, unsigned int level);
+ int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
+ int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload);
+ int (*set)(struct git_config_backend *, const char *key, const char *value);
+ int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
+ int (*del)(struct git_config_backend *, const char *key);
+ int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload);
+ int (*refresh)(struct git_config_backend *);
+ void (*free)(struct git_config_backend *);
};
+#define GIT_CONFIG_BACKEND_VERSION 1
+#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
typedef enum {
GIT_CVAR_FALSE = 0,
@@ -61,11 +90,32 @@ typedef struct {
* may be used on any `git_config` call to load the
* global configuration file.
*
- * @param global_config_path Buffer of GIT_PATH_MAX length to store the path
- * @return 0 if a global configuration file has been
+ * This method will not guess the path to the xdg compatible
+ * config file (.config/git/config).
+ *
+ * @param out Buffer to store the path in
+ * @param length size of the buffer in bytes
+ * @return 0 if a global configuration file has been found. Its path will be stored in `buffer`.
+ */
+GIT_EXTERN(int) git_config_find_global(char *out, size_t length);
+
+/**
+ * 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 Buffer to store the path in
+ * @param length size of the buffer in bytes
+ * @return 0 if a xdg compatible configuration file has been
* found. Its path will be stored in `buffer`.
*/
-GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length);
+GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length);
/**
* Locate the path to the system configuration file
@@ -73,35 +123,24 @@ GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length);
* If /etc/gitconfig doesn't exist, it will look for
* %PROGRAMFILES%\Git\etc\gitconfig.
- * @param system_config_path Buffer of GIT_PATH_MAX length to store the path
+ * @param global_config_path Buffer to store the path in
+ * @param length size of the buffer in bytes
* @return 0 if a system configuration file has been
* found. Its path will be stored in `buffer`.
*/
-GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length);
+GIT_EXTERN(int) git_config_find_system(char *out, size_t length);
/**
- * Open the global configuration file
+ * Open the global, XDG and system configuration files
*
- * Utility wrapper that calls `git_config_find_global`
- * and opens the located file, if it exists.
+ * 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_global(git_config **out);
-
-/**
- * Create a configuration file backend for ondisk files
- *
- * These are the normal `.gitconfig` files that Core Git
- * processes. Note that you first have to add this file to a
- * configuration object before you can query it for configuration
- * variables.
- *
- * @param out the new backend
- * @param path where the config file is located
- */
-GIT_EXTERN(int) git_config_file__ondisk(struct git_config_file **out, const char *path);
+GIT_EXTERN(int) git_config_open_default(git_config **out);
/**
* Allocate a new configuration object
@@ -122,14 +161,21 @@ GIT_EXTERN(int) git_config_new(git_config **out);
*
* Further queries on this config object will access each
* of the config file instances in order (instances with
- * a higher priority will be accessed first).
+ * 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 priority the priority the backend should have
- * @return 0 or an error code
+ * @param level the priority level of the backend
+ * @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_file(git_config *cfg, git_config_file *file, int priority);
+GIT_EXTERN(int) git_config_add_backend(
+ git_config *cfg,
+ git_config_backend *file,
+ unsigned int level,
+ int force);
/**
* Add an on-disk config file instance to an existing config
@@ -143,15 +189,22 @@ GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int
*
* Further queries on this config object will access each
* of the config file instances in order (instances with
- * a higher priority will be accessed first).
+ * a higher priority level will be accessed first).
*
* @param cfg the configuration to add the file to
* @param path path to the configuration file (backend) to add
- * @param priority the priority the backend should have
- * @return 0 or an error code
+ * @param level the priority level of the backend
+ * @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),
+ * 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, int priority);
-
+GIT_EXTERN(int) git_config_add_file_ondisk(
+ git_config *cfg,
+ const char *path,
+ unsigned int level,
+ int force);
/**
* Create a new config instance containing a single on-disk file
@@ -161,11 +214,46 @@ GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, in
* - git_config_new
* - git_config_add_file_ondisk
*
- * @param cfg The configuration instance to create
+ * @param out The configuration instance to create
* @param path Path to the on-disk file to open
+ * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist
+ * 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,
+ unsigned int level);
+
+/**
+ * Reload changed config files
+ *
+ * A config file may be changed on disk out from under the in-memory
+ * config object. This function causes us to look for files that have
+ * been modified since we last loaded them and refresh the config with
+ * the latest information.
+ *
+ * @param cfg The configuration to refresh
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
+GIT_EXTERN(int) git_config_refresh(git_config *cfg);
/**
* Free the configuration and its associated memory and files
@@ -175,24 +263,48 @@ GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
GIT_EXTERN(void) git_config_free(git_config *cfg);
/**
+ * Get the git_config_entry of a config variable.
+ *
+ * The git_config_entry is owned by the config and should not be freed by the
+ * user.
+
+ * @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(
+ const 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 occurence 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, git_config *cfg, const char *name);
+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, git_config *cfg, const char *name);
+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.
@@ -200,12 +312,16 @@ GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *
* 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, git_config *cfg, const char *name);
+GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name);
/**
* Get the value of a string config variable.
@@ -213,12 +329,16 @@ GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name)
* The string is owned by the variable and should not be freed by the
* user.
*
+ * 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's value
* @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, git_config *cfg, const char *name);
+GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
/**
* Get each value of a multivar.
@@ -232,10 +352,11 @@ GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const c
* @param fn the function to be called on each value of the variable
* @param data opaque pointer to pass to the callback
*/
-GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const char *regexp, int (*fn)(const char *, void *), void *data);
+GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
/**
- * Set the value of an integer config variable.
+ * 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
@@ -245,7 +366,8 @@ GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const
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.
+ * 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
@@ -255,7 +377,8 @@ GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t
GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
/**
- * Set the value of a boolean config variable.
+ * 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
@@ -265,7 +388,8 @@ GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t
GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
/**
- * Set the value of a string config variable.
+ * 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.
@@ -277,9 +401,8 @@ GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value
*/
GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value);
-
/**
- * Set a multivar
+ * Set a multivar in the local config file.
*
* @param cfg where to look for the variable
* @param name the variable's name
@@ -289,12 +412,13 @@ GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const c
GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value);
/**
- * Delete a config variable
+ * 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
*/
-GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name);
+GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
/**
* Perform an operation on each config variable.
@@ -302,18 +426,36 @@ GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name);
* The callback receives the normalized name and value of each variable
* in the config backend, and the data pointer passed to this function.
* As soon as one of the callback functions returns something other than 0,
- * this function returns that value.
+ * this function stops iterating and returns `GIT_EUSER`.
*
* @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 or the return value of the callback which didn't return 0
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_config_foreach(
- git_config *cfg,
- int (*callback)(const char *var_name, const char *value, void *payload),
+ const git_config *cfg,
+ git_config_foreach_cb callback,
void *payload);
+/**
+ * Perform an operation on each config variable matching a regular expression.
+ *
+ * This behaviors like `git_config_foreach` with an additional filter of a
+ * regular expression that filters which config keys are passed to the
+ * callback.
+ *
+ * @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
@@ -324,7 +466,7 @@ GIT_EXTERN(int) git_config_foreach(
*
* A mapping array looks as follows:
*
- * git_cvar_map autocrlf_mapping[3] = {
+ * git_cvar_map 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},
@@ -349,7 +491,63 @@ GIT_EXTERN(int) git_config_foreach(
* @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, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n);
+GIT_EXTERN(int) git_config_get_mapped(
+ int *out,
+ const git_config *cfg,
+ const char *name,
+ const git_cvar_map *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_cvar_map` objects specifying the possible mappings
+ * @param map_n number of mapping objects in `maps`
+ * @param value value to parse
+ */
+GIT_EXTERN(int) git_config_lookup_map_value(
+ int *out,
+ const git_cvar_map *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
+ */
+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
+ */
+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
+ */
+GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
+
/** @} */
GIT_END_DECL
diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h
new file mode 100644
index 000000000..e3eb91d6c
--- /dev/null
+++ b/include/git2/cred_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_cred_helpers_h__
+#define INCLUDE_git_cred_helpers_h__
+
+#include "git2/transport.h"
+
+/**
+ * @file git2/cred_helpers.h
+ * @brief Utility functions for credential management
+ * @defgroup git_cred_helpers credential management helpers
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Payload for git_cred_stock_userpass_plaintext.
+ */
+typedef struct git_cred_userpass_payload {
+ char *username;
+ char *password;
+} git_cred_userpass_payload;
+
+
+/**
+ * Stock callback usable as a git_cred_acquire_cb. This calls
+ * git_cred_userpass_plaintext_new unless the protocol has not specified
+ * GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type.
+ *
+ * @param cred 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 cred types are OK to return.
+ * @param payload The payload provided when specifying this callback. (This is
+ * interpreted as a `git_cred_userpass_payload*`.)
+ */
+GIT_EXTERN(int) git_cred_userpass(
+ git_cred **cred,
+ const char *url,
+ const char *user_from_url,
+ unsigned int allowed_types,
+ void *payload);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/diff.h b/include/git2/diff.h
index bafe6268c..d9ceadf20 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -17,6 +17,9 @@
* @file git2/diff.h
* @brief Git tree and file differencing routines.
*
+ * Overview
+ * --------
+ *
* Calculating diffs is generally done in two phases: building a diff list
* then traversing the diff list. This makes is easier to share logic
* across the various types of diffs (tree vs tree, workdir vs index, etc.),
@@ -24,156 +27,327 @@
* such as rename detected, in between the steps. When you are done with a
* diff list object, it must be freed.
*
+ * Terminology
+ * -----------
+ *
+ * To understand the diff APIs, you should know the following terms:
+ *
+ * - A `diff` or `diff list` represents the cumulative list of differences
+ * between two snapshots of a repository (possibly filtered by a set of
+ * file name patterns). This is the `git_diff_list` object.
+ * - 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.
+ * - A `binary` file / delta is a file (or pair) for which no text diffs
+ * should be generated. A diff list 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.
+ * - 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.
+ * - 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.
+ *
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
-enum {
+/**
+ * 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,
+ /** Reverse the sides of the diff */
GIT_DIFF_REVERSE = (1 << 0),
+ /** Treat all files as text, disabling binary attributes & detection */
GIT_DIFF_FORCE_TEXT = (1 << 1),
+ /** Ignore all whitespace */
GIT_DIFF_IGNORE_WHITESPACE = (1 << 2),
+ /** Ignore changes in amount of whitespace */
GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3),
+ /** Ignore whitespace at end of line */
GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4),
+ /** Exclude submodules from the diff completely */
GIT_DIFF_IGNORE_SUBMODULES = (1 << 5),
+ /** Use the "patience diff" algorithm (currently unimplemented) */
GIT_DIFF_PATIENCE = (1 << 6),
+ /** Include ignored files in the diff list */
GIT_DIFF_INCLUDE_IGNORED = (1 << 7),
+ /** Include untracked files in the diff list */
GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8),
+ /** Include unmodified files in the diff list */
GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9),
+ /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked directory
+ * will be marked with only a single entry in the diff list; this flag
+ * adds all files under the directory as UNTRACKED entries, too.
+ */
GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10),
-};
+ /** If the pathspec is set in the diff options, this flags means to
+ * apply it as an exact match instead of as an fnmatch pattern.
+ */
+ GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11),
+ /** Use case insensitive filename comparisons */
+ GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12),
+ /** When generating patch text, include the content of untracked files */
+ GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13),
+ /** 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 = (1 << 14),
+ /** 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 = (1 << 15),
+ /** 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 = (1 << 16),
+ /** Ignore file mode changes */
+ GIT_DIFF_IGNORE_FILEMODE = (1 << 17),
+ /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
+ * will be marked with only a single entry in the diff list; this flag
+ * adds all files under the directory as IGNORED entries, too.
+ */
+ GIT_DIFF_RECURSE_IGNORED_DIRS = (1 << 18),
+} git_diff_option_t;
/**
- * 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.
+ * The diff list object that contains all individual file deltas.
*
- * @todo Most of the parameters here are not actually supported at this time.
+ * 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_list_free()` function.
*/
-typedef struct {
- uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */
- uint16_t context_lines; /**< defaults to 3 */
- uint16_t interhunk_lines; /**< defaults to 3 */
- char *old_prefix; /**< defaults to "a" */
- char *new_prefix; /**< defaults to "b" */
- git_strarray pathspec; /**< defaults to show all paths */
-} git_diff_options;
+typedef struct git_diff_list git_diff_list;
/**
- * The diff list object that contains all individual file deltas.
+ * 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 struct git_diff_list git_diff_list;
-
-enum {
- GIT_DIFF_FILE_VALID_OID = (1 << 0),
- GIT_DIFF_FILE_FREE_PATH = (1 << 1),
- GIT_DIFF_FILE_BINARY = (1 << 2),
- GIT_DIFF_FILE_NOT_BINARY = (1 << 3),
- GIT_DIFF_FILE_FREE_DATA = (1 << 4),
- GIT_DIFF_FILE_UNMAP_DATA = (1 << 5)
-};
+typedef enum {
+ GIT_DIFF_FLAG_BINARY = (1 << 0), /** file(s) treated as binary data */
+ GIT_DIFF_FLAG_NOT_BINARY = (1 << 1), /** file(s) treated as text data */
+ GIT_DIFF_FLAG_VALID_OID = (1 << 2), /** `oid` 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 list 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,
- GIT_DELTA_ADDED = 1,
- GIT_DELTA_DELETED = 2,
- GIT_DELTA_MODIFIED = 3,
- GIT_DELTA_RENAMED = 4,
- GIT_DELTA_COPIED = 5,
- GIT_DELTA_IGNORED = 6,
- GIT_DELTA_UNTRACKED = 7
+ 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_t;
/**
- * Description of one side of a diff.
+ * Description of one side of a diff entry.
+ *
+ * Although this is called a "file", it may actually 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).
+ *
+ * The `oid` is 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.
+ *
+ * `path` is the NUL-terminated path to the entry relative to the working
+ * directory of the repository.
+ *
+ * `size` is the size of the entry in bytes.
+ *
+ * `flags` is a combination of the `git_diff_flag_t` types
+ *
+ * `mode` is, roughly, the stat() `st_mode` value for the item. This will
+ * be restricted to one of the `git_filemode_t` values.
*/
typedef struct {
- git_oid oid;
- char *path;
- uint16_t mode;
- git_off_t size;
- unsigned int flags;
+ git_oid oid;
+ const char *path;
+ git_off_t size;
+ uint32_t flags;
+ uint16_t mode;
} git_diff_file;
/**
- * Description of changes to one file.
+ * Description of changes to one entry.
*
- * When iterating over a diff list object, this will generally be passed to
- * most callback functions and you can use the contents to understand
- * exactly what has changed.
+ * When iterating over a diff list object, this will be passed to most
+ * callback functions and you can use the contents to understand exactly
+ * what has changed.
*
- * Under some circumstances, not all fields will be filled in, but the code
- * generally tries to fill in as much as possible. One example is that the
- * "binary" field will not actually look at 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 `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.
*/
typedef struct {
git_diff_file old_file;
git_diff_file new_file;
git_delta_t status;
- unsigned int similarity; /**< for RENAMED and COPIED, value 0-100 */
- int binary;
+ uint32_t similarity; /**< for RENAMED and COPIED, value 0-100 */
+ uint32_t flags;
} git_diff_delta;
/**
+ * Diff notification callback function.
+ *
+ * The callback will be called for each file, just before the `git_delta_t`
+ * gets inserted into the diff list.
+ *
+ * When the callback:
+ * - returns < 0, the diff process will be aborted.
+ * - returns > 0, the delta will not be inserted into the diff list, but the
+ * diff process continues.
+ * - returns 0, the delta is inserted into the diff list, and the diff process
+ * continues.
+ */
+typedef int (*git_diff_notify_cb)(
+ const git_diff_list *diff_so_far,
+ const git_diff_delta *delta_to_add,
+ const char *matched_pathspec,
+ 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.
+ *
+ * - `flags` is a combination of the `git_diff_option_t` values above
+ * - `context_lines` is the number of unchanged lines that define the
+ * boundary of a hunk (and to display before and after)
+ * - `interhunk_lines` is the maximum number of unchanged lines between
+ * hunk boundaries before the hunks will be merged into a one.
+ * - `old_prefix` is the virtual "directory" to prefix to old file names
+ * in hunk headers (default "a")
+ * - `new_prefix` is the virtual "directory" to prefix to new file names
+ * in hunk headers (default "b")
+ * - `pathspec` is an array of paths / fnmatch patterns to constrain diff
+ * - `max_size` is a file size (in bytes) above which a blob will be marked
+ * as binary automatically; pass a negative value to disable.
+ * - `notify_cb` is an optional callback function, notifying the consumer of
+ * which files are being examined as the diff is generated
+ * - `notify_payload` is the payload data to pass to the `notify_cb` function
+ */
+typedef struct {
+ unsigned int version; /**< version for the struct */
+ uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */
+ uint16_t context_lines; /**< defaults to 3 */
+ uint16_t interhunk_lines; /**< defaults to 0 */
+ const char *old_prefix; /**< defaults to "a" */
+ const char *new_prefix; /**< defaults to "b" */
+ git_strarray pathspec; /**< defaults to include all paths */
+ git_off_t max_size; /**< defaults to 512MB */
+ git_diff_notify_cb notify_cb;
+ void *notify_payload;
+} git_diff_options;
+
+#define GIT_DIFF_OPTIONS_VERSION 1
+#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_NORMAL, 3}
+
+/**
* 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 list
+ * @param payload User-specified pointer from foreach function
*/
-typedef int (*git_diff_file_fn)(
- void *cb_data,
- git_diff_delta *delta,
- float progress);
+typedef int (*git_diff_file_cb)(
+ const git_diff_delta *delta,
+ float progress,
+ void *payload);
/**
* Structure describing a hunk of a diff.
*/
typedef struct {
- int old_start;
- int old_lines;
- int new_start;
- int new_lines;
+ 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 */
} git_diff_range;
/**
* When iterating over a diff, callback that will be made per hunk.
*/
-typedef int (*git_diff_hunk_fn)(
- void *cb_data,
- git_diff_delta *delta,
- git_diff_range *range,
+typedef int (*git_diff_hunk_cb)(
+ const git_diff_delta *delta,
+ const git_diff_range *range,
const char *header,
- size_t header_len);
+ size_t header_len,
+ void *payload);
/**
* Line origin constants.
*
* These values describe where a line came from and will be passed to
- * the git_diff_data_fn when iterating over a diff. There are some
- * special origin contants at the end that are used for the text
+ * the git_diff_data_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.
*/
-enum {
- /* these values will be sent to `git_diff_data_fn` along with the line */
+typedef enum {
+ /* These values will be sent to `git_diff_data_cb` along with the line */
GIT_DIFF_LINE_CONTEXT = ' ',
GIT_DIFF_LINE_ADDITION = '+',
GIT_DIFF_LINE_DELETION = '-',
- GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< LF was added at end of file */
+ GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */
GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */
- /* these values will only be sent to a `git_diff_data_fn` when the content
- * of a diff is being formatted (eg. through git_diff_print_patch() or
- * git_diff_print_compact(), for instance).
+
+ /* The following values will only be sent to a `git_diff_data_cb` when
+ * the content of a diff is being formatted (eg. through
+ * git_diff_print_patch() or git_diff_print_compact(), for instance).
*/
GIT_DIFF_LINE_FILE_HDR = 'F',
GIT_DIFF_LINE_HUNK_HDR = 'H',
GIT_DIFF_LINE_BINARY = 'B'
-};
+} git_diff_line_t;
/**
* When iterating over a diff, callback that will be made per text diff
@@ -183,13 +357,108 @@ enum {
* of text. This uses some extra GIT_DIFF_LINE_... constants for output
* of lines of file and hunk headers.
*/
-typedef int (*git_diff_data_fn)(
- void *cb_data,
- git_diff_delta *delta,
- git_diff_range *range,
- char line_origin, /**< GIT_DIFF_LINE_... value from above */
- const char *content,
- size_t content_len);
+typedef int (*git_diff_data_cb)(
+ const git_diff_delta *delta, /** delta that contains this data */
+ const git_diff_range *range, /** range of lines containing this data */
+ char line_origin, /** git_diff_list_t value from above */
+ const char *content, /** diff data - not NUL terminated */
+ size_t content_len, /** number of bytes of diff data */
+ void *payload); /** user reference data */
+
+/**
+ * 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_diff_patch git_diff_patch;
+
+/**
+ * Flags to control the behavior of diff rename/copy detection.
+ */
+typedef enum {
+ /** look for renames? (`--find-renames`) */
+ GIT_DIFF_FIND_RENAMES = (1 << 0),
+ /** consider old side of modified for renames? (`--break-rewrites=N`) */
+ GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1 << 1),
+
+ /** look for copies? (a la `--find-copies`) */
+ GIT_DIFF_FIND_COPIES = (1 << 2),
+ /** consider unmodified as copy sources? (`--find-copies-harder`) */
+ GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3),
+
+ /** split large rewrites into delete/add pairs (`--break-rewrites=/M`) */
+ GIT_DIFF_FIND_AND_BREAK_REWRITES = (1 << 4),
+
+ /** turn on all finding features */
+ GIT_DIFF_FIND_ALL = (0x1f),
+
+ /** measure similarity ignoring leading whitespace (default) */
+ GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
+ /** measure similarity ignoring all whitespace */
+ GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 6),
+ /** measure similarity including all data */
+ GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 7),
+} git_diff_find_t;
+
+/**
+ * Pluggable similarity metric
+ */
+typedef struct {
+ int (*file_signature)(
+ void **out, const git_diff_file *file,
+ const char *fullpath, void *payload);
+ int (*buffer_signature)(
+ void **out, const git_diff_file *file,
+ const char *buf, size_t buflen, void *payload);
+ void (*free_signature)(void *sig, void *payload);
+ int (*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.
+ *
+ * - `rename_threshold` is the same as the -M option with a value
+ * - `copy_threshold` is the same as the -C option with a value
+ * - `rename_from_rewrite_threshold` matches the top of the -B option
+ * - `break_rewrite_threshold` matches the bottom of the -B option
+ * - `target_limit` matches the -l option
+ *
+ * The `metric` option allows you to plug in a custom similarity metric.
+ * Set it to NULL for the default internal metric which is based on sampling
+ * hashes of ranges of data in the file. The default metric is a pretty
+ * good similarity approximation that should work fairly well for both text
+ * and binary data, and is pretty fast with fixed memory overhead.
+ */
+typedef struct {
+ unsigned int version;
+
+ /** Combination of git_diff_find_t values (default FIND_RENAMES) */
+ unsigned int flags;
+
+ /** Similarity to consider a file renamed (default 50) */
+ unsigned int rename_threshold;
+ /** Similarity of modified to be eligible rename source (default 50) */
+ unsigned int rename_from_rewrite_threshold;
+ /** Similarity to consider a file a copy (default 50) */
+ unsigned int copy_threshold;
+ /** Similarity to split modify into delete/add pair (default 60) */
+ unsigned int break_rewrite_threshold;
+
+ /** Maximum similarity sources to examine (a la diff's `-l` option or
+ * the `diff.renameLimit` config) (default 200)
+ */
+ unsigned int target_limit;
+
+ /** Pluggable similarity metric; pass NULL to use internal metric */
+ 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}
/** @name Diff List Generator Functions
*
@@ -204,69 +473,104 @@ typedef int (*git_diff_data_fn)(
GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff);
/**
- * Compute a difference between two tree objects.
+ * Create a diff list 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.
*
+ * @param diff Output pointer to a git_diff_list pointer to be allocated.
* @param repo The repository containing the trees.
- * @param opts Structure with options to influence diff or NULL for defaults.
* @param old_tree A git_tree object to diff from.
* @param new_tree A git_tree object to diff to.
- * @param diff A pointer to a git_diff_list pointer that will be allocated.
+ * @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_tree(
+ git_diff_list **diff,
git_repository *repo,
- const git_diff_options *opts, /**< can be NULL for defaults */
git_tree *old_tree,
git_tree *new_tree,
- git_diff_list **diff);
+ const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Compute a difference between a tree and the index.
+ * Create a diff list 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.
+ *
+ * @param diff Output pointer to a git_diff_list pointer to be allocated.
* @param repo The repository containing the tree and index.
- * @param opts Structure with options to influence diff or NULL for defaults.
* @param old_tree A git_tree object to diff from.
- * @param diff A pointer to a git_diff_list pointer that will be allocated.
+ * @param index The index to diff with; repo index used if NULL.
+ * @param opts Structure with options to influence diff or NULL for defaults.
*/
-GIT_EXTERN(int) git_diff_index_to_tree(
+GIT_EXTERN(int) git_diff_tree_to_index(
+ git_diff_list **diff,
git_repository *repo,
- const git_diff_options *opts, /**< can be NULL for defaults */
git_tree *old_tree,
- git_diff_list **diff);
+ git_index *index,
+ const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Compute a difference between the working directory and the index.
+ * Create a diff list 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.
+ *
+ * @param diff Output pointer to a git_diff_list 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.
- * @param diff A pointer to a git_diff_list pointer that will be allocated.
*/
-GIT_EXTERN(int) git_diff_workdir_to_index(
+GIT_EXTERN(int) git_diff_index_to_workdir(
+ git_diff_list **diff,
git_repository *repo,
- const git_diff_options *opts, /**< can be NULL for defaults */
- git_diff_list **diff);
+ git_index *index,
+ const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Compute a difference between the working directory and a tree.
+ * Create a diff list 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.
+ *
+ * Please note: this is *NOT* the same as `git diff <treeish>`. Running
+ * `git diff HEAD` or the like actually uses information from the index,
+ * along with the tree and working directory info.
+ *
+ * This function returns strictly the differences between the tree and the
+ * files contained in the working directory, regardless of the state of
+ * files in the index. It may come as a surprise, but there is no direct
+ * equivalent in core git.
*
- * This returns strictly the differences between the tree and the
- * files contained in the working directory, regardless of the state
- * of files in the index. There is no direct equivalent in C git.
+ * To emulate `git diff <treeish>`, call both `git_diff_tree_to_index` and
+ * `git_diff_index_to_workdir`, then call `git_diff_merge` on the results.
+ * That will yield a `git_diff_list` that matches the git output.
*
- * This is *NOT* the same as 'git diff HEAD' or 'git diff <SHA>'. Those
- * commands diff the tree, the index, and the workdir. To emulate those
- * functions, call `git_diff_index_to_tree` and `git_diff_workdir_to_index`,
- * then call `git_diff_merge` on the results.
+ * If this seems confusing, take the case of a file with a staged deletion
+ * where the file has then been put back into the working dir and modified.
+ * The tree-to-workdir diff for that file is 'modified', but core git would
+ * show status 'deleted' since there is a pending deletion in the index.
*
+ * @param diff A pointer to a git_diff_list pointer that will be allocated.
* @param repo The repository containing the tree.
- * @param opts Structure with options to influence diff or NULL for defaults.
* @param old_tree A git_tree object to diff from.
- * @param diff A pointer to a git_diff_list pointer that will be allocated.
+ * @param opts Structure with options to influence diff or NULL for defaults.
*/
-GIT_EXTERN(int) git_diff_workdir_to_tree(
+GIT_EXTERN(int) git_diff_tree_to_workdir(
+ git_diff_list **diff,
git_repository *repo,
- const git_diff_options *opts, /**< can be NULL for defaults */
git_tree *old_tree,
- git_diff_list **diff);
+ const git_diff_options *opts); /**< can be NULL for defaults */
/**
* Merge one diff list into another.
@@ -285,6 +589,22 @@ GIT_EXTERN(int) git_diff_merge(
git_diff_list *onto,
const git_diff_list *from);
+/**
+ * Transform a diff list marking file renames, copies, etc.
+ *
+ * This modifies a diff list 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 list 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_list *diff,
+ git_diff_find_options *options);
+
/**@}*/
@@ -296,37 +616,273 @@ GIT_EXTERN(int) git_diff_merge(
/**@{*/
/**
- * Iterate over a diff list issuing callbacks.
+ * Loop over all deltas in a diff list 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 list or for
+ * files whose only changed is a file mode change.
*
- * If the hunk and/or line callbacks are not NULL, then this will calculate
- * text diffs for all files it thinks are not binary. If those are both
- * NULL, then this will not bother with the text diffs, so it can be
- * efficient.
+ * Returning a non-zero value from any of the callbacks will terminate
+ * the iteration and cause this return `GIT_EUSER`.
+ *
+ * @param diff A git_diff_list generated by one of the above functions.
+ * @param file_cb Callback function to make per file in the diff.
+ * @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, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_diff_foreach(
git_diff_list *diff,
- void *cb_data,
- git_diff_file_fn file_cb,
- git_diff_hunk_fn hunk_cb,
- git_diff_data_fn line_cb);
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_data_cb line_cb,
+ void *payload);
/**
* Iterate over a diff generating text output like "git diff --name-status".
+ *
+ * Returning a non-zero value from the callbacks will terminate the
+ * iteration and cause this return `GIT_EUSER`.
+ *
+ * @param diff A git_diff_list generated by one of the above functions.
+ * @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, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_diff_print_compact(
git_diff_list *diff,
- void *cb_data,
- git_diff_data_fn print_cb);
+ git_diff_data_cb print_cb,
+ void *payload);
+
+/**
+ * Look up the single character abbreviation for a delta status code.
+ *
+ * When you call `git_diff_print_compact` it prints single letter codes into
+ * the output such as 'A' for added, 'D' for deleted, 'M' for modified, etc.
+ * It is sometimes convenient to convert a git_delta_t value into these
+ * letters for your own purposes. This function does just that. By the
+ * way, unmodified will return a space (i.e. ' ').
+ *
+ * @param delta_t 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);
/**
* Iterate over a diff generating text output like "git diff".
*
* This is a super easy way to generate a patch from a diff.
+ *
+ * Returning a non-zero value from the callbacks will terminate the
+ * iteration and cause this return `GIT_EUSER`.
+ *
+ * @param diff A git_diff_list generated by one of the above functions.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @param print_cb Callback function to output lines of the diff. This
+ * same function will be called for file headers, hunk
+ * headers, and diff lines. Fortunately, you can probably
+ * use various GIT_DIFF_LINE constants to determine what
+ * text you are given.
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_diff_print_patch(
git_diff_list *diff,
- void *cb_data,
- git_diff_data_fn print_cb);
+ git_diff_data_cb print_cb,
+ void *payload);
+
+/**
+ * Query how many diff records are there in a diff list.
+ *
+ * @param diff A git_diff_list generated by one of the above functions
+ * @return Count of number of deltas in the list
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas(git_diff_list *diff);
+
+/**
+ * Query how many diff deltas are there in a diff list filtered by type.
+ *
+ * This works just like `git_diff_entrycount()` 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_list 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(
+ git_diff_list *diff,
+ git_delta_t type);
+
+/**
+ * Return the diff delta and patch for an entry in the diff list.
+ *
+ * The `git_diff_patch` is a newly created object contains the text diffs
+ * for the delta. You have to call `git_diff_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_diff_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.
+ *
+ * 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_list` and `git_diff_patch` go away.
+ *
+ * It is okay to pass NULL for either of the output parameters; if you pass
+ * NULL for the `git_diff_patch`, then the text diff will not be calculated.
+ *
+ * @param patch_out Output parameter for the delta patch object
+ * @param delta_out Output parameter for the delta 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_diff_get_patch(
+ git_diff_patch **patch_out,
+ const git_diff_delta **delta_out,
+ git_diff_list *diff,
+ size_t idx);
+
+/**
+ * Free a git_diff_patch object.
+ */
+GIT_EXTERN(void) git_diff_patch_free(
+ git_diff_patch *patch);
+
+/**
+ * Get the delta associated with a patch
+ */
+GIT_EXTERN(const git_diff_delta *) git_diff_patch_delta(
+ git_diff_patch *patch);
+
+/**
+ * Get the number of hunks in a patch
+ */
+GIT_EXTERN(size_t) git_diff_patch_num_hunks(
+ git_diff_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_diff_patch object
+ * @return Number of lines in hunk or -1 if invalid hunk index
+ */
+GIT_EXTERN(int) git_diff_patch_line_stats(
+ size_t *total_context,
+ size_t *total_additions,
+ size_t *total_deletions,
+ const git_diff_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 range Output pointer to git_diff_range of hunk
+ * @param header Output pointer to header string for hunk. Unlike the
+ * content pointer for each line, this will be NUL-terminated
+ * @param header_len Output value of characters in header string
+ * @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_diff_patch_get_hunk(
+ const git_diff_range **range,
+ const char **header,
+ size_t *header_len,
+ size_t *lines_in_hunk,
+ git_diff_patch *patch,
+ size_t hunk_idx);
+
+/**
+ * Get the number of lines in a hunk.
+ *
+ * @param patch The git_diff_patch object
+ * @param hunk_idx Index of the hunk
+ * @return Number of lines in hunk or -1 if invalid hunk index
+ */
+GIT_EXTERN(int) git_diff_patch_num_lines_in_hunk(
+ git_diff_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 line_origin A GIT_DIFF_LINE constant from above
+ * @param content Pointer to content of diff line, not NUL-terminated
+ * @param content_len Number of characters in content
+ * @param old_lineno Line number in old file or -1 if line is added
+ * @param new_lineno Line number in new file or -1 if line is deleted
+ * @param patch The patch to look in
+ * @param hunk_idx The index of the hunk
+ * @param line_of_index The index of the line in the hunk
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_diff_patch_get_line_in_hunk(
+ char *line_origin,
+ const char **content,
+ size_t *content_len,
+ int *old_lineno,
+ int *new_lineno,
+ git_diff_patch *patch,
+ size_t hunk_idx,
+ size_t line_of_hunk);
+
+/**
+ * Serialize the patch to text via callback.
+ *
+ * Returning a non-zero value from the callback will terminate the iteration
+ * and cause this return `GIT_EUSER`.
+ *
+ * @param patch A git_diff_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, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_diff_patch_print(
+ git_diff_patch *patch,
+ git_diff_data_cb print_cb,
+ void *payload);
+
+/**
+ * Get the content of a patch as a single diff text.
+ *
+ * @param string Allocated string; caller must free.
+ * @param patch A git_diff_patch representing changes to one file
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_diff_patch_to_str(
+ char **string,
+ git_diff_patch *patch);
/**@}*/
@@ -336,24 +892,55 @@ GIT_EXTERN(int) git_diff_print_patch(
*/
/**
- * Directly run a text diff on two blobs.
+ * Directly run a diff on two blobs.
*
- * Compared to a file, a blob lacks some contextual information. As such, the
- * `git_diff_file` parameters of the callbacks will be filled accordingly to the following:
- * `mode` will be set to 0, `path` will be set to NULL. When dealing with a NULL blob, `oid`
- * will be set to 0.
+ * 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.
*
- * When at least one of the blobs being dealt with is binary, the `git_diff_delta` binary
- * attribute will be set to 1 and no call to the hunk_cb nor line_cb will be made.
+ * 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).
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_diff_blobs(
- git_blob *old_blob,
- git_blob *new_blob,
- git_diff_options *options,
- void *cb_data,
- git_diff_file_fn file_cb,
- git_diff_hunk_fn hunk_cb,
- git_diff_data_fn line_cb);
+ const git_blob *old_blob,
+ const git_blob *new_blob,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_data_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.
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_diff_blob_to_buffer(
+ const git_blob *old_blob,
+ const char *buffer,
+ size_t buffer_len,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_data_cb data_cb,
+ void *payload);
GIT_END_DECL
diff --git a/include/git2/errors.h b/include/git2/errors.h
index fb6670004..917f0699c 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -17,43 +17,6 @@
*/
GIT_BEGIN_DECL
-#ifdef GIT_OLD_ERRORS
-enum {
- GIT_SUCCESS = 0,
- GIT_ENOTOID = -2,
- GIT_ENOTFOUND = -3,
- GIT_ENOMEM = -4,
- GIT_EOSERR = -5,
- GIT_EOBJTYPE = -6,
- GIT_ENOTAREPO = -7,
- GIT_EINVALIDTYPE = -8,
- GIT_EMISSINGOBJDATA = -9,
- GIT_EPACKCORRUPTED = -10,
- GIT_EFLOCKFAIL = -11,
- GIT_EZLIB = -12,
- GIT_EBUSY = -13,
- GIT_EBAREINDEX = -14,
- GIT_EINVALIDREFNAME = -15,
- GIT_EREFCORRUPTED = -16,
- GIT_ETOONESTEDSYMREF = -17,
- GIT_EPACKEDREFSCORRUPTED = -18,
- GIT_EINVALIDPATH = -19,
- GIT_EREVWALKOVER = -20,
- GIT_EINVALIDREFSTATE = -21,
- GIT_ENOTIMPLEMENTED = -22,
- GIT_EEXISTS = -23,
- GIT_EOVERFLOW = -24,
- GIT_ENOTNUM = -25,
- GIT_ESTREAM = -26,
- GIT_EINVALIDARGS = -27,
- GIT_EOBJCORRUPTED = -28,
- GIT_EAMBIGUOUS = -29,
- GIT_EPASSTHROUGH = -30,
- GIT_ENOMATCH = -31,
- GIT_ESHORTBUFFER = -32,
-};
-#endif
-
/** Generic return codes */
enum {
GIT_OK = 0,
@@ -62,9 +25,16 @@ enum {
GIT_EEXISTS = -4,
GIT_EAMBIGUOUS = -5,
GIT_EBUFS = -6,
+ GIT_EUSER = -7,
+ GIT_EBAREREPO = -8,
+ GIT_EORPHANEDHEAD = -9,
+ GIT_EUNMERGED = -10,
+ GIT_ENONFASTFORWARD = -11,
+ GIT_EINVALIDSPEC = -12,
+ GIT_EMERGECONFLICT = -13,
GIT_PASSTHROUGH = -30,
- GIT_REVWALKOVER = -31,
+ GIT_ITEROVER = -31,
};
typedef struct {
@@ -72,6 +42,7 @@ typedef struct {
int klass;
} git_error;
+/** Error classes */
typedef enum {
GITERR_NOMEMORY,
GITERR_OS,
@@ -88,6 +59,13 @@ typedef enum {
GITERR_TAG,
GITERR_TREE,
GITERR_INDEXER,
+ GITERR_SSL,
+ GITERR_SUBMODULE,
+ GITERR_THREAD,
+ GITERR_STASH,
+ GITERR_CHECKOUT,
+ GITERR_FETCHHEAD,
+ GITERR_MERGE,
} git_error_t;
/**
@@ -103,6 +81,40 @@ GIT_EXTERN(const git_error *) giterr_last(void);
*/
GIT_EXTERN(void) giterr_clear(void);
+/**
+ * Set the error message string for this thread.
+ *
+ * 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.
+ *
+ * NOTE: Passing the `error_class` as GITERR_OS has a special behavior: we
+ * attempt to append the system default error message for the last OS error
+ * that occurred and then clear the last error. The specific implementation
+ * of looking up and clearing this last OS error will vary by platform.
+ *
+ * @param error_class One of the `git_error_t` enum above describing the
+ * general subsystem that is responsible for the error.
+ * @param message The formatted error message to keep
+ */
+GIT_EXTERN(void) giterr_set_str(int error_class, const char *string);
+
+/**
+ * Set the error message to a special value for memory allocation failure.
+ *
+ * The normal `giterr_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) giterr_set_oom(void);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/graph.h b/include/git2/graph.h
new file mode 100644
index 000000000..a2710219e
--- /dev/null
+++ b/include/git2/graph.h
@@ -0,0 +1,41 @@
+/*
+ * 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
+ */
+GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/ignore.h b/include/git2/ignore.h
new file mode 100644
index 000000000..d0c1877a8
--- /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, a la the contents of 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 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, 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
index 6a42c8515..3d4bd15a8 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -8,6 +8,7 @@
#define INCLUDE_git_index_h__
#include "common.h"
+#include "indexer.h"
#include "types.h"
#include "oid.h"
@@ -20,10 +21,10 @@
*/
GIT_BEGIN_DECL
-#define GIT_IDXENTRY_NAMEMASK (0x0fff)
+#define GIT_IDXENTRY_NAMEMASK (0x0fff)
#define GIT_IDXENTRY_STAGEMASK (0x3000)
-#define GIT_IDXENTRY_EXTENDED (0x4000)
-#define GIT_IDXENTRY_VALID (0x8000)
+#define GIT_IDXENTRY_EXTENDED (0x4000)
+#define GIT_IDXENTRY_VALID (0x8000)
#define GIT_IDXENTRY_STAGESHIFT 12
/*
@@ -33,26 +34,26 @@ GIT_BEGIN_DECL
*
* In-memory only flags:
*/
-#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_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) /* remove in work directory */
-#define GIT_IDXENTRY_CONFLICTED (1 << 7)
+#define GIT_IDXENTRY_HASHED (1 << 4)
+#define GIT_IDXENTRY_UNHASHED (1 << 5)
+#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */
+#define GIT_IDXENTRY_CONFLICTED (1 << 7)
-#define GIT_IDXENTRY_UNPACKED (1 << 8)
+#define GIT_IDXENTRY_UNPACKED (1 << 8)
#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
/*
* Extended on-disk flags:
*/
-#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
-#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
+#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
+#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
/* GIT_IDXENTRY_EXTENDED2 is for future extension */
-#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
+#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
@@ -83,12 +84,26 @@ typedef struct git_index_entry {
char *path;
} git_index_entry;
-/** Representation of an unmerged file entry in the index. */
-typedef struct git_index_entry_unmerged {
+/** Representation of a resolve undo entry in the index. */
+typedef struct git_index_reuc_entry {
unsigned int mode[3];
git_oid oid[3];
char *path;
-} git_index_entry_unmerged;
+} git_index_reuc_entry;
+
+/** Capabilities of system that affect index actions. */
+enum {
+ GIT_INDEXCAP_IGNORE_CASE = 1,
+ GIT_INDEXCAP_NO_FILEMODE = 2,
+ GIT_INDEXCAP_NO_SYMLINKS = 4,
+ GIT_INDEXCAP_FROM_OWNER = ~0u
+};
+
+/** @name Index File Functions
+ *
+ * These functions work on the index file itself.
+ */
+/**@{*/
/**
* Create a new bare Git index object as a memory representation
@@ -104,20 +119,24 @@ typedef struct git_index_entry_unmerged {
*
* The index must be freed once it's no longer in use.
*
- * @param index the pointer for the new index
+ * @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
*/
-GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path);
+GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
/**
- * Clear the contents (all the entries) of an index object.
- * This clears the index object in memory; changes must be manually
- * written to disk for them to take effect.
+ * Create an in-memory index object.
*
- * @param index an existing 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
*/
-GIT_EXTERN(void) git_index_clear(git_index *index);
+GIT_EXTERN(int) git_index_new(git_index **out);
/**
* Free an existing index object.
@@ -127,6 +146,35 @@ GIT_EXTERN(void) git_index_clear(git_index *index);
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_INDEXCAP values
+ */
+GIT_EXTERN(unsigned int) git_index_caps(const git_index *index);
+
+/**
+ * Set index capabilities flags.
+ *
+ * If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the
+ * 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_INDEXCAP values
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_index_set_caps(git_index *index, unsigned int caps);
+
+/**
* Update the contents of an existing index object in memory
* by reading from the hard disk.
*
@@ -145,44 +193,143 @@ GIT_EXTERN(int) git_index_read(git_index *index);
GIT_EXTERN(int) git_index_write(git_index *index);
/**
- * Find the first index of any entries which point to given
- * path in the Git index.
+ * 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 path path to search
- * @return an index >= 0 if found, -1 otherwise
+ * @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_find(git_index *index, const char *path);
+GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index);
/**
- * Remove all entries with equal path except last added
+ * 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 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(void) git_index_uniq(git_index *index);
+GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
/**
- * Add or update an index entry from a file in disk
+ * Clear the contents (all the entries) of an index object.
+ * This clears the index object in memory; changes must be manually
+ * written to disk for them to take effect.
*
- * The file `path` must be relative to the repository's
- * working folder and must be readable.
+ * @param index an existing index object
+ */
+GIT_EXTERN(void) git_index_clear(git_index *index);
+
+/**
+ * Get a pointer to one of the entries in the index
*
- * This method will fail in bare index instances.
+ * The values of this entry can be modified (except the path)
+ * and the changes will be written back to disk on the next
+ * write() call.
*
- * 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.
+ * The entry should not be freed by the caller.
*
* @param index an existing index object
- * @param path filename to add
- * @param stage stage for the entry
+ * @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 values of this entry can be modified (except the path)
+ * and the changes will be written back to disk on the next
+ * write() call.
+ *
+ * The entry should not be freed by the caller.
+ *
+ * @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_add(git_index *index, const char *path, int stage);
+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.
*
@@ -190,131 +337,242 @@ GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
* @param source_entry new entry object
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry);
+GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry);
/**
- * Add (append) an index entry from a file in disk
+ * Return the stage number from a git index entry
+ *
+ * This entry is calculated from the entry's flag
+ * attribute like this:
+ *
+ * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
*
- * A new entry will always be inserted into the index;
- * if the index already contains an entry for such
- * path, the old entry will **not** be replaced.
+ * @param entry The entry
+ * @returns the stage number
+ */
+GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
+
+/**@}*/
+
+/** @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
- * @param stage stage for the entry
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
+GIT_EXTERN(int) git_index_add_bypath(git_index *index, const char *path);
/**
- * Add (append) an index entry from an in-memory struct
+ * Remove an index entry corresponding to a file on disk
*
- * A new entry will always be inserted into the index;
- * if the index already contains an entry for the path
- * in the `entry` struct, the old entry will **not** be
- * replaced.
+ * The file `path` must be relative to the repository's
+ * working folder. It may exist.
*
- * A full copy (including the 'path' string) of the given
- * 'source_entry' will be inserted on the index.
+ * 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 source_entry new entry object
+ * @param path filename to remove
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry);
+GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
/**
- * Remove an entry from the index
+ * 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 position position of the entry to remove
- * @return 0 or an error code
+ * @param path path to search
+ * @return a zero-based position in the index if found;
+ * GIT_ENOTFOUND otherwise
*/
-GIT_EXTERN(int) git_index_remove(git_index *index, int position);
+GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
+
+/**@}*/
+/** @name Conflict Index Entry Functions
+ *
+ * These functions work on conflict index entries specifically (ie, stages 1-3)
+ */
+/**@{*/
/**
- * Get a pointer to one of the entries in the index
+ * Add or update index entries to represent a conflict
*
- * This entry can be modified, and the changes will be written
- * back to disk on the next write() call.
+ * 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.
*
- * The entry should not be freed by the caller.
+ * @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 values of this entry can be modified (except the paths)
+ * and the changes will be written back to disk on the next
+ * write() call.
+ *
+ * @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 n the position of the entry
- * @return a pointer to the entry; NULL if out of bounds
+ * @param path path to search
*/
-GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, unsigned int n);
+GIT_EXTERN(int) git_index_conflict_get(git_index_entry **ancestor_out, git_index_entry **our_out, git_index_entry **their_out, git_index *index, const char *path);
/**
- * Get the count of entries currently in the index
+ * Removes the index entries that represent a conflict of a single file.
*
* @param index an existing index object
- * @return integer of count of current entries
+ * @param path to search
+ */
+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
+ */
+GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index);
+
+/**
+ * Determine if the index contains entries representing file conflicts.
+ *
+ * @return 1 if at least one conflict is found, 0 otherwise.
+ */
+GIT_EXTERN(int) git_index_has_conflicts(const 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(unsigned int) git_index_entrycount(git_index *index);
+GIT_EXTERN(unsigned int) git_index_reuc_entrycount(git_index *index);
/**
- * Get the count of unmerged entries currently in the 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
- * @return integer of count of current unmerged entries
+ * @param path path to search
+ * @return 0 if found, < 0 otherwise (GIT_ENOTFOUND)
*/
-GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index);
+GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path);
/**
- * Get an unmerged entry from the index.
+ * Get a resolve undo entry from the index.
*
* The returned entry is read-only and should not be modified
- * of freed by the caller.
+ * or freed by the caller.
*
* @param index an existing index object
* @param path path to search
- * @return the unmerged entry; NULL if not found
+ * @return the resolve undo entry; NULL if not found
*/
-GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_bypath(git_index *index, const char *path);
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path);
/**
- * Get an unmerged entry from the index.
+ * Get a resolve undo entry from the index.
*
* The returned entry is read-only and should not be modified
- * of freed by the caller.
+ * or freed by the caller.
*
* @param index an existing index object
* @param n the position of the entry
- * @return a pointer to the unmerged entry; NULL if out of bounds
+ * @return a pointer to the resolve undo entry; NULL if out of bounds
*/
-GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_index *index, unsigned int n);
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n);
/**
- * Return the stage number from a git index entry
+ * Adds a resolve undo entry for a file based on the given parameters.
*
- * This entry is calculated from the entrie's flag
- * attribute like this:
+ * 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.
*
- * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
+ * If there exists a resolve undo entry for the given path in the index,
+ * it will be removed.
*
- * @param entry The entry
- * @returns the stage number
+ * 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_entry_stage(const git_index_entry *entry);
+GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path,
+ int ancestor_mode, git_oid *ancestor_id,
+ int our_mode, git_oid *our_id,
+ int their_mode, git_oid *their_id);
/**
- * Read a tree into the index file
+ * Remove an resolve undo entry from the index
*
- * The current index contents will be replaced by the specified tree.
+ * @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
- * @param tree tree to read
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree);
+GIT_EXTERN(void) git_index_reuc_clear(git_index *index);
+
+/**@}*/
/** @} */
GIT_END_DECL
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index 14bd0e402..dfe6ae5aa 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -16,32 +16,48 @@ GIT_BEGIN_DECL
* This is passed as the first argument to the callback to allow the
* user to see the progress.
*/
-typedef struct git_indexer_stats {
- unsigned int total;
- unsigned int processed;
-} git_indexer_stats;
+typedef struct git_transfer_progress {
+ unsigned int total_objects;
+ unsigned int indexed_objects;
+ unsigned int received_objects;
+ size_t received_bytes;
+} git_transfer_progress;
-typedef struct git_indexer git_indexer;
+/**
+ * Type for progress callbacks during indexing. Return a value less than zero
+ * to cancel the transfer.
+ *
+ * @param stats Structure containing information about the state of the transfer
+ * @param payload Payload provided by caller
+ */
+typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
+
typedef struct git_indexer_stream git_indexer_stream;
/**
* Create a new streaming indexer instance
*
- * @param out where to store the inexer instance
- * @param path to the gitdir (metadata directory)
+ * @param out where to store the indexer instance
+ * @param path to the directory where the packfile should be stored
+ * @param progress_cb function to call with progress information
+ * @param progress_payload payload for the progress callback
*/
-GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *gitdir);
+GIT_EXTERN(int) git_indexer_stream_new(
+ git_indexer_stream **out,
+ const char *path,
+ git_transfer_progress_callback progress_cb,
+ void *progress_cb_payload);
/**
* Add data to the indexer
*
* @param idx the indexer
* @param data the data to add
- * @param size the size of the data
+ * @param size the size of the data in bytes
* @param stats stat storage
*/
-GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats);
+GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_transfer_progress *stats);
/**
* Finalize the pack and index
@@ -50,7 +66,7 @@ GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data
*
* @param idx the indexer
*/
-GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stats);
+GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress *stats);
/**
* Get the packfile's hash
@@ -60,7 +76,7 @@ GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer
*
* @param idx the indexer instance
*/
-GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx);
+GIT_EXTERN(const git_oid *) git_indexer_stream_hash(const git_indexer_stream *idx);
/**
* Free the indexer and its resources
@@ -69,53 +85,6 @@ GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx);
*/
GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx);
-/**
- * Create a new indexer instance
- *
- * @param out where to store the indexer instance
- * @param packname the absolute filename of the packfile to index
- */
-GIT_EXTERN(int) git_indexer_new(git_indexer **out, const char *packname);
-
-/**
- * Iterate over the objects in the packfile and extract the information
- *
- * Indexing a packfile can be very expensive so this function is
- * expected to be run in a worker thread and the stats used to provide
- * feedback the user.
- *
- * @param idx the indexer instance
- * @param stats storage for the running state
- */
-GIT_EXTERN(int) git_indexer_run(git_indexer *idx, git_indexer_stats *stats);
-
-/**
- * Write the index file to disk.
- *
- * The file will be stored as pack-$hash.idx in the same directory as
- * the packfile.
- *
- * @param idx the indexer instance
- */
-GIT_EXTERN(int) git_indexer_write(git_indexer *idx);
-
-/**
- * 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 written to disk.
- *
- * @param idx the indexer instance
- */
-GIT_EXTERN(const git_oid *) git_indexer_hash(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/inttypes.h b/include/git2/inttypes.h
index ead903f78..716084219 100644
--- a/include/git2/inttypes.h
+++ b/include/git2/inttypes.h
@@ -40,7 +40,11 @@
#pragma once
#endif
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
#include "stdint.h"
+#endif
// 7.8 Format conversion of integer types
diff --git a/include/git2/merge.h b/include/git2/merge.h
index 5a0b2e7f2..f4c5d9881 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -27,8 +27,28 @@ GIT_BEGIN_DECL
* @param repo the repository where the commits exist
* @param one one of the commits
* @param two the other commit
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
*/
-GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, git_oid *one, git_oid *two);
+GIT_EXTERN(int) git_merge_base(
+ git_oid *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 input_array oids of the commits
+ * @param length The number of commits in the provided `input_array`
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_many(
+ git_oid *out,
+ git_repository *repo,
+ const git_oid input_array[],
+ size_t length);
/** @} */
GIT_END_DECL
diff --git a/include/git2/message.h b/include/git2/message.h
new file mode 100644
index 000000000..395c88690
--- /dev/null
+++ b/include/git2/message.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_git_message_h__
+#define INCLUDE_git_message_h__
+
+#include "common.h"
+
+/**
+ * @file git2/message.h
+ * @brief Git message management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Clean up message from excess whitespace and make sure that the last line
+ * ends with a '\n'.
+ *
+ * Optionally, can remove lines starting with a "#".
+ *
+ * @param out The user-allocated buffer which will be filled with the
+ * cleaned up message. Pass NULL if you just want to get the needed
+ * size of the prettified message as the output value.
+ *
+ * @param out_size Size of the `out` buffer in bytes.
+ *
+ * @param message The message to be prettified.
+ *
+ * @param strip_comments Non-zero to remove lines starting with "#", 0 to
+ * leave them in.
+ *
+ * @return -1 on error, else number of characters in prettified message
+ * including the trailing NUL byte
+ */
+GIT_EXTERN(int) git_message_prettify(
+ char *out,
+ size_t out_size,
+ const char *message,
+ int strip_comments);
+
+/** @} */
+GIT_END_DECL
+
+#endif /* INCLUDE_git_message_h__ */
diff --git a/include/git2/net.h b/include/git2/net.h
index c2301b6f1..e70ba1f71 100644
--- a/include/git2/net.h
+++ b/include/git2/net.h
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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_net_h__
-#define INCLUDE_net_h__
+#ifndef INCLUDE_git_net_h__
+#define INCLUDE_git_net_h__
#include "common.h"
#include "oid.h"
@@ -27,15 +27,17 @@ GIT_BEGIN_DECL
* gets called.
*/
-#define GIT_DIR_FETCH 0
-#define GIT_DIR_PUSH 1
+typedef enum {
+ GIT_DIRECTION_FETCH = 0,
+ GIT_DIRECTION_PUSH = 1
+} git_direction;
/**
* Remote head description, given out on `ls` calls.
*/
struct git_remote_head {
- int local:1; /* available locally */
+ int local; /* available locally */
git_oid oid;
git_oid loid;
char *name;
@@ -44,7 +46,7 @@ struct git_remote_head {
/**
* Callback for listing the remote heads
*/
-typedef int (*git_headlist_cb)(git_remote_head *, void *);
+typedef int (*git_headlist_cb)(git_remote_head *rhead, void *payload);
/** @} */
GIT_END_DECL
diff --git a/include/git2/notes.h b/include/git2/notes.h
index 19073abd1..7382904ad 100644
--- a/include/git2/notes.h
+++ b/include/git2/notes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -19,19 +19,82 @@
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_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);
+
+/**
+ * Frees an git_note_iterator
+ *
+ * @param it pointer to the iterator
+ */
+GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it);
+
+/**
+ * Returns the current item (note_id and annotated_id) and advance the iterator
+ * internally to the next value
+ *
+ * The notes must not be freed manually by the user.
+ *
+ * @param it pointer to the iterator
+ * @param note_id id of blob containing the message
+ * @param annotated_id id of the git object being annotated
+ *
+ * @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 note the note; NULL in case of error
- * @param repo the Git repository
- * @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
- * @param oid OID of the object
+ * @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 **note, git_repository *repo,
- const char *notes_ref, const git_oid *oid);
+GIT_EXTERN(int) git_note_read(
+ git_note **out,
+ git_repository *repo,
+ const char *notes_ref,
+ const git_oid *oid);
/**
* Get the note message
@@ -39,7 +102,7 @@ GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo,
* @param note
* @return the note message
*/
-GIT_EXTERN(const char *) git_note_message(git_note *note);
+GIT_EXTERN(const char *) git_note_message(const git_note *note);
/**
@@ -48,42 +111,52 @@ GIT_EXTERN(const char *) git_note_message(git_note *note);
* @param note
* @return the note object OID
*/
-GIT_EXTERN(const git_oid *) git_note_oid(git_note *note);
-
+GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note);
/**
* Add a note for an object
*
- * @param oid pointer to store the OID (optional); NULL in case of error
- * @param repo the Git repository
+ * @param out pointer to store the OID (optional); NULL in case of error
+ * @param repo repository where to store the note
* @param author signature of the notes commit author
* @param committer signature of the notes commit committer
- * @param notes_ref OID reference to update (optional); defaults to "refs/notes/commits"
- * @param oid The OID of the object
- * @param oid The note to add for object oid
+ * @param notes_ref canonical name of the reference to use (optional);
+ * defaults to "refs/notes/commits"
+ * @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,
- git_signature *author, git_signature *committer,
- const char *notes_ref, const git_oid *oid,
- const char *note);
+GIT_EXTERN(int) git_note_create(
+ git_oid *out,
+ git_repository *repo,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *notes_ref,
+ const git_oid *oid,
+ const char *note,
+ int force);
/**
* Remove the note for an object
*
- * @param repo the Git repository
- * @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
+ * @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 the oid which note's to be removed
+ * @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,
- git_signature *author, git_signature *committer,
- const git_oid *oid);
+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);
/**
* Free a git_note object
@@ -103,36 +176,26 @@ GIT_EXTERN(void) git_note_free(git_note *note);
GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo);
/**
- * Basic components of a note
- *
- * - Oid of the blob containing the message
- * - Oid of the git object being annotated
- */
-typedef struct {
- git_oid blob_oid;
- git_oid annotated_object_oid;
-} git_note_data;
-
-/**
* 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 OID reference to read from (optional); defaults to "refs/notes/commits".
+ * @param notes_ref Reference to read from (optional); defaults to
+ * "refs/notes/commits".
*
- * @param note_cb Callback to invoke per found annotation.
+ * @param note_cb Callback to invoke per found annotation. Return non-zero
+ * to stop looping.
*
* @param payload Extra parameter to callback function.
*
- * @return 0 or an error code.
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_note_foreach(
- git_repository *repo,
- const char *notes_ref,
- int (*note_cb)(git_note_data *note_data, void *payload),
- void *payload
-);
+ git_repository *repo,
+ const char *notes_ref,
+ git_note_foreach_cb note_cb,
+ void *payload);
/** @} */
GIT_END_DECL
diff --git a/include/git2/object.h b/include/git2/object.h
index 9e988b7b6..b91b04dba 100644
--- a/include/git2/object.h
+++ b/include/git2/object.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -21,7 +21,7 @@
GIT_BEGIN_DECL
/**
- * Lookup a reference to one of the objects in a repostory.
+ * 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
@@ -45,7 +45,7 @@ GIT_EXTERN(int) git_object_lookup(
git_otype type);
/**
- * Lookup a reference to one of the objects in a repostory,
+ * 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
@@ -75,7 +75,7 @@ GIT_EXTERN(int) git_object_lookup_prefix(
git_object **object_out,
git_repository *repo,
const git_oid *id,
- unsigned int len,
+ size_t len,
git_otype type);
/**
@@ -114,7 +114,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
* 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 agressive is the caching mechanism used
+ * depending on how aggressive is the caching mechanism used
* by the repository.
*
* IMPORTANT:
@@ -167,6 +167,36 @@ GIT_EXTERN(int) git_object_typeisloose(git_otype type);
*/
GIT_EXTERN(size_t) git_object__size(git_otype type);
+/**
+ * Recursively peel an object until an object of the specified type is met.
+ *
+ * The retrieved `peeled` object is owned by the repository and should be
+ * closed with the `git_object_free` method.
+ *
+ * If you pass `GIT_OBJ_ANY` as the target type, then the object will be
+ * peeled until the type changes (e.g. a tag will be chased until the
+ * referenced object is no longer a tag).
+ *
+ * @param peeled Pointer to the peeled git_object
+ * @param object The object to be processed
+ * @param target_type The type of the requested object (GIT_OBJ_COMMIT,
+ * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY).
+ * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
+ */
+GIT_EXTERN(int) git_object_peel(
+ git_object **peeled,
+ const git_object *object,
+ git_otype 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
+ */
+GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
+
/** @} */
GIT_END_DECL
diff --git a/include/git2/odb.h b/include/git2/odb.h
index 1df193389..8fd1a95be 100644
--- a/include/git2/odb.h
+++ b/include/git2/odb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -11,6 +11,7 @@
#include "types.h"
#include "oid.h"
#include "odb_backend.h"
+#include "indexer.h"
/**
* @file git2/odb.h
@@ -62,7 +63,7 @@ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
* @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 sucess; error code otherwise
+ * @return 0 on success; error code otherwise
*/
GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
@@ -83,11 +84,28 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int
* @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 sucess; error code otherwise
+ * @return 0 on success; error code otherwise
*/
GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
/**
+ * 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.
@@ -135,11 +153,12 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i
* @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)
+ * @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, unsigned int len);
+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
@@ -151,15 +170,15 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git
* of an object, so the whole object will be read and then the
* header will be returned.
*
- * @param len_p pointer where to store the length
- * @param type_p pointer where to store the type
+ * @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_p, git_otype *type_p, git_odb *db, const git_oid *id);
+GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id);
/**
* Determine if the given object can be found in the object database.
@@ -173,6 +192,41 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *d
GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
/**
+ * 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, GIT_EUSER on non-zero callback, 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.
@@ -183,14 +237,14 @@ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
* This method is provided for compatibility with custom backends
* which are not able to support streaming writes
*
- * @param oid pointer to store the OID result of the write
+ * @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 storr
+ * @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 *oid, git_odb *odb, const void *data, size_t len, git_otype type);
+GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type);
/**
* Open a stream to write an object into the ODB
@@ -213,13 +267,13 @@ GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size
*
* @see git_odb_stream
*
- * @param stream pointer where to store the 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 **stream, git_odb *db, size_t size, git_otype type);
+GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type);
/**
* Open a stream to read an object from the ODB
@@ -240,32 +294,58 @@ GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_
*
* @see git_odb_stream
*
- * @param stream pointer where to store the stream
+ * @param out pointer where to store the stream
* @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 **stream, git_odb *db, const git_oid *oid);
+GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, 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
+ */
+GIT_EXTERN(int) git_odb_write_pack(
+ git_odb_writepack **out,
+ git_odb *db,
+ git_transfer_progress_callback progress_cb,
+ void *progress_payload);
/**
* Determine the object-ID (sha1 hash) of a data buffer
*
- * The resulting SHA-1 OID will the itentifier for the data
+ * The resulting SHA-1 OID will be the identifier for the data
* buffer as if the data buffer it were to written to the ODB.
*
- * @param id the resulting object-ID.
+ * @param out the resulting object-ID.
* @param data data to hash
* @param len size of the data
* @param type of the data to hash
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type);
+GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_otype type);
/**
* 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. Similar functionality
- * to git.git's `git hash-object` without the `-w` flag.
+ * 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
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index f4620f5f4..dbc3981f6 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -10,6 +10,7 @@
#include "common.h"
#include "types.h"
#include "oid.h"
+#include "indexer.h"
/**
* @file git2/backend.h
@@ -21,11 +22,24 @@
GIT_BEGIN_DECL
struct git_odb_stream;
+struct git_odb_writepack;
-/** An instance for a custom backend */
+/**
+ * Function type for callbacks from git_odb_foreach.
+ */
+typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload);
+
+/**
+ * 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_malloc to ensure that it can
+ * be safely freed later. */
int (* read)(
void **, size_t *, git_otype *,
struct git_odb_backend *,
@@ -42,13 +56,17 @@ struct git_odb_backend {
void **, size_t *, git_otype *,
struct git_odb_backend *,
const git_oid *,
- unsigned int);
+ size_t);
int (* read_header)(
size_t *, git_otype *,
struct git_odb_backend *,
const git_oid *);
+ /* The writer may assume that the object
+ * has already been hashed and is passed
+ * in the first parameter.
+ */
int (* write)(
git_oid *,
struct git_odb_backend *,
@@ -71,9 +89,25 @@ struct git_odb_backend {
struct git_odb_backend *,
const git_oid *);
+ int (* refresh)(struct git_odb_backend *);
+
+ int (* foreach)(
+ struct git_odb_backend *,
+ git_odb_foreach_cb cb,
+ void *payload);
+
+ int (* writepack)(
+ struct git_odb_writepack **,
+ struct git_odb_backend *,
+ git_transfer_progress_callback progress_cb,
+ void *progress_payload);
+
void (* free)(struct git_odb_backend *);
};
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
/** Streaming mode */
enum {
GIT_STREAM_RDONLY = (1 << 1),
@@ -84,7 +118,7 @@ enum {
/** A stream to read/write from a backend */
struct git_odb_stream {
struct git_odb_backend *backend;
- int mode;
+ unsigned int mode;
int (*read)(struct git_odb_stream *stream, char *buffer, size_t len);
int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len);
@@ -92,8 +126,23 @@ struct git_odb_stream {
void (*free)(struct git_odb_stream *stream);
};
-GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir);
-GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync);
+/** A stream to write a pack file to the ODB */
+struct git_odb_writepack {
+ struct git_odb_backend *backend;
+
+ int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
+ int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats);
+ void (*free)(struct git_odb_writepack *writepack);
+};
+
+GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
+
+/**
+ * Constructors for in-box ODB backends.
+ */
+GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
+GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync);
+GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
GIT_END_DECL
diff --git a/include/git2/oid.h b/include/git2/oid.h
index c06458d24..862f4b202 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -30,11 +30,10 @@ GIT_BEGIN_DECL
#define GIT_OID_MINPREFIXLEN 4
/** Unique identity of any object (commit, tree, blob, tag). */
-typedef struct _git_oid git_oid;
-struct _git_oid {
+typedef struct git_oid {
/** raw binary formatted id */
unsigned char id[GIT_OID_RAWSZ];
-};
+} git_oid;
/**
* Parse a hex formatted object id into a git_oid.
@@ -48,6 +47,16 @@ struct _git_oid {
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
/**
+ * Parse a hex formatted null-terminated string into a git_oid.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string; must be at least 4 characters
+ * long and null-terminated.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
+
+/**
* Parse N characters of a hex formatted object id into a git_oid
*
* If N is odd, N-1 characters will be parsed instead.
@@ -71,29 +80,29 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw);
/**
* Format a git_oid into a hex string.
*
- * @param str output hex string; must be pointing at the start of
+ * @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). Only the
* oid digits are written; a '\\0' terminator must be added
* by the caller if it is required.
* @param oid oid structure to format.
*/
-GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid);
+GIT_EXTERN(void) git_oid_fmt(char *out, 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 digitis of the oid and "..." is the remaining 38 digits.
+ * hex digits of the oid and "..." is the remaining 38 digits.
*
- * @param str output hex string; must be pointing at the start of
+ * @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). Only the
* oid digits are written; a '\\0' terminator must be added
* by the caller if it is required.
- * @param oid oid structure to format.
+ * @param id oid structure to format.
*/
-GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid);
+GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id);
/**
* Format a git_oid into a newly allocated c-string.
@@ -102,7 +111,7 @@ GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid);
* @return the c-string; NULL if memory is exhausted. Caller must
* deallocate the string with git__free().
*/
-GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
+GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id);
/**
* Format a git_oid into a buffer as a hex format c-string.
@@ -115,11 +124,11 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
*
* @param out the buffer into which the oid string is output.
* @param n the size of the out buffer.
- * @param oid the oid structure to format.
+ * @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 *oid);
+GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id);
/**
* Copy an oid from one structure to another.
@@ -136,7 +145,31 @@ GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src);
* @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);
+GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b)
+{
+ const unsigned char *sha1 = a->id;
+ const unsigned char *sha2 = b->id;
+ int i;
+
+ for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) {
+ if (*sha1 != *sha2)
+ return *sha1 - *sha2;
+ }
+
+ return 0;
+}
+
+/**
+ * Compare two oid structures for equality
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return true if equal, false otherwise
+ */
+GIT_INLINE(int) git_oid_equal(const git_oid *a, const git_oid *b)
+{
+ return !git_oid_cmp(a, b);
+}
/**
* Compare the first 'len' hexadecimal characters (packets of 4 bits)
@@ -147,22 +180,24 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
* @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, unsigned int len);
+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 a oid structure.
+ * @param id oid structure.
* @param str input hex string of an object id.
* @return GIT_ENOTOID if str is not a valid hex string,
* 0 in case of a match, GIT_ERROR otherwise.
*/
-GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str);
+GIT_EXTERN(int) git_oid_streq(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_iszero(const git_oid *a);
+GIT_EXTERN(int) git_oid_iszero(const git_oid *id);
/**
* OID Shortener object
@@ -204,12 +239,12 @@ GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
* GIT_ENOMEM error
*
* @param os a `git_oid_shorten` instance
- * @param text_oid an OID in text form
+ * @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_oid);
+GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id);
/**
* Free an OID shortener instance
diff --git a/include/git2/pack.h b/include/git2/pack.h
new file mode 100644
index 000000000..2f033bef6
--- /dev/null
+++ b/include/git2/pack.h
@@ -0,0 +1,143 @@
+/*
+ * 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"
+
+/**
+ * @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-clar/pack/packbuilder.c for an example.
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * 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);
+
+/**
+ * Write the new pack and the corresponding index to path
+ *
+ * @param pb The packbuilder
+ * @param path Directory to store the new pack and index
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file);
+
+typedef int (*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
+ */
+GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
+
+/**
+ * Get the number of objects the packbuilder has already written out
+ *
+ * @param pb the packbuilder
+ * @return
+ */
+GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb);
+
+/**
+ * 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/push.h b/include/git2/push.h
new file mode 100644
index 000000000..f92308144
--- /dev/null
+++ b/include/git2/push.h
@@ -0,0 +1,131 @@
+/*
+ * 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_push_h__
+#define INCLUDE_git_push_h__
+
+#include "common.h"
+
+/**
+ * @file git2/push.h
+ * @brief Git push management functions
+ * @defgroup git_push push management functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * 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;
+} git_push_options;
+
+#define GIT_PUSH_OPTIONS_VERSION 1
+#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION }
+
+/**
+ * Create a new push object
+ *
+ * @param out New push object
+ * @param remote Remote instance
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote);
+
+/**
+ * Set options on a push object
+ *
+ * @param push The push object
+ * @param opts The options to set on the push object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_set_options(
+ git_push *push,
+ const git_push_options *opts);
+
+/**
+ * Add a refspec to be pushed
+ *
+ * @param push The push object
+ * @param refspec Refspec string
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_add_refspec(git_push *push, const char *refspec);
+
+/**
+ * Update remote tips after a push
+ *
+ * @param push The push object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_update_tips(git_push *push);
+
+/**
+ * Actually push all given refspecs
+ *
+ * Note: To check if the push was successful (i.e. all remote references
+ * have been updated as requested), you need to call both
+ * `git_push_unpack_ok` and `git_push_status_foreach`. The remote
+ * repository might have refused to update some or all of the references.
+ *
+ * @param push The push object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_finish(git_push *push);
+
+/**
+ * Check if remote side successfully unpacked
+ *
+ * @param push The push object
+ *
+ * @return true if equal, false otherwise
+ */
+GIT_EXTERN(int) git_push_unpack_ok(git_push *push);
+
+/**
+ * Call callback `cb' on each status
+ *
+ * For each of the updated references, we receive a status report in the
+ * form of `ok refs/heads/master` or `ng refs/heads/master <msg>`.
+ * `msg != NULL` means the reference has not been updated for the given
+ * reason.
+ *
+ * @param push The push object
+ * @param cb The callback to call on each object
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_push_status_foreach(git_push *push,
+ int (*cb)(const char *ref, const char *msg, void *data),
+ void *data);
+
+/**
+ * Free the given push object
+ *
+ * @param push The push object
+ */
+GIT_EXTERN(void) git_push_free(git_push *push);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/refdb.h b/include/git2/refdb.h
new file mode 100644
index 000000000..0586b119e
--- /dev/null
+++ b/include/git2/refdb.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_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. Either an oid or a symbolic target must be
+ * specified.
+ *
+ * @param refdb the reference database to associate with this reference
+ * @param name the reference name
+ * @param oid the object id for a direct reference
+ * @param symbolic the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc(
+ git_refdb *refdb,
+ const char *name,
+ const git_oid *oid,
+ const char *symbolic);
+
+/**
+ * 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.
+ */
+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);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * Read <refdb_backends.h> for more information.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @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/refdb_backend.h b/include/git2/refdb_backend.h
new file mode 100644
index 000000000..bf33817d6
--- /dev/null
+++ b/include/git2/refdb_backend.h
@@ -0,0 +1,109 @@
+/*
+ * 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_backend_h__
+#define INCLUDE_git_refdb_backend_h__
+
+#include "common.h"
+#include "types.h"
+#include "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
+
+/** An instance for a custom backend */
+struct git_refdb_backend {
+ unsigned int version;
+
+ /**
+ * Queries the refdb backend to determine if the given ref_name
+ * exists. A refdb implementation must provide this function.
+ */
+ int (*exists)(
+ int *exists,
+ struct git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Queries the refdb backend for a given reference. A refdb
+ * implementation must provide this function.
+ */
+ int (*lookup)(
+ git_reference **out,
+ struct git_refdb_backend *backend,
+ const char *ref_name);
+
+ /**
+ * Enumerates each reference in the refdb. A refdb implementation must
+ * provide this function.
+ */
+ int (*foreach)(
+ struct git_refdb_backend *backend,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+ /**
+ * Enumerates each reference in the refdb that matches the given
+ * glob string. A refdb implementation may provide this function;
+ * if it is not provided, foreach will be used and the results filtered
+ * against the glob.
+ */
+ int (*foreach_glob)(
+ struct git_refdb_backend *backend,
+ const char *glob,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+ /**
+ * Writes the given reference to the refdb. A refdb implementation
+ * must provide this function.
+ */
+ int (*write)(struct git_refdb_backend *backend, const git_reference *ref);
+
+ /**
+ * Deletes the given reference from the refdb. A refdb implementation
+ * must provide this function.
+ */
+ int (*delete)(struct git_refdb_backend *backend, const git_reference *ref);
+
+ /**
+ * 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.
+ */
+ int (*compress)(struct git_refdb_backend *backend);
+
+ /**
+ * Frees any resources held by the refdb. A refdb implementation may
+ * provide this function; if it is not provided, nothing will be done.
+ */
+ void (*free)(struct git_refdb_backend *backend);
+};
+
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
+/**
+ * Constructors for default refdb backends.
+ */
+GIT_EXTERN(int) git_refdb_backend_fs(
+ struct git_refdb_backend **backend_out,
+ git_repository *repo,
+ git_refdb *refdb);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/reflog.h b/include/git2/reflog.h
index f490e29de..4944530af 100644
--- a/include/git2/reflog.h
+++ b/include/git2/reflog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -23,41 +23,54 @@ 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 reflog pointer to reflog
+ * @param out pointer to reflog
* @param ref reference to read the reflog for
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref);
+GIT_EXTERN(int) git_reflog_read(git_reflog **out, const git_reference *ref);
/**
- * Write a new reflog for the given reference
+ * Write an existing in-memory reflog object back to disk
+ * using an atomic file lock.
*
- * If there is no reflog file for the given
- * reference yet, it will be created.
- *
- * `oid_old` may be NULL in case it's a new reference.
+ * @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 reflog.
*
* `msg` is optional and can be NULL.
*
- * @param ref the changed reference
- * @param oid_old the OID the reference was pointing to
+ * @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_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg);
+GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg);
/**
* Rename the reflog for the given reference
*
+ * 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 ref the reference
- * @param new_name the new name of the reference
- * @return 0 or an error code
+ * @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_reference *ref, const char *new_name);
+GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name);
/**
* Delete the reflog for the given reference
@@ -73,16 +86,42 @@ GIT_EXTERN(int) git_reflog_delete(git_reference *ref);
* @param reflog the previously loaded reflog
* @return the number of log entries
*/
-GIT_EXTERN(unsigned int) git_reflog_entrycount(git_reflog *reflog);
+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 to lookup
+ * @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(git_reflog *reflog, unsigned int idx);
+GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(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
@@ -90,7 +129,7 @@ GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog
* @param entry a reflog entry
* @return the old oid
*/
-GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entry);
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry);
/**
* Get the new oid
@@ -98,7 +137,7 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entr
* @param entry a reflog entry
* @return the new oid at this time
*/
-GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entry);
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry);
/**
* Get the committer of this entry
@@ -106,15 +145,15 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entr
* @param entry a reflog entry
* @return the committer
*/
-GIT_EXTERN(git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
+GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
/**
- * Get the log msg
+ * Get the log message
*
* @param entry a reflog entry
* @return the log msg
*/
-GIT_EXTERN(char *) git_reflog_entry_msg(const git_reflog_entry *entry);
+GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry);
/**
* Free the reflog
diff --git a/include/git2/refs.h b/include/git2/refs.h
index 882e32769..e0451ba82 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -10,6 +10,7 @@
#include "common.h"
#include "types.h"
#include "oid.h"
+#include "strarray.h"
/**
* @file git2/refs.h
@@ -21,175 +22,221 @@
GIT_BEGIN_DECL
/**
- * Lookup a reference by its name in a repository.
+ * Lookup a reference by name in a repository.
*
- * The generated reference must be freed by the user.
+ * The returned reference must be freed by the user.
*
- * @param reference_out pointer to the looked-up reference
+ * The name will be checked for validity.
+ * See `git_reference_create_symbolic()` 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, ref/heads/master, refs/tags/v0.1.0, ...)
- * @return 0 or an error code
+ * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
+ * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
*/
-GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name);
+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.
*
- * @param oid Pointer to oid to be filled in
+ * 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
- * @return 0 on success, -1 if name could not be resolved
+ * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
*/
-GIT_EXTERN(int) git_reference_name_to_oid(
+GIT_EXTERN(int) git_reference_name_to_id(
git_oid *out, git_repository *repo, const char *name);
/**
* Create a new symbolic reference.
*
- * The reference will be created in the repository and written
- * to the disk.
+ * 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.
*
- * The generated reference must be freed by the user.
+ * Valid reference names must follow one of two patterns:
*
- * If `force` is true and there already exists a reference
- * with the same name, it will be overwritten.
+ * 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 ref_out Pointer to the newly created reference
+ * 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.
+ *
+ * @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
- * @return 0 or an error code
+ * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force);
+GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force);
/**
- * Create a new object id reference.
+ * 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.
*
- * The reference will be created in the repository and written
- * to the disk.
+ * Valid reference names must follow one of two patterns:
*
- * The generated reference must be freed by the user.
+ * 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.
*
- * If `force` is true and there already exists a reference
- * with the same name, it will be overwritten.
+ * 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.
*
- * @param ref_out Pointer to the newly created reference
+ * @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
- * @return 0 or an error code
+ * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force);
+GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force);
/**
- * Get the OID pointed to by a reference.
+ * 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).
*
- * Only available if the reference is direct (i.e. not symbolic)
+ * 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_oid(git_reference *ref);
+GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref);
/**
- * Get full name to the reference pointed by this reference
+ * Get full name to the reference pointed to by a symbolic reference.
*
- * Only available if the reference is symbolic
+ * 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_target(git_reference *ref);
+GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref);
/**
- * Get the type of a reference
+ * Get the type of a reference.
*
* Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC)
*
* @param ref The reference
* @return the type
*/
-GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref);
+GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref);
/**
- * Get the full name of a reference
+ * Get the full name of a reference.
+ *
+ * See `git_reference_create_symbolic()` for rules about valid names.
*
* @param ref The reference
* @return the full name for the ref
*/
-GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
+GIT_EXTERN(const char *) git_reference_name(const git_reference *ref);
/**
- * Resolve a symbolic reference
+ * Resolve a symbolic reference to a direct reference.
*
- * Thie method iteratively peels a symbolic reference
- * until it resolves to a direct reference to an OID.
+ * 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.
+ * 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.
+ * If a direct reference is passed as an argument, a copy of that
+ * reference is returned. This copy must be manually freed too.
*
* @param resolved_ref Pointer to the peeled reference
* @param ref The reference
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref);
+GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref);
/**
- * Get the repository where a reference resides
+ * Get the repository where a reference resides.
*
* @param ref The reference
* @return a pointer to the repo
*/
-GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref);
+GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
/**
- * Set the symbolic target of a reference.
+ * 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 reference must be a symbolic reference, otherwise
- * this method will fail.
+ * The new reference will be written to disk, overwriting the given reference.
*
- * The reference will be automatically updated in
- * memory and on disk.
+ * The target name will be checked for validity.
+ * See `git_reference_create_symbolic()` for rules about valid names.
*
+ * @param out Pointer to the newly created reference
* @param ref The reference
* @param target The new target for the reference
- * @return 0 or an error code
+ * @return 0 on success, EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target);
+GIT_EXTERN(int) git_reference_symbolic_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const char *target);
/**
- * Set the OID target of a reference.
- *
- * The reference must be a direct reference, otherwise
- * this method will fail.
+ * 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 reference will be automatically updated in
- * memory and on disk.
+ * 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
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
+GIT_EXTERN(int) git_reference_set_target(
+ git_reference **out,
+ git_reference *ref,
+ const git_oid *id);
/**
- * Rename an existing reference
+ * Rename an existing reference.
*
* This method works for both direct and symbolic references.
- * The new name will be checked for validity and may be
- * modified into a normalized form.
*
- * The given git_reference will be updated in place.
+ * The new name will be checked for validity.
+ * See `git_reference_create_symbolic()` for rules about valid names.
*
- * The reference will be immediately renamed in-memory
- * and on disk.
+ * On success, the given git_reference will be deleted from disk and a
+ * new `git_reference` will be returned.
+ *
+ * The reference will be immediately renamed in-memory and on disk.
*
* If the `force` flag is not enabled, and there's already
* a reference with the given name, the renaming will fail.
@@ -200,20 +247,23 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
* the reflog if it exists.
*
* @param ref The reference to rename
- * @param new_name The new name for the reference
+ * @param name The new name for the reference
* @param force Overwrite an existing reference
- * @return 0 or an error code
+ * @return 0 on success, EINVALIDSPEC, EEXISTS or an error code
*
*/
-GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force);
+GIT_EXTERN(int) git_reference_rename(
+ git_reference **out,
+ git_reference *ref,
+ const char *new_name,
+ int force);
/**
- * Delete an existing reference
- *
- * This method works for both direct and symbolic references.
+ * Delete an existing reference.
*
- * The reference will be immediately removed on disk and from
- * memory. The given reference pointer will no longer be valid.
+ * 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`.
*
* @param ref The reference to remove
* @return 0 or an error code
@@ -221,108 +271,209 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
/**
- * Pack all the loose references in the repository
+ * Fill a list with all the references that can be found in a repository.
*
- * This method will load into the cache all the loose
- * references on the repository and update the
- * `packed-refs` file with them.
+ * Using the `list_flags` parameter, the listed references may be filtered
+ * by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
+ * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
+ * For convenience, use the value `GIT_REF_LISTALL` to obtain all
+ * references, including packed ones.
*
- * Once the `packed-refs` file has been written properly,
- * the loose references will be removed from disk.
+ * 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 repo Repository where the loose refs will be packed
+ * @param array Pointer to a git_strarray structure where
+ * the reference names will be stored
+ * @param repo Repository where to find the refs
+ * @param list_flags Filtering flags for the reference listing
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reference_packall(git_repository *repo);
+GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
+
+typedef int (*git_reference_foreach_cb)(const char *refname, void *payload);
/**
- * Fill a list with all the references that can be found
- * in a repository.
+ * Perform a callback on each reference in the repository.
*
- * The listed references may be filtered by type, or using
- * a bitwise OR of several types. Use the magic value
- * `GIT_REF_LISTALL` to obtain all references, including
- * packed ones.
+ * Using the `list_flags` parameter, the references may be filtered by
+ * type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
+ * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
+ * For convenience, use the value `GIT_REF_LISTALL` to obtain all
+ * references, including packed ones.
*
- * 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`.
+ * 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 array Pointer to a git_strarray structure where
- * the reference names will be stored
* @param repo Repository where to find the refs
- * @param list_flags Filtering flags for the reference
- * listing.
- * @return 0 or an error code
+ * @param list_flags Filtering flags for the reference listing.
+ * @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_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
+GIT_EXTERN(int) git_reference_foreach(
+ git_repository *repo,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+/**
+ * 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(git_reference *ref1, git_reference *ref2);
/**
- * Perform an operation on each reference in the repository
+ * Perform a callback on each reference in the repository whose name
+ * matches the given pattern.
*
- * The processed references may be filtered by type, or using
- * a bitwise OR of several types. Use the magic value
- * `GIT_REF_LISTALL` to obtain all references, including
- * packed ones.
+ * 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 `callback` function will be called for each of the references
- * in the repository, and will receive the name of the reference and
- * the `payload` value passed to this method.
+ * 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 list_flags Filtering flags for the reference
- * listing.
+ * @param glob Pattern to match (fnmatch-style) against reference name.
+ * @param list_flags Filtering flags for the reference listing.
* @param callback Function which will be called for every listed ref
* @param payload Additional data to pass to the callback
- * @return 0 or an error code
+ * @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,
+ unsigned int list_flags,
+ git_reference_foreach_cb callback,
+ void *payload);
+
+/**
+ * Check if a reflog exists for the specified reference.
+ *
+ * @param ref A git reference
+ *
+ * @return 0 when no reflog can be found, 1 when it exists;
+ * otherwise an error code.
+ */
+GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
+
+/**
+ * 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_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
+GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
/**
- * Check if a reference has been loaded from a packfile
+ * Check if a reference is a remote tracking branch
*
* @param ref A git reference
- * @return 0 in case it's not packed; 1 otherwise
+ *
+ * @return 1 when the reference lives in the refs/remotes
+ * namespace; 0 otherwise.
*/
-GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
+GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
+
+
+typedef enum {
+ GIT_REF_FORMAT_NORMAL = 0,
+
+ /**
+ * 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_REF_FORMAT_ALLOW_ONELEVEL = (1 << 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_REF_FORMAT_REFSPEC_PATTERN = (1 << 1),
+} git_reference_normalize_t;
/**
- * Reload a reference from disk
+ * Normalize reference name and check validity.
*
- * Reference pointers may become outdated if the Git
- * repository is accessed simultaneously by other clients
- * whilt the library is open.
+ * 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.
*
- * This method forces a reload of the reference from disk,
- * to ensure that the provided information is still
- * reliable.
+ * Once normalized, if the reference name is valid, it will be returned in
+ * the user allocated buffer.
*
- * If the reload fails (e.g. the reference no longer exists
- * on disk, or has become corrupted), an error code will be
- * returned and the reference pointer will be invalidated.
+ * See `git_reference_create_symbolic()` for rules about valid names.
*
- * @param ref The reference to reload
- * @return 0 on success, or an error code
+ * @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_REF_FORMAT constants above.
+ * @return 0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC
+ * or an error code.
*/
-GIT_EXTERN(int) git_reference_reload(git_reference *ref);
+GIT_EXTERN(int) git_reference_normalize_name(
+ char *buffer_out,
+ size_t buffer_size,
+ const char *name,
+ unsigned int flags);
/**
- * Free the given reference
+ * Recursively peel reference until object of the specified type is found.
*
- * @param ref git_reference
+ * The retrieved `peeled` object is owned by the repository
+ * and should be closed with the `git_object_free` method.
+ *
+ * If you pass `GIT_OBJ_ANY` as the target type, then the object
+ * will be peeled until a non-tag object is met.
+ *
+ * @param peeled Pointer to the peeled git_object
+ * @param ref The reference to be processed
+ * @param target_type The type of the requested object (GIT_OBJ_COMMIT,
+ * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY).
+ * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
*/
-GIT_EXTERN(void) git_reference_free(git_reference *ref);
+GIT_EXTERN(int) git_reference_peel(
+ git_object **out,
+ git_reference *ref,
+ git_otype type);
/**
- * Compare two references.
+ * Ensure the reference name is well-formed.
*
- * @param ref1 The first git_reference
- * @param ref2 The second git_reference
- * @return 0 if the same, else a stable but meaningless ordering.
+ * 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 refname name to be checked.
+ * @return 1 if the reference name is acceptable; 0 if it isn't
*/
-GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
+GIT_EXTERN(int) git_reference_is_valid_name(const char *refname);
/** @} */
GIT_END_DECL
diff --git a/include/git2/refspec.h b/include/git2/refspec.h
index c0a8eabfe..ec7830b7c 100644
--- a/include/git2/refspec.h
+++ b/include/git2/refspec.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -36,6 +36,14 @@ GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec);
GIT_EXTERN(const char *) git_refspec_dst(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);
+
+/**
* Check if a refspec's source descriptor matches a reference
*
* @param refspec the refspec
@@ -45,16 +53,36 @@ GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
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 outlen the size ouf the `out` buffer
+ * @param outlen the size of the `out` buffer
* @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(char *out, size_t outlen, 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 outlen the size of the `out` buffer
+ * @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(char *out, size_t outlen, const git_refspec *spec, const char *name);
+
GIT_END_DECL
#endif
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 865dfef04..6f36a3999 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -12,6 +12,8 @@
#include "refspec.h"
#include "net.h"
#include "indexer.h"
+#include "strarray.h"
+#include "transport.h"
/**
* @file git2/remote.h
@@ -22,6 +24,7 @@
*/
GIT_BEGIN_DECL
+typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload);
/*
* TODO: This functions still need to be implemented:
* - _listcb/_foreach
@@ -31,35 +34,64 @@ GIT_BEGIN_DECL
*/
/**
+ * Add a remote with the default fetch refspec to the repository's configuration. This
+ * calls git_remote_save before returning.
+ *
+ * @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);
+
+/**
* Create a remote in memory
*
- * Create a remote with the default refspecs in memory. You can use
- * this when you have a URL instead of a remote's name.
+ * Create a remote with the given refspec in memory. You can use
+ * this when you have a URL instead of a remote's name. Note that in-memory
+ * remotes cannot be converted to persisted remotes.
+ *
+ * The name, when provided, 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 associtated repository
- * @param name the remote's name
+ * @param repo the associated repository
+ * @param fetch the fetch refspec to use for this remote. May be NULL for defaults.
* @param url the remote repository's URL
- * @param fetch the fetch refspec to use for this remote
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch);
+GIT_EXTERN(int) git_remote_create_inmemory(
+ git_remote **out,
+ git_repository *repo,
+ const char *fetch,
+ 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 cfg the repository's configuration
+ * @param repo the associated repository
* @param name the remote's name
- * @return 0 or an error code
+ * @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name);
/**
* Save a remote to its repository's configuration
*
+ * One can't save a in-memory remote. Doing so will
+ * result in a GIT_EINVALIDSPEC being returned.
+ *
* @param remote the remote to save to config
- * @return 0 or an error code
+ * @return 0, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
@@ -67,9 +99,9 @@ GIT_EXTERN(int) git_remote_save(const git_remote *remote);
* Get the remote's name
*
* @param remote the remote
- * @return a pointer to the name
+ * @return a pointer to the name or NULL for in-memory remotes
*/
-GIT_EXTERN(const char *) git_remote_name(git_remote *remote);
+GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
/**
* Get the remote's url
@@ -77,7 +109,37 @@ GIT_EXTERN(const char *) git_remote_name(git_remote *remote);
* @param remote the remote
* @return a pointer to the url
*/
-GIT_EXTERN(const char *) git_remote_url(git_remote *remote);
+GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
+
+/**
+ * Get the remote's url for pushing
+ *
+ * @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
+ *
+ * Existing connections will not be updated.
+ *
+ * @param remote the remote
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url);
+
+/**
+ * Set the remote's url for pushing
+ *
+ * Existing connections will not be updated.
+ *
+ * @param remote the remote
+ * @param url the url to set or NULL to clear the pushurl
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
/**
* Set the remote's fetch refspec
@@ -94,13 +156,13 @@ GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec);
* @param remote the remote
* @return a pointer to the fetch refspec or NULL if it doesn't exist
*/
-GIT_EXTERN(const git_refspec *) git_remote_fetchspec(git_remote *remote);
+GIT_EXTERN(const git_refspec *) git_remote_fetchspec(const git_remote *remote);
/**
* Set the remote's push refspec
*
* @param remote the remote
- * @apram spec the new push refspec
+ * @param spec the new push refspec
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec);
@@ -112,7 +174,7 @@ GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec);
* @return a pointer to the push refspec or NULL if it doesn't exist
*/
-GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote);
+GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote);
/**
* Open a connection to a remote
@@ -125,7 +187,7 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote);
* @param direction whether you want to receive or send data
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
+GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
/**
* Get a list of refs at the remote
@@ -133,9 +195,13 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
* The remote (or more exactly its transport) must be connected. The
* memory belongs to the remote.
*
- * @param refs where to store the refs
+ * If you a return a non-zero value from the callback, this will stop
+ * looping over the refs.
+ *
* @param remote the remote
- * @return 0 or an error code
+ * @param list_cb function to call with each ref discovered at the remote
+ * @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_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload);
@@ -149,10 +215,16 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void
* filename will be NULL and the function will return success.
*
* @param remote the remote to download from
- * @param filename where to store the temproray filename
+ * @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_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats);
+GIT_EXTERN(int) git_remote_download(
+ git_remote *remote,
+ git_transfer_progress_callback progress_cb,
+ void *payload);
/**
* Check whether the remote is connected
@@ -160,11 +232,22 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_in
* 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(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
+ */
+GIT_EXTERN(void) git_remote_stop(git_remote *remote);
+
+/**
* Disconnect from the remote
*
* Close the connection to the remote and free the underlying
@@ -188,14 +271,14 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
* Update the tips to the new state
*
* @param remote the remote to update
- * @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value
+ * @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b));
+GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
/**
* Return whether a string is a valid remote URL
*
- * @param tranport the url to check
+ * @param url the url to check
* @param 1 if the url is valid, 0 otherwise
*/
GIT_EXTERN(int) git_remote_valid_url(const char *url);
@@ -213,21 +296,167 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url);
*
* The string array must be freed by the user.
*
- * @param remotes_list a string array with the names of the remotes
+ * @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 *remotes_list, git_repository *repo);
+GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
/**
- * Add a remote with the default fetch refspec to the repository's configuration
+ * Choose whether to check the server's certificate (applies to HTTPS only)
*
- * @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 remote the remote to configure
+ * @param check whether to check the server's certificate (defaults to yes)
+ */
+GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check);
+
+/**
+ * Set a credentials acquisition callback for this remote. If the remote is
+ * not available for anonymous access, then you must set this callback in order
+ * to provide credentials to the transport at the time of authentication
+ * failure so that retry can be performed.
+ *
+ * @param remote the remote to configure
+ * @param cred_acquire_cb The credentials acquisition callback to use (defaults
+ * to NULL)
+ */
+GIT_EXTERN(void) git_remote_set_cred_acquire_cb(
+ git_remote *remote,
+ git_cred_acquire_cb cred_acquire_cb,
+ void *payload);
+
+/**
+ * Sets a custom transport for the remote. The caller can use this function
+ * to bypass the automatic discovery of a transport by URL scheme (i.e.
+ * http://, https://, git://) and supply their own transport to be used
+ * instead. After providing the transport to a remote using this function,
+ * the transport object belongs exclusively to that remote, and the remote will
+ * free it when it is freed with git_remote_free.
+ *
+ * @param remote the remote to configure
+ * @param transport the transport object for the remote to use
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_set_transport(
+ git_remote *remote,
+ git_transport *transport);
+
+/**
+ * Argument to the completion callback which tells it which operation
+ * finished.
+ */
+typedef enum git_remote_completion_type {
+ GIT_REMOTE_COMPLETION_DOWNLOAD,
+ GIT_REMOTE_COMPLETION_INDEXING,
+ GIT_REMOTE_COMPLETION_ERROR,
+} git_remote_completion_type;
+
+/**
+ * The callback settings structure
+ *
+ * Set the calbacks to be called by the remote.
+ */
+struct git_remote_callbacks {
+ unsigned int version;
+ void (*progress)(const char *str, int len, void *data);
+ int (*completion)(git_remote_completion_type type, void *data);
+ int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
+ void *payload;
+};
+
+#define GIT_REMOTE_CALLBACKS_VERSION 1
+#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
+
+/**
+ * Set the callbacks for a remote
+ *
+ * Note that the remote keeps its own copy of the data and you need to
+ * call this function again if you want to change the callbacks.
+ *
+ * @param remote the remote to configure
+ * @param callbacks a pointer to the user's callback settings
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
+
+/**
+ * Get the statistics structure that is filled in by the fetch operation.
+ */
+GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote);
+
+typedef enum {
+ GIT_REMOTE_DOWNLOAD_TAGS_UNSET,
+ GIT_REMOTE_DOWNLOAD_TAGS_NONE,
+ GIT_REMOTE_DOWNLOAD_TAGS_AUTO,
+ GIT_REMOTE_DOWNLOAD_TAGS_ALL
+} git_remote_autotag_option_t;
+
+/**
+ * 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(git_remote *remote);
+
+/**
+ * Set the tag auto-follow setting
+ *
+ * @param remote the remote to configure
+ * @param value a GIT_REMOTE_DOWNLOAD_TAGS value
+ */
+GIT_EXTERN(void) git_remote_set_autotag(
+ git_remote *remote,
+ git_remote_autotag_option_t value);
+
+/**
+ * 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.
+ *
+ * A temporary in-memory remote cannot be given a name with this method.
+ *
+ * @param remote the remote to rename
+ * @param new_name the new name the remote should bear
+ * @param callback Optional callback to notify the consumer of fetch refspecs
+ * that haven't been automatically updated and need potential manual tweaking.
+ * @param payload Additional data to pass to the callback
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_rename(
+ git_remote *remote,
+ const char *new_name,
+ git_remote_rename_problem_cb callback,
+ void *payload);
+
+/**
+ * Retrieve the update FETCH_HEAD setting.
+ *
+ * @param remote the remote to query
+ * @return the update FETCH_HEAD setting
+ */
+GIT_EXTERN(int) git_remote_update_fetchhead(git_remote *remote);
+
+/**
+ * Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be
+ * updated on every fetch. Set to 0 to disable.
+ *
+ * @param remote the remote to configure
+ * @param value 0 to disable updating FETCH_HEAD
+ */
+GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value);
+
+/**
+ * Ensure the remote name is well-formed.
+ *
+ * @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_add(git_remote **out, git_repository *repo, const char *name, const char *url);
+GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
/** @} */
GIT_END_DECL
diff --git a/include/git2/repository.h b/include/git2/repository.h
index 3949438cf..e75c8b136 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -29,11 +29,24 @@ GIT_BEGIN_DECL
* The method will automatically detect if 'path' is a normal
* or bare repository or fail is 'path' is neither.
*
- * @param repository pointer to the repo which will be opened
+ * @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 **repository, const char *path);
+GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
+
+/**
+ * Create a "fake" repository to wrap an object database
+ *
+ * Create a repository object to wrap an object database to be used
+ * with the API when all you have is an object database. This doesn't
+ * have any paths associated with it, so use with care.
+ *
+ * @param out pointer to the repo
+ * @param odb the object database to wrap
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
/**
* Look for a git repository and copy its path in the given buffer.
@@ -45,10 +58,10 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat
* The method will automatically detect if the repository is bare
* (if there is a repository).
*
- * @param repository_path The user allocated buffer which will
+ * @param path_out The user allocated buffer which will
* contain the found path.
*
- * @param size repository_path size
+ * @param path_size repository_path size
*
* @param start_path The base path where the lookup starts.
*
@@ -64,24 +77,50 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat
* @return 0 or an error code
*/
GIT_EXTERN(int) git_repository_discover(
- char *repository_path,
- size_t size,
+ char *path_out,
+ size_t path_size,
const char *start_path,
int across_fs,
const char *ceiling_dirs);
-enum {
+/**
+ * Option flags for `git_repository_open_ext`.
+ *
+ * * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be
+ * immediately found in the start_path. Do not walk up from the
+ * start_path looking at parent directories.
+ * * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not
+ * continue searching across filesystem boundaries (i.e. when `st_dev`
+ * changes from the `stat` system call). (E.g. Searching in a user's home
+ * directory "/home/user/source/" will not return "/.git/" as the found
+ * repo if "/" is a different filesystem than "/home".)
+ */
+typedef enum {
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
-};
+} 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.
+ * @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 **repo,
- const char *start_path,
- uint32_t flags,
+ git_repository **out,
+ const char *path,
+ unsigned int flags,
const char *ceiling_dirs);
/**
@@ -103,25 +142,148 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo);
* TODO:
* - Reinit the repository
*
- * @param repo_out pointer to the repo which will be created or reinitialized
+ * @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.
+ * @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 **repo_out, const char *path, unsigned is_bare);
+GIT_EXTERN(int) git_repository_init(
+ git_repository **out,
+ const char *path,
+ unsigned is_bare);
+
+/**
+ * Option flags for `git_repository_init_ext`.
+ *
+ * These flags configure extra behaviors to `git_repository_init_ext`.
+ * In every case, the default behavior is the zero value (i.e. flag is
+ * not set). Just OR the flag values together for the `flags` parameter
+ * when initializing a new repo. Details of individual values are:
+ *
+ * * BARE - Create a bare repository with no working directory.
+ * * NO_REINIT - Return an EEXISTS error if the repo_path appears to
+ * already be an git repository.
+ * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo
+ * path for non-bare repos (if it is not already there), but
+ * passing this flag prevents that behavior.
+ * * MKDIR - Make the repo_path (and workdir_path) as needed. Init is
+ * always willing to create the ".git" directory even without this
+ * flag. This flag tells init to create the trailing component of
+ * the repo and workdir paths as needed.
+ * * MKPATH - Recursively make all components of the repo and workdir
+ * paths as necessary.
+ * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to
+ * initialize a new repo. This flags enables external templates,
+ * looking the "template_path" from the options if set, or the
+ * `init.templatedir` global config if not, or falling back on
+ * "/usr/share/git-core/templates" if it exists.
+ */
+typedef enum {
+ GIT_REPOSITORY_INIT_BARE = (1u << 0),
+ GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1),
+ GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2),
+ GIT_REPOSITORY_INIT_MKDIR = (1u << 3),
+ GIT_REPOSITORY_INIT_MKPATH = (1u << 4),
+ GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5),
+} git_repository_init_flag_t;
+
+/**
+ * Mode options for `git_repository_init_ext`.
+ *
+ * Set the mode field of the `git_repository_init_options` structure
+ * either to the custom mode that you would like, or to one of the
+ * following modes:
+ *
+ * * SHARED_UMASK - Use permissions configured by umask - the default.
+ * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo
+ * to be group writable and "g+sx" for sticky group assignment.
+ * * SHARED_ALL - Use "--shared=all" behavior, adding world readability.
+ * * Anything else - Set to custom value.
+ */
+typedef enum {
+ GIT_REPOSITORY_INIT_SHARED_UMASK = 0,
+ GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775,
+ GIT_REPOSITORY_INIT_SHARED_ALL = 0002777,
+} git_repository_init_mode_t;
+
+/**
+ * Extended options structure for `git_repository_init_ext`.
+ *
+ * This contains extra options for `git_repository_init_ext` that enable
+ * additional initialization features. The fields are:
+ *
+ * * flags - Combination of GIT_REPOSITORY_INIT flags above.
+ * * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...
+ * constants above, or to a custom value that you would like.
+ * * workdir_path - The path to the working dir or NULL for default (i.e.
+ * repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH,
+ * IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not
+ * the "natural" working directory, a .git gitlink file will be
+ * created here linking to the repo_path.
+ * * description - If set, this will be used to initialize the "description"
+ * file in the repository, instead of using the template content.
+ * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,
+ * this contains the path to use for the template directory. If
+ * this is NULL, the config or default directory options will be
+ * used instead.
+ * * initial_head - The name of the head to point HEAD at. If NULL, then
+ * this will be treated as "master" and the HEAD ref will be set
+ * to "refs/heads/master". If this begins with "refs/" it will be
+ * used verbatim; otherwise "refs/heads/" will be prefixed.
+ * * origin_url - If this is non-NULL, then after the rest of the
+ * repository initialization is completed, an "origin" remote
+ * will be added pointing to this URL.
+ */
+typedef struct {
+ unsigned int version;
+ uint32_t flags;
+ uint32_t mode;
+ const char *workdir_path;
+ const char *description;
+ const char *template_path;
+ const char *initial_head;
+ const char *origin_url;
+} git_repository_init_options;
+
+#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1
+#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}
+
+/**
+ * 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.
*
- * @param head_out pointer to the reference which will be retrieved
+ * 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; error code otherwise
+ * @return 0 on success, GIT_EORPHANEDHEAD 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 **head_out, git_repository *repo);
+GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
/**
* Check if a repository's HEAD is detached
@@ -130,7 +292,7 @@ GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *re
* instead of a branch.
*
* @param repo Repo to test
- * @return 1 if HEAD is detached, 0 if i'ts not; error code if there
+ * @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);
@@ -143,7 +305,7 @@ GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
*
* @param repo Repo to test
* @return 1 if the current branch is an orphan, 0 if it's not; error
- * code if therewas an error
+ * code if there was an error
*/
GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
@@ -151,7 +313,7 @@ GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
* Check if a repository is empty
*
* An empty repository has just been initialized and contains
- * no commits.
+ * no references.
*
* @param repo Repo to test
* @return 1 if the repository is empty, 0 if it isn't, error code
@@ -194,9 +356,12 @@ GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
*
* @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);
+GIT_EXTERN(int) git_repository_set_workdir(
+ git_repository *repo, const char *workdir, int update_gitlink);
/**
* Check if a repository is bare
@@ -269,6 +434,39 @@ GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
/**
+ * 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);
+
+/**
+ * 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
+ */
+GIT_EXTERN(void) git_repository_set_refdb(
+ git_repository *repo,
+ git_refdb *refdb);
+
+/**
* Get the Index file for this repository.
*
* If a custom index has not been set, the default
@@ -299,6 +497,184 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
*/
GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
+/**
+ * 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 Buffer to write data into or NULL to just read required size
+ * @param len Length of buffer in bytes
+ * @param repo Repository to read prepared message from
+ * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error
+ */
+GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
+
+/**
+ * Remove git's prepared message.
+ *
+ * Remove the message that `git_repository_message` retrieves.
+ */
+GIT_EXTERN(int) git_repository_message_remove(git_repository *repo);
+
+/**
+ * Remove all the metadata associated with an ongoing git merge, including
+ * MERGE_HEAD, MERGE_MSG, etc.
+ *
+ * @param repo A repository object
+ * @return 0 on success, or error
+ */
+GIT_EXTERN(int) git_repository_merge_cleanup(git_repository *repo);
+
+typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
+ const char *remote_url,
+ const git_oid *oid,
+ unsigned int is_merge,
+ void *payload);
+
+/**
+ * Call callback 'callback' for each entry in the given FETCH_HEAD file.
+ *
+ * @param repo A repository object
+ * @param callback Callback function
+ * @param payload Pointer to callback data (optional)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
+ */
+GIT_EXTERN(int) git_repository_fetchhead_foreach(git_repository *repo,
+ git_repository_fetchhead_foreach_cb callback,
+ void *payload);
+
+typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid,
+ void *payload);
+
+/**
+ * If a merge is in progress, call callback 'cb' for each commit ID in the
+ * MERGE_HEAD file.
+ *
+ * @param repo A repository object
+ * @param callback Callback function
+ * @param apyload Pointer to callback data (optional)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
+ */
+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.
+ *
+ * @param out Output value of calculated SHA
+ * @param repo Repository pointer
+ * @param path Path to file on disk whose contents should be hashed. If the
+ * repository is not NULL, this can be a relative path.
+ * @param type The object type to hash as (e.g. GIT_OBJ_BLOB)
+ * @param as_path The path to use to look up filtering rules. If this is
+ * NULL, then the `path` parameter will be used instead. If
+ * this is passed as the empty string, then no filters will be
+ * applied when calculating the hash.
+ */
+GIT_EXTERN(int) git_repository_hashfile(
+ git_oid *out,
+ git_repository *repo,
+ const char *path,
+ git_otype type,
+ const char *as_path);
+
+/**
+ * Make the repository HEAD point to the specified reference.
+ *
+ * If the provided reference points to a Tree or a Blob, the HEAD is
+ * unaltered and -1 is returned.
+ *
+ * If the provided reference points to a branch, the HEAD will point
+ * to that branch, staying attached, or become attached if it isn't yet.
+ * If the branch doesn't exist yet, no error will be return. The HEAD
+ * will then be attached to an unborn branch.
+ *
+ * Otherwise, the HEAD will be detached and will directly point to
+ * the Commit.
+ *
+ * @param repo Repository pointer
+ * @param refname Canonical name of the reference the HEAD should point at
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_head(
+ git_repository* repo,
+ const char* refname);
+
+/**
+ * Make the repository HEAD directly point to the Commit.
+ *
+ * If the provided committish cannot be found in the repository, the HEAD
+ * is unaltered and GIT_ENOTFOUND is returned.
+ *
+ * If the provided commitish cannot be peeled into a commit, the HEAD
+ * is unaltered and -1 is returned.
+ *
+ * Otherwise, the HEAD will eventually be detached and will directly point to
+ * the peeled Commit.
+ *
+ * @param repo Repository pointer
+ * @param commitish Object id of the Commit the HEAD should point to
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_head_detached(
+ git_repository* repo,
+ const git_oid* commitish);
+
+/**
+ * Detach the HEAD.
+ *
+ * If the HEAD is already detached and points to a Commit, 0 is returned.
+ *
+ * If the HEAD is already detached and points to a Tag, the HEAD is
+ * updated into making it point to the peeled Commit, and 0 is returned.
+ *
+ * If the HEAD is already detached and points to a non commitish, the HEAD is
+ * unaltered, and -1 is returned.
+ *
+ * Otherwise, the HEAD will be detached and point to the peeled Commit.
+ *
+ * @param repo Repository pointer
+ * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
+ * branch or an error code
+ */
+GIT_EXTERN(int) git_repository_detach_head(
+ git_repository* repo);
+
+typedef enum {
+ GIT_REPOSITORY_STATE_NONE,
+ GIT_REPOSITORY_STATE_MERGE,
+ GIT_REPOSITORY_STATE_REVERT,
+ GIT_REPOSITORY_STATE_CHERRY_PICK,
+ 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);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/reset.h b/include/git2/reset.h
new file mode 100644
index 000000000..c7c951942
--- /dev/null
+++ b/include/git2/reset.h
@@ -0,0 +1,81 @@
+/*
+ * 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__
+
+/**
+ * @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 dereferencable
+ * to a git_commit which oid will be used as the target of the branch.
+ *
+ * @param reset_type Kind of reset operation to perform.
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_reset(
+ git_repository *repo, git_object *target, git_reset_t reset_type);
+
+/**
+ * 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,
+ git_object *target,
+ git_strarray* pathspecs);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/revparse.h b/include/git2/revparse.h
new file mode 100644
index 000000000..e155c7012
--- /dev/null
+++ b/include/git2/revparse.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_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.
+ *
+ * @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);
+
+
+/**
+ * Revparse flags. These indicate the intended behavior of the spec passed to
+ * git_revparse.
+ */
+typedef enum {
+ /** The spec targeted a single object. */
+ GIT_REVPARSE_SINGLE = 1 << 0,
+ /** The spec targeted a range of commits. */
+ GIT_REVPARSE_RANGE = 1 << 1,
+ /** The spec used the '...' operator, which invokes special semantics. */
+ GIT_REVPARSE_MERGE_BASE = 1 << 2,
+} git_revparse_mode_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 */
+ 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
index aac6fb7c2..8bfe0b502 100644
--- a/include/git2/revwalk.h
+++ b/include/git2/revwalk.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -63,11 +63,11 @@ GIT_BEGIN_DECL
* it is possible to have several revision walkers in
* several different threads walking the same repository.
*
- * @param walker pointer to the new revision walker
+ * @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 **walker, git_repository *repo);
+GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo);
/**
* Reset the revision walker for reuse.
@@ -92,22 +92,22 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
*
* The given commit will be used as one of the roots
* when starting the revision walk. At least one commit
- * must be pushed the repository before a walk can
+ * must be pushed onto the walker before a walk can
* be started.
*
* @param walk the walker being used for the traversal.
- * @param oid the oid of the commit to start from.
+ * @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 *oid);
+GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
/**
* Push matching references
*
- * The OIDs pinted to by the references that match the given glob
+ * 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 it not present as well as a trailing
+ * A leading 'refs/' is implied if not present as well as a trailing
* '/ *' if the glob lacks '?', '*' or '['.
*
* @param walk the walker being used for the traversal
@@ -134,19 +134,19 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
* output on the revision walk.
*
* @param walk the walker being used for the traversal.
- * @param oid the oid of commit that will be ignored during 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 *oid);
+GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
/**
* Hide matching references.
*
- * The OIDs pinted to by the references that match the given glob
+ * 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 it not present as well as a trailing
+ * A leading 'refs/' is implied if not present as well as a trailing
* '/ *' if the glob lacks '?', '*' or '['.
*
* @param walk the walker being used for the traversal
@@ -169,7 +169,7 @@ GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
* The reference must point to a commit.
*
* @param walk the walker being used for the traversal
- * @param refname the referece to push
+ * @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);
@@ -180,7 +180,7 @@ GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
* The reference must point to a commit.
*
* @param walk the walker being used for the traversal
- * @param refname the referece to hide
+ * @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);
@@ -198,12 +198,12 @@ GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
*
* The revision walker is reset when the walk is over.
*
- * @param oid Pointer where to store the oid of the next commit
+ * @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_REVWALKOVER if there are no commits left to iterate
+ * GIT_ITEROVER if there are no commits left to iterate
*/
-GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
+GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk);
/**
* Change the sorting mode when iterating through the
@@ -217,6 +217,21 @@ GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
GIT_EXTERN(void) 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);
+
+/**
* Free a revision walker previously allocated.
*
* @param walk traversal handle to close. If NULL nothing occurs.
diff --git a/include/git2/signature.h b/include/git2/signature.h
index cbf94269f..00d19de66 100644
--- a/include/git2/signature.h
+++ b/include/git2/signature.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -20,41 +20,52 @@
GIT_BEGIN_DECL
/**
- * Create a new action signature. The signature must be freed
- * manually or using git_signature_free
+ * Create a new action signature.
*
- * @param sig_out new signature, in case of error NULL
+ * 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 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 **sig_out, const char *name, const char *email, git_time_t time, int offset);
+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'. The
- * signature must be freed manually or using git_signature_free
+ * Create a new action signature with a timestamp of 'now'.
+ *
+ * Call `git_signature_free()` to free the data.
*
- * @param sig_out new signature, in case of error NULL
+ * @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 **sig_out, const char *name, const char *email);
+GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email);
/**
- * Create a copy of an existing signature.
+ * Create a copy of an existing signature. All internal strings are also
+ * duplicated.
+ *
+ * Call `git_signature_free()` to free the data.
*
- * All internal strings are also duplicated.
* @param sig signature to duplicated
* @return a copy of sig, NULL on out of memory
*/
GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig);
/**
- * Free an existing signature
+ * 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
*/
diff --git a/include/git2/stash.h b/include/git2/stash.h
new file mode 100644
index 000000000..cf8bc9d4c
--- /dev/null
+++ b/include/git2/stash.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_stash_h__
+#define INCLUDE_git_stash_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/stash.h
+ * @brief Git stash management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef enum {
+ 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),
+} 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,
+ git_signature *stasher,
+ const char *message,
+ unsigned int flags);
+
+/**
+ * When iterating over all the stashed states, callback that will be
+ * issued 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 on success, GIT_EUSER on non-zero callback, or error code
+ */
+typedef int (*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 callabck 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, GIT_EUSER on non-zero callback, 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, or error code
+ */
+
+GIT_EXTERN(int) git_stash_drop(
+ git_repository *repo,
+ size_t index);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/status.h b/include/git2/status.h
index 6a424dfd6..38b6fa5bd 100644
--- a/include/git2/status.h
+++ b/include/git2/status.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -19,38 +19,67 @@
*/
GIT_BEGIN_DECL
-enum {
- GIT_STATUS_CURRENT = 0,
+/**
+ * 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_INDEX_NEW = (1 << 0),
- GIT_STATUS_INDEX_MODIFIED = (1 << 1),
- GIT_STATUS_INDEX_DELETED = (1 << 2),
+ 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_NEW = (1 << 3),
- GIT_STATUS_WT_MODIFIED = (1 << 4),
- GIT_STATUS_WT_DELETED = (1 << 5),
+ GIT_STATUS_IGNORED = (1u << 14),
+} git_status_t;
- GIT_STATUS_IGNORED = (1 << 6),
-};
+/**
+ * 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_status_cb)(
+ const char *path, unsigned int status_flags, void *payload);
/**
* Gather file statuses and run a callback for each one.
*
- * The callback is passed the path of the file, the status and the data
- * pointer passed to this function. If the callback returns something other
- * than 0, this function will return that value.
+ * 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 GIT_EUSER.
*
- * @param repo a repository object
- * @param callback the function to call on each file
- * @return 0 on success or the return value of the callback that was non-zero
+ * @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, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_status_foreach(
git_repository *repo,
- int (*callback)(const char *, unsigned int, void *),
+ git_status_cb callback,
void *payload);
/**
- * Select the files on which to report status.
+ * For extended status, select the files on which to report status.
*
* - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the
* rough equivalent of `git status --porcelain` where each file
@@ -78,62 +107,108 @@ typedef enum {
/**
* Flags to control status callbacks
*
- * - GIT_STATUS_OPT_INCLUDE_UNTRACKED 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_IGNORED says that ignored files should
- * get callbacks. Again, these callbacks will only be made if
- * the workdir files are included in the status "show" option.
- * Right now, there is no option to include all files in
- * directories that are ignored completely.
- * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback
- * should be made even on unmodified files.
- * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories
- * which appear to be submodules should just be skipped over.
- * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the
- * contents of untracked directories should be included in the
- * status. Normally if an entire directory is new, then just
- * the top-level directory will be included (with a trailing
- * slash on the entry name). Given this flag, the directory
- * itself will not be included, but all the files in it will.
+ * - GIT_STATUS_OPT_INCLUDE_UNTRACKED 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_IGNORED says that ignored files should get
+ * callbacks. Again, these callbacks will only be made if the workdir
+ * files are included in the status "show" option. Right now, there is
+ * no option to include all files in directories that are ignored
+ * completely.
+ * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be
+ * made even on unmodified files.
+ * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories which
+ * appear to be submodules should just be skipped over.
+ * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the contents of
+ * untracked directories should be included in the status. Normally if
+ * an entire directory is new, then just the top-level directory will be
+ * included (with a trailing slash on the entry name). Given this flag,
+ * the directory itself will not be included, but all the files in it
+ * will.
+ * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path
+ * will be treated as a literal path, and not as a pathspec.
+ * - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS 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.
+ *
+ * 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 {
+ GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0),
+ GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1),
+ GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2),
+ GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3),
+ GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4),
+ GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5),
+ GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6),
+} git_status_opt_t;
-enum {
- GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0),
- GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1),
- GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2),
- GIT_STATUS_OPT_EXCLUDE_SUBMODULED = (1 << 3),
- GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4),
-};
+#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 callbacks will be made by
- * `git_status_foreach_ext()`.
+ * Options to control how `git_status_foreach_ext()` will issue callbacks.
+ *
+ * This structure is set so that zeroing it out will give you relatively
+ * sane defaults.
+ *
+ * The `show` value is one of the `git_status_show_t` constants that
+ * control which files to scan and in what order.
+ *
+ * The `flags` value is an OR'ed combination of the `git_status_opt_t`
+ * values above.
+ *
+ * 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.
*/
typedef struct {
+ unsigned int version;
git_status_show_t show;
- unsigned int flags;
- git_strarray pathspec;
+ unsigned int flags;
+ git_strarray pathspec;
} git_status_options;
+#define GIT_STATUS_OPTIONS_VERSION 1
+#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION}
+
/**
* 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.
+ *
+ * @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, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_status_foreach_ext(
git_repository *repo,
const git_status_options *opts,
- int (*callback)(const char *, unsigned int, void *),
+ git_status_cb callback,
void *payload);
/**
- * Get file status for a single file
- *
- * @param status_flags the status value
- * @param repo a repository object
- * @param path the file to retrieve status for, rooted at the repo's workdir
- * @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when
- * the file doesn't exist in any of HEAD, the index or the worktree,
- * 0 otherwise
+ * Get file status for a single file.
+ *
+ * This is not quite the same as calling `git_status_foreach_ext()` with
+ * the pathspec set to the specified path.
+ *
+ * @param status_flags The status value for the file
+ * @param repo A repository object
+ * @param path The file to retrieve status for, rooted at the repo's workdir
+ * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,
+ * index, and work tree, GIT_EINVALIDPATH if `path` points at a folder,
+ * GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error.
*/
GIT_EXTERN(int) git_status_file(
unsigned int *status_flags,
@@ -143,14 +218,16 @@ GIT_EXTERN(int) git_status_file(
/**
* Test if the ignore rules apply to a given file.
*
- * This function simply checks the ignore rules to see if they would apply
- * to the given file. Unlike git_status_file(), this indicates if the file
- * would be ignored regardless of whether the file is already in the index
- * or in the repository.
+ * 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.
+ * @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.
*/
diff --git a/include/git2/strarray.h b/include/git2/strarray.h
new file mode 100644
index 000000000..d338eb7ad
--- /dev/null
+++ b/include/git2/strarray.h
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+/**
+ * Close a string array object
+ *
+ * This method should be called on `git_strarray` objects where the strings
+ * array is allocated and contains allocated strings, such as what you
+ * would get from `git_strarray_copy()`. 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 (it is more commonly embedded
+ * inside another struct or created on the stack).
+ *
+ * @param array git_strarray from which to free string data
+ */
+GIT_EXTERN(void) git_strarray_free(git_strarray *array);
+
+/**
+ * Copy a string array object from source to target.
+ *
+ * Note: target is overwritten and hence should be empty, otherwise its
+ * contents are leaked. Call git_strarray_free() if necessary.
+ *
+ * @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);
+
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index 930168275..40934b3ed 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 the libgit2 contributors
+ * 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.
@@ -20,54 +20,177 @@
*/
GIT_BEGIN_DECL
+/**
+ * Opaque structure representing a submodule.
+ *
+ * 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.
+ */
+typedef struct git_submodule git_submodule;
+
+/**
+ * Values that could be specified for the update rule of a submodule.
+ *
+ * Use the DEFAULT value if you have altered the update value via
+ * `git_submodule_set_update()` and wish to reset to the original default.
+ */
typedef enum {
+ GIT_SUBMODULE_UPDATE_DEFAULT = -1,
GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
GIT_SUBMODULE_UPDATE_REBASE = 1,
- GIT_SUBMODULE_UPDATE_MERGE = 2
+ GIT_SUBMODULE_UPDATE_MERGE = 2,
+ GIT_SUBMODULE_UPDATE_NONE = 3
} git_submodule_update_t;
+/**
+ * Values that could be specified for how closely to examine the
+ * working directory when getting submodule status.
+ *
+ * Use the DEFUALT value if you have altered the ignore value via
+ * `git_submodule_set_ignore()` and wish to reset to the original value.
+ */
typedef enum {
- GIT_SUBMODULE_IGNORE_ALL = 0, /* never dirty */
- GIT_SUBMODULE_IGNORE_DIRTY = 1, /* only dirty if HEAD moved */
- GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
- GIT_SUBMODULE_IGNORE_NONE = 3 /* any change or untracked == dirty */
+ GIT_SUBMODULE_IGNORE_DEFAULT = -1, /* reset to default */
+ GIT_SUBMODULE_IGNORE_NONE = 0, /* any change or untracked == dirty */
+ GIT_SUBMODULE_IGNORE_UNTRACKED = 1, /* dirty if tracked files change */
+ GIT_SUBMODULE_IGNORE_DIRTY = 2, /* only dirty if HEAD moved */
+ GIT_SUBMODULE_IGNORE_ALL = 3 /* never dirty */
} git_submodule_ignore_t;
/**
- * Description of submodule
+ * 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.
*
- * This record describes a submodule found in a repository. There
- * should be an entry for every submodule found in the HEAD and for
- * every submodule described in .gitmodules. The fields are as follows:
+ * 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.
*
- * - `name` is the name of the submodule from .gitmodules.
- * - `path` is the path to the submodule from the repo working directory.
- * It is almost always the same as `name`.
- * - `url` is the url for the submodule.
- * - `oid` is the HEAD SHA1 for the submodule.
- * - `update` is a value from above - see gitmodules(5) update.
- * - `ignore` is a value from above - see gitmodules(5) ignore.
- * - `fetch_recurse` is 0 or 1 - see gitmodules(5) fetchRecurseSubmodules.
- * - `refcount` is for internal use.
+ * 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".
*
- * If the submodule has been added to .gitmodules but not yet git added,
- * then the `oid` will be zero. If the submodule has been deleted, but
- * the delete has not been committed yet, then the `oid` will be set, but
- * the `url` will be NULL.
+ * * 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 struct {
- char *name;
- char *path;
- char *url;
- git_oid oid; /* sha1 of submodule HEAD ref or zero if not committed */
- git_submodule_update_t update;
- git_submodule_ignore_t ignore;
- int fetch_recurse;
- int refcount;
-} git_submodule;
+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 \
+ (GIT_SUBMODULE_STATUS_IN_HEAD | \
+ GIT_SUBMODULE_STATUS_IN_INDEX | \
+ GIT_SUBMODULE_STATUS_IN_CONFIG | \
+ GIT_SUBMODULE_STATUS_IN_WD)
+
+#define GIT_SUBMODULE_STATUS__INDEX_FLAGS \
+ (GIT_SUBMODULE_STATUS_INDEX_ADDED | \
+ GIT_SUBMODULE_STATUS_INDEX_DELETED | \
+ GIT_SUBMODULE_STATUS_INDEX_MODIFIED)
+
+#define GIT_SUBMODULE_STATUS__WD_FLAGS \
+ ~(GIT_SUBMODULE_STATUS__IN_FLAGS | GIT_SUBMODULE_STATUS__INDEX_FLAGS)
+
+#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) == 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)
+
+/**
+ * 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 is a valid self-contained git repo). In this case, this function
+ * returns GIT_EEXISTS to indicate the the submodule 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.
+ *
+ * The submodule object is owned by the containing repo and will be freed
+ * when the repo is freed. The caller need not free the submodule.
+ *
+ * @param submodule Pointer to submodule description object pointer..
+ * @param repo The repository.
+ * @param name The name of the submodule. Trailing slashes will be ignored.
+ * @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
+ * GIT_EEXISTS if submodule exists in working directory only, -1 on
+ * other errors.
+ */
+GIT_EXTERN(int) git_submodule_lookup(
+ git_submodule **submodule,
+ git_repository *repo,
+ const char *name);
/**
- * Iterate over all submodules of a repository.
+ * Iterate over all tracked submodules of a repository.
+ *
+ * See the note on `git_submodule` above. This iterates over the tracked
+ * submodules as decribed 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.
@@ -77,26 +200,344 @@ typedef struct {
*/
GIT_EXTERN(int) git_submodule_foreach(
git_repository *repo,
- int (*callback)(const char *name, void *payload),
+ int (*callback)(git_submodule *sm, const char *name, void *payload),
void *payload);
/**
- * Lookup submodule information by name or path.
+ * Set up a new git submodule for checkout.
*
- * Given either the submodule name or path (they are ususally the same),
- * this returns a structure describing the submodule. If the submodule
- * does not exist, this will return GIT_ENOTFOUND and set the submodule
- * pointer to NULL.
+ * 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.
*
- * @param submodule Pointer to submodule description object pointer..
- * @param repo The repository.
- * @param name The name of the submodule. Trailing slashes will be ignored.
- * @return 0 on success, GIT_ENOTFOUND if submodule does not exist, -1 on error
+ * To fully emulate "git submodule add" call this function, then open the
+ * submodule repo and perform the clone step as needed. Lastly, call
+ * `git_submodule_add_finalize()` to wrap up adding the new submodule and
+ * .gitmodules to the index to be ready to commit.
+ *
+ * @param submodule The newly created submodule ready to open for clone
+ * @param repo Superproject repository to contain the new submodule
+ * @param url URL for the submodules 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_lookup(
+GIT_EXTERN(int) git_submodule_add_setup(
git_submodule **submodule,
git_repository *repo,
- const char *name);
+ const char *url,
+ const char *path,
+ int use_gitlink);
+
+/**
+ * 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.
+ */
+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);
+
+/**
+ * Write submodule settings to .gitmodules file.
+ *
+ * This commits any in-memory changes to the submodule to the gitmodules
+ * file on disk. You may also be interested in `git_submodule_init()` which
+ * writes submodule info to ".git/config" (which is better for local changes
+ * to submodule settings) and/or `git_submodule_sync()` which writes
+ * settings about remotes to the actual submodule repository.
+ *
+ * @param submodule The submodule to write.
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_submodule_save(git_submodule *submodule);
+
+/**
+ * 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);
+
+/**
+ * Set the URL for the submodule.
+ *
+ * This sets the URL in memory for the submodule. This will be used for
+ * any following submodule actions while this submodule data is in memory.
+ *
+ * After calling this, you may wish to call `git_submodule_save()` to write
+ * the changes back to the ".gitmodules" file and `git_submodule_sync()` to
+ * write the changes to the checked out submodule repository.
+ *
+ * @param submodule Pointer to the submodule object
+ * @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_submodule *submodule, 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 for the 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.
+ */
+GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
+ git_submodule *submodule);
+
+/**
+ * Set the ignore rule for the submodule.
+ *
+ * This sets the ignore rule in memory for the submodule. This will be used
+ * for any following actions (such as `git_submodule_status()`) while the
+ * submodule is in memory. You should call `git_submodule_save()` if you
+ * want to persist the new ignore role.
+ *
+ * Calling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling
+ * `git_submodule_reload()` will revert the rule to the value that was in the
+ * original config.
+ *
+ * @return old value for ignore
+ */
+GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
+ git_submodule *submodule,
+ git_submodule_ignore_t ignore);
+
+/**
+ * Get the update rule for the submodule.
+ */
+GIT_EXTERN(git_submodule_update_t) git_submodule_update(
+ git_submodule *submodule);
+
+/**
+ * Set the update rule for the submodule.
+ *
+ * This sets the update rule in memory for the submodule. You should call
+ * `git_submodule_save()` if you want to persist the new update rule.
+ *
+ * Calling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling
+ * `git_submodule_reload()` will revert the rule to the value that was in the
+ * original config.
+ *
+ * @return old value for update
+ */
+GIT_EXTERN(git_submodule_update_t) git_submodule_set_update(
+ git_submodule *submodule,
+ 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(int) git_submodule_fetch_recurse_submodules(
+ git_submodule *submodule);
+
+/**
+ * Set the fetchRecurseSubmodules rule for a submodule.
+ *
+ * This sets the submodule.<name>.fetchRecurseSubmodules value for
+ * the submodule. You should call `git_submodule_save()` if you want
+ * to persist the new value.
+ *
+ * @param submodule The submodule to modify
+ * @param fetch_recurse_submodules Boolean value
+ * @return old value for fetchRecurseSubmodules
+ */
+GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
+ git_submodule *submodule,
+ int 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);
+
+/**
+ * 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.
+ */
+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 subrepo 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.
+ */
+GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule);
+
+/**
+ * Reread all submodule info.
+ *
+ * Call this to reload all cached submodule information for the repo.
+ */
+GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo);
+
+/**
+ * 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 - which can be
+ * set either temporarily or permanently with `git_submodule_set_ignore()`.
+ *
+ * @param status Combination of `GIT_SUBMODULE_STATUS` flags
+ * @param submodule Submodule for which to get status
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_status(
+ unsigned int *status,
+ git_submodule *submodule);
+
+/**
+ * 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 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
diff --git a/include/git2/tag.h b/include/git2/tag.h
index 859c28995..84c954c27 100644
--- a/include/git2/tag.h
+++ b/include/git2/tag.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -11,6 +11,7 @@
#include "types.h"
#include "oid.h"
#include "object.h"
+#include "strarray.h"
/**
* @file git2/tag.h
@@ -24,14 +25,16 @@ GIT_BEGIN_DECL
/**
* Lookup a tag object from the repository.
*
- * @param tag pointer to the looked up tag
+ * @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_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id)
+GIT_INLINE(int) git_tag_lookup(
+ git_tag **out, git_repository *repo, const git_oid *id)
{
- return git_object_lookup((git_object **)tag, repo, id, (git_otype)GIT_OBJ_TAG);
+ return git_object_lookup(
+ (git_object **)out, repo, id, (git_otype)GIT_OBJ_TAG);
}
/**
@@ -40,32 +43,33 @@ GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oi
*
* @see git_object_lookup_prefix
*
- * @param tag pointer to the looked up tag
+ * @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_INLINE(int) git_tag_lookup_prefix(git_tag **tag, git_repository *repo, const git_oid *id, unsigned int len)
+GIT_INLINE(int) git_tag_lookup_prefix(
+ git_tag **out, git_repository *repo, const git_oid *id, size_t len)
{
- return git_object_lookup_prefix((git_object **)tag, repo, id, len, (git_otype)GIT_OBJ_TAG);
+ return git_object_lookup_prefix(
+ (git_object **)out, repo, id, len, (git_otype)GIT_OBJ_TAG);
}
/**
* Close an open tag
*
- * This is a wrapper around git_object_free()
+ * You can no longer use the git_tag pointer after this call.
*
- * IMPORTANT:
- * It *is* necessary to call this method when you stop
- * using a tag. Failure to do so will cause a memory leak.
+ * 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_INLINE(void) git_tag_free(git_tag *tag)
{
- git_object_free((git_object *) tag);
+ git_object_free((git_object *)tag);
}
@@ -75,7 +79,7 @@ GIT_INLINE(void) git_tag_free(git_tag *tag)
* @param tag a previously loaded tag.
* @return object identity for the tag.
*/
-GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
+GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag);
/**
* Get the tagged object of a tag
@@ -83,11 +87,11 @@ GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
* This method performs a repository lookup for the
* given object and returns it
*
- * @param target pointer where to store the target
+ * @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, git_tag *tag);
+GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag);
/**
* Get the OID of the tagged object of a tag
@@ -95,7 +99,7 @@ GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag);
* @param tag a previously loaded tag.
* @return pointer to the OID
*/
-GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag);
+GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag);
/**
* Get the type of a tag's tagged object
@@ -103,7 +107,7 @@ GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag);
* @param tag a previously loaded tag.
* @return type of the tagged object
*/
-GIT_EXTERN(git_otype) git_tag_type(git_tag *tag);
+GIT_EXTERN(git_otype) git_tag_target_type(const git_tag *tag);
/**
* Get the name of a tag
@@ -111,23 +115,23 @@ GIT_EXTERN(git_otype) git_tag_type(git_tag *tag);
* @param tag a previously loaded tag.
* @return name of the tag
*/
-GIT_EXTERN(const char *) git_tag_name(git_tag *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
+ * @return reference to the tag's author or NULL when unspecified
*/
-GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag);
+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
+ * @return message of the tag or NULL when unspecified
*/
-GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
+GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
/**
@@ -137,8 +141,12 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
* this tag object. If `force` is true and a reference
* already exists with the given name, it'll be replaced.
*
- * The message will be cleaned up from excess whitespace
- * it will be made sure that the last line ends with a '\n'.
+ * 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
@@ -161,18 +169,18 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
*
* @param force Overwrite existing references
*
- * @return 0 or an error code
+ * @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);
+ 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 repository from a buffer
@@ -181,13 +189,13 @@ GIT_EXTERN(int) git_tag_create(
* @param repo Repository where to store the tag
* @param buffer Raw tag data
* @param force Overwrite existing tags
- * @return 0 on sucess; error code otherwise
+ * @return 0 on success; error code otherwise
*/
GIT_EXTERN(int) git_tag_create_frombuffer(
- git_oid *oid,
- git_repository *repo,
- const char *buffer,
- int force);
+ git_oid *oid,
+ git_repository *repo,
+ const char *buffer,
+ int force);
/**
* Create a new lightweight tag pointing at a target object
@@ -196,6 +204,9 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
* 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
@@ -212,30 +223,33 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
*
* @param force Overwrite existing references
*
- * @return 0 or an error code
+ * @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);
+ 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 or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_tag_delete(
- git_repository *repo,
- const char *tag_name);
+ git_repository *repo,
+ const char *tag_name);
/**
* Fill a list with all the tags in the Repository
@@ -251,8 +265,8 @@ GIT_EXTERN(int) git_tag_delete(
* @return 0 or an error code
*/
GIT_EXTERN(int) git_tag_list(
- git_strarray *tag_names,
- git_repository *repo);
+ git_strarray *tag_names,
+ git_repository *repo);
/**
* Fill a list with all the tags in the Repository
@@ -273,24 +287,39 @@ GIT_EXTERN(int) git_tag_list(
* @return 0 or an error code
*/
GIT_EXTERN(int) git_tag_list_match(
- git_strarray *tag_names,
- const char *pattern,
- git_repository *repo);
+ git_strarray *tag_names,
+ const char *pattern,
+ git_repository *repo);
+
+
+typedef int (*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 met
+ * 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 Pointer to the peeled git_object
+ * @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,
- git_tag *tag);
+ git_object **tag_target_out,
+ const git_tag *tag);
/** @} */
GIT_END_DECL
diff --git a/include/git2/threads.h b/include/git2/threads.h
index 567a10487..11f89729a 100644
--- a/include/git2/threads.h
+++ b/include/git2/threads.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -27,8 +27,10 @@ GIT_BEGIN_DECL
*
* If libgit2 has been built without GIT_THREADS
* support, this function is a no-op.
+ *
+ * @return 0 or an error code
*/
-GIT_EXTERN(void) git_threads_init(void);
+GIT_EXTERN(int) git_threads_init(void);
/**
* Shutdown the threading system.
diff --git a/include/git2/trace.h b/include/git2/trace.h
new file mode 100644
index 000000000..7409b032d
--- /dev/null
+++ b/include/git2/trace.h
@@ -0,0 +1,68 @@
+/*
+ * 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_trace_callback)(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_callback cb);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/transport.h b/include/git2/transport.h
new file mode 100644
index 000000000..5e9968363
--- /dev/null
+++ b/include/git2/transport.h
@@ -0,0 +1,328 @@
+/*
+ * 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"
+
+/**
+ * @file git2/transport.h
+ * @brief Git transport interfaces and functions
+ * @defgroup git_transport interfaces and functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/*
+ *** Begin interface for credentials acquisition ***
+ */
+
+typedef enum {
+ /* git_cred_userpass_plaintext */
+ GIT_CREDTYPE_USERPASS_PLAINTEXT = 1,
+} git_credtype_t;
+
+/* The base structure for all credential types */
+typedef struct git_cred {
+ git_credtype_t credtype;
+ void (*free)(
+ struct git_cred *cred);
+} git_cred;
+
+/* A plaintext username and password */
+typedef struct git_cred_userpass_plaintext {
+ git_cred parent;
+ char *username;
+ char *password;
+} git_cred_userpass_plaintext;
+
+/**
+ * Creates 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_cred_userpass_plaintext_new(
+ git_cred **out,
+ const char *username,
+ const char *password);
+
+/**
+ * Signature of a function which acquires a credential object.
+ *
+ * @param cred 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 cred types are OK to return.
+ * @param payload The payload provided when specifying this callback.
+ * @return 0 for success or an error code for failure
+ */
+typedef int (*git_cred_acquire_cb)(
+ git_cred **cred,
+ const char *url,
+ const char *username_from_url,
+ unsigned int allowed_types,
+ void *payload);
+
+/*
+ *** End interface for credentials acquisition ***
+ *** Begin base transport interface ***
+ */
+
+typedef enum {
+ GIT_TRANSPORTFLAGS_NONE = 0,
+ /* If the connection is secured with SSL/TLS, the authenticity
+ * of the server certificate should not be verified. */
+ GIT_TRANSPORTFLAGS_NO_CHECK_CERT = 1
+} git_transport_flags_t;
+
+typedef void (*git_transport_message_cb)(const char *str, int len, void *data);
+
+typedef struct git_transport {
+ unsigned int version;
+ /* Set progress and error callbacks */
+ int (*set_callbacks)(struct git_transport *transport,
+ git_transport_message_cb progress_cb,
+ git_transport_message_cb error_cb,
+ void *payload);
+
+ /* Connect the transport to the remote repository, using the given
+ * direction. */
+ int (*connect)(struct git_transport *transport,
+ const char *url,
+ git_cred_acquire_cb cred_acquire_cb,
+ void *cred_acquire_payload,
+ int direction,
+ int flags);
+
+ /* This function may be called after a successful call to connect(). The
+ * provided callback is invoked for each ref discovered on the remote
+ * end. */
+ int (*ls)(struct git_transport *transport,
+ git_headlist_cb list_cb,
+ void *payload);
+
+ /* Executes the push whose context is in the git_push object. */
+ int (*push)(struct git_transport *transport, git_push *push);
+
+ /* This function may be called after a successful call to connect(), when
+ * the direction is FETCH. The function performs a negotiation to calculate
+ * the wants list for the fetch. */
+ int (*negotiate_fetch)(struct git_transport *transport,
+ git_repository *repo,
+ const git_remote_head * const *refs,
+ size_t count);
+
+ /* This function may be called after a successful call to negotiate_fetch(),
+ * when the direction is FETCH. This function retrieves the pack file for
+ * the fetch from the remote end. */
+ int (*download_pack)(struct git_transport *transport,
+ git_repository *repo,
+ git_transfer_progress *stats,
+ git_transfer_progress_callback progress_cb,
+ void *progress_payload);
+
+ /* Checks to see if the transport is connected */
+ int (*is_connected)(struct git_transport *transport);
+
+ /* Reads the flags value previously passed into connect() */
+ int (*read_flags)(struct git_transport *transport, int *flags);
+
+ /* Cancels any outstanding transport operation */
+ void (*cancel)(struct git_transport *transport);
+
+ /* This function is the reverse of connect() -- it terminates the
+ * connection to the remote end. */
+ int (*close)(struct git_transport *transport);
+
+ /* Frees/destructs the git_transport object. */
+ void (*free)(struct git_transport *transport);
+} git_transport;
+
+#define GIT_TRANSPORT_VERSION 1
+#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_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);
+
+/* Signature of a function which creates a transport */
+typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
+
+/* 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);
+
+/*
+ *** End of base transport interface ***
+ *** Begin interface for subtransports for the smart transport ***
+ */
+
+/* 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 implemented: git, http, and winhttp. (The http and
+ * winhttp transports each implement both http and https.) */
+
+/* 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 and winhttp are both
+ * RPC = 1. */
+
+/* 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;
+
+struct git_smart_subtransport;
+
+/* A stream used by the smart transport to read and write data
+ * from a subtransport */
+typedef struct git_smart_subtransport_stream {
+ /* The owning subtransport */
+ struct git_smart_subtransport *subtransport;
+
+ int (*read)(
+ struct git_smart_subtransport_stream *stream,
+ char *buffer,
+ size_t buf_size,
+ size_t *bytes_read);
+
+ int (*write)(
+ struct git_smart_subtransport_stream *stream,
+ const char *buffer,
+ size_t len);
+
+ void (*free)(
+ struct git_smart_subtransport_stream *stream);
+} git_smart_subtransport_stream;
+
+/* An implementation of a subtransport which carries data for the
+ * smart transport */
+typedef struct git_smart_subtransport {
+ int (* action)(
+ git_smart_subtransport_stream **out,
+ struct git_smart_subtransport *transport,
+ const char *url,
+ git_smart_service_t action);
+
+ /* Subtransports are guaranteed a call to close() between
+ * calls to action(), except for the following two "natural" progressions
+ * of actions against a constant URL.
+ *
+ * 1. UPLOADPACK_LS -> UPLOADPACK
+ * 2. RECEIVEPACK_LS -> RECEIVEPACK */
+ int (* close)(struct git_smart_subtransport *transport);
+
+ void (* free)(struct git_smart_subtransport *transport);
+} git_smart_subtransport;
+
+/* A function which creates a new subtransport for the smart transport */
+typedef int (*git_smart_subtransport_cb)(
+ git_smart_subtransport **out,
+ git_transport* owner);
+
+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;
+} git_smart_subtransport_definition;
+
+/* Smart transport subtransports that come with libgit2 */
+
+/**
+ * Create an instance of the http subtransport. This subtransport
+ * also supports https. On Win32, this subtransport may be implemented
+ * using the WinHTTP library.
+ *
+ * @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);
+
+/**
+ * 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);
+
+/*
+ *** End interface for subtransports for the smart transport ***
+ */
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/tree.h b/include/git2/tree.h
index 777f8ff0d..73bfc86f4 100644
--- a/include/git2/tree.h
+++ b/include/git2/tree.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -24,14 +24,15 @@ GIT_BEGIN_DECL
/**
* Lookup a tree object from the repository.
*
- * @param tree 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 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_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id)
+GIT_INLINE(int) git_tree_lookup(
+ git_tree **out, git_repository *repo, const git_oid *id)
{
- return git_object_lookup((git_object **)tree, repo, id, GIT_OBJ_TREE);
+ return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE);
}
/**
@@ -46,36 +47,46 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git
* @param len the length of the short identifier
* @return 0 or an error code
*/
-GIT_INLINE(int) git_tree_lookup_prefix(git_tree **tree, git_repository *repo, const git_oid *id, unsigned int len)
+GIT_INLINE(int) git_tree_lookup_prefix(
+ git_tree **out,
+ git_repository *repo,
+ const git_oid *id,
+ size_t len)
{
- return git_object_lookup_prefix((git_object **)tree, repo, id, len, GIT_OBJ_TREE);
+ return git_object_lookup_prefix(
+ (git_object **)out, repo, id, len, GIT_OBJ_TREE);
}
/**
* Close an open tree
*
- * This is a wrapper around git_object_free()
+ * You can no longer use the git_tree pointer after this call.
*
- * IMPORTANT:
- * It *is* necessary to call this method when you stop
- * using a tree. Failure to do so will cause a memory leak.
+ * 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
+ * @param tree The tree to close
*/
-
GIT_INLINE(void) git_tree_free(git_tree *tree)
{
- git_object_free((git_object *) tree);
+ git_object_free((git_object *)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(git_tree *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
@@ -83,33 +94,87 @@ GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
* @param tree a previously loaded tree.
* @return the number of entries in the tree
*/
-GIT_EXTERN(unsigned int) git_tree_entrycount(git_tree *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(git_tree *tree, const char *filename);
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
+ 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(git_tree *tree, unsigned int idx);
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
+ git_tree *tree, size_t idx);
/**
- * Get the UNIX file attributes of a tree entry
+ * Lookup a tree entry by SHA value.
*
- * @param entry a tree entry
- * @return attributes as an integer
+ * 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 oid the sha being looked for
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid(
+ const git_tree *tree, const git_oid *oid);
+
+/**
+ * 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 subtree_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,
+ 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 entry A tree entry to duplicate
+ * @return a copy of the original entry or NULL on error (alloc failure)
+ */
+GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry);
+
+/**
+ * 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(unsigned int) git_tree_entry_attributes(const git_tree_entry *entry);
+GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry);
/**
* Get the filename of a tree entry
@@ -136,51 +201,55 @@ GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry);
GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
/**
- * Convert a tree entry to the git_object it points too.
+ * Get the UNIX file attributes of a tree entry
*
- * @param object 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
+ * @return filemode as an integer
*/
-GIT_EXTERN(int) git_tree_entry_to_object(git_object **object_out, git_repository *repo, const git_tree_entry *entry);
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
/**
- * Write a tree to the ODB from the index file
+ * Compare two tree entries
*
- * 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.
+ * @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 too.
*
- * The index instance cannot be bare, and needs to be associated
- * to an existing repository.
+ * You must call `git_object_free()` on the object when you are done with it.
*
- * @param oid Pointer where to store the written tree
- * @param index Index to write
+ * @param object 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_create_fromindex(git_oid *oid, git_index *index);
+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.
+ * 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 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
- * have no entries and will have to be filled manually.
+ * If the `source` parameter is NULL, the tree builder will start with no
+ * entries and will have to be filled manually.
*
- * @param builder_p Pointer where to store the tree builder
+ * @param out Pointer where to store the tree builder
* @param source Source tree to initialize the builder (optional)
- * @return 0 on sucess; error code otherwise
+ * @return 0 on success; error code otherwise
*/
-GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source);
+GIT_EXTERN(int) git_treebuilder_create(
+ git_treebuilder **out, const git_tree *source);
/**
* Clear all the entires in the builder
@@ -190,6 +259,14 @@ GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tr
GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld);
/**
+ * Get the number of entries listed in a treebuilder
+ *
+ * @param tree a previously loaded treebuilder.
+ * @return the number of entries in the treebuilder
+ */
+GIT_EXTERN(unsigned int) git_treebuilder_entrycount(git_treebuilder *bld);
+
+/**
* Free a tree builder
*
* This will clear all the entries and free to builder.
@@ -210,7 +287,8 @@ GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld);
* @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);
+GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
+ git_treebuilder *bld, const char *filename);
/**
* Add or update an entry to the builder
@@ -218,20 +296,31 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con
* Insert a new entry for `filename` in the builder with the
* given attributes.
*
- * if an entry named `filename` already exists, its attributes
+ * If an entry named `filename` already exists, its attributes
* will be updated with the given ones.
*
- * The optional pointer `entry_out` can be used to retrieve a
- * pointer to the newly created/updated entry.
+ * 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.
+ *
+ * No attempt is being made to ensure that the provided oid points
+ * to an existing git object in the object database, nor that the
+ * attributes make sense regarding the type of the pointed at object.
*
- * @param entry_out Pointer to store the entry (optional)
+ * @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 attributes Folder attributes 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(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes);
+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
@@ -239,78 +328,75 @@ GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuild
* @param bld Tree builder
* @param filename Filename of the entry to remove
*/
-GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filename);
+GIT_EXTERN(int) git_treebuilder_remove(
+ git_treebuilder *bld, const char *filename);
+
+typedef int (*git_treebuilder_filter_cb)(
+ const git_tree_entry *entry, void *payload);
/**
* Filter the 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 1, the
- * entry will be filtered (removed from the builder).
+ * 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
*/
-GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(const git_tree_entry *, void *), void *payload);
+GIT_EXTERN(void) 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
- * it's identifying SHA1 hash will be stored in the `oid`
- * pointer.
+ * The tree builder will be written to the given `repo`, and its
+ * identifying SHA1 hash will be stored in the `id` pointer.
*
- * @param oid Pointer where to store the written OID
- * @param repo Repository where to store the object
+ * @param id Pointer to store the OID of the newly written tree
+ * @param repo Repository in which to store the object
* @param bld Tree builder to write
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld);
+GIT_EXTERN(int) git_treebuilder_write(
+ git_oid *id, git_repository *repo, git_treebuilder *bld);
-/**
- * Retrieve a subtree contained in a tree, given its
- * relative path.
- *
- * The returned tree is owned by the repository and
- * should be closed with the `git_object_free` method.
- *
- * @param subtree Pointer where to store the subtree
- * @param root A previously loaded tree which will be the root of the relative path
- * @param subtree_path Path to the contained subtree
- * @return 0 on success; GIT_ENOTFOUND if the path does not lead to a subtree
- */
-GIT_EXTERN(int) git_tree_get_subtree(git_tree **subtree, git_tree *root, const char *subtree_path);
/** Callback for the tree traversal method */
-typedef int (*git_treewalk_cb)(const char *root, git_tree_entry *entry, void *payload);
+typedef int (*git_treewalk_cb)(
+ const char *root, const git_tree_entry *entry, void *payload);
/** Tree traversal modes */
-enum git_treewalk_mode {
+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
+ * 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.
+ * 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 negative value, the passed entry
- * will be skiped on the traversal.
+ * 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 callback Function to call on each tree entry
* @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(git_tree *tree, git_treewalk_cb callback, int mode, void *payload);
+GIT_EXTERN(int) git_tree_walk(
+ const git_tree *tree,
+ git_treewalk_mode mode,
+ git_treewalk_cb callback,
+ void *payload);
/** @} */
diff --git a/include/git2/types.h b/include/git2/types.h
index cfb0acf33..bc15050ce 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -32,6 +32,9 @@ GIT_BEGIN_DECL
* stat() functions, for all platforms.
*/
#include <sys/types.h>
+#ifdef __amigaos4__
+#include <stdint.h>
+#endif
#if defined(_MSC_VER)
@@ -86,6 +89,15 @@ 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;
+
+/** An open refs database handle. */
+typedef struct git_refdb git_refdb;
+
+/** A custom backend for refs */
+typedef struct git_refdb_backend git_refdb_backend;
+
/**
* Representation of an existing git repository,
* including all its object contents
@@ -123,7 +135,7 @@ typedef struct git_index git_index;
typedef struct git_config git_config;
/** Interface to access a configuration file */
-typedef struct git_config_file git_config_file;
+typedef struct git_config_backend git_config_backend;
/** Representation of a reference log entry */
typedef struct git_reflog_entry git_reflog_entry;
@@ -134,6 +146,9 @@ 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 */
@@ -155,9 +170,7 @@ typedef enum {
GIT_REF_INVALID = 0, /** Invalid reference */
GIT_REF_OID = 1, /** A reference which points at an object id */
GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */
- GIT_REF_PACKED = 4,
- GIT_REF_HAS_PEEL = 8,
- GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
+ GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
} git_ref_t;
/** Basic type of any Git branch. */
@@ -166,10 +179,22 @@ typedef enum {
GIT_BRANCH_REMOTE = 2,
} git_branch_t;
+/** Valid modes for index and tree entries. */
+typedef enum {
+ GIT_FILEMODE_NEW = 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;
+
typedef struct git_refspec git_refspec;
typedef struct git_remote git_remote;
+typedef struct git_push git_push;
typedef struct git_remote_head git_remote_head;
+typedef struct git_remote_callbacks git_remote_callbacks;
/** @} */
GIT_END_DECL
diff --git a/include/git2/version.h b/include/git2/version.h
index 8edbe323c..630d51526 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 the libgit2 contributors
+ * 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.
@@ -7,9 +7,9 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.17.0"
+#define LIBGIT2_VERSION "0.18.0"
#define LIBGIT2_VER_MAJOR 0
-#define LIBGIT2_VER_MINOR 17
+#define LIBGIT2_VER_MINOR 18
#define LIBGIT2_VER_REVISION 0
#endif
diff --git a/include/git2/windows.h b/include/git2/windows.h
deleted file mode 100644
index 8b743f0aa..000000000
--- a/include/git2/windows.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2009-2012 the libgit2 contributors
- *
- * 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_windows_h__
-#define INCLUDE_git_windows_h__
-
-#include "common.h"
-
-/**
- * @file git2/windows.h
- * @brief Windows-specific functions
- * @ingroup Git
- * @{
- */
-GIT_BEGIN_DECL
-
-/**
- * Set the active codepage for Windows syscalls
- *
- * All syscalls performed by the library will assume
- * this codepage when converting paths and strings
- * to use by the Windows kernel.
- *
- * The default value of UTF-8 will work automatically
- * with most Git repositories created on Unix systems.
- *
- * This settings needs only be changed when working
- * with repositories that contain paths in specific,
- * non-UTF codepages.
- *
- * A full list of all available codepage identifiers may
- * be found at:
- *
- * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
- *
- * @param codepage numeric codepage identifier
- */
-GIT_EXTERN(void) gitwin_set_codepage(unsigned int codepage);
-
-/**
- * Return the active codepage for Windows syscalls
- *
- * @return numeric codepage identifier
- */
-GIT_EXTERN(unsigned int) gitwin_get_codepage(void);
-
-/**
- * Set the active Windows codepage to UTF-8 (this is
- * the default value)
- */
-GIT_EXTERN(void) gitwin_set_utf8(void);
-
-/** @} */
-GIT_END_DECL
-#endif
-