summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/git2.h2
-rw-r--r--include/git2/attr.h3
-rw-r--r--include/git2/blame.h17
-rw-r--r--include/git2/blob.h54
-rw-r--r--include/git2/branch.h60
-rw-r--r--include/git2/checkout.h90
-rw-r--r--include/git2/cherrypick.h87
-rw-r--r--include/git2/clone.h163
-rw-r--r--include/git2/commit.h59
-rw-r--r--include/git2/common.h41
-rw-r--r--include/git2/config.h62
-rw-r--r--include/git2/diff.h428
-rw-r--r--include/git2/errors.h52
-rw-r--r--include/git2/filter.h9
-rw-r--r--include/git2/graph.h14
-rw-r--r--include/git2/index.h125
-rw-r--r--include/git2/indexer.h2
-rw-r--r--include/git2/merge.h449
-rw-r--r--include/git2/message.h23
-rw-r--r--include/git2/net.h5
-rw-r--r--include/git2/notes.h8
-rw-r--r--include/git2/object.h17
-rw-r--r--include/git2/odb.h17
-rw-r--r--include/git2/oid.h5
-rw-r--r--include/git2/pack.h16
-rw-r--r--include/git2/patch.h45
-rw-r--r--include/git2/pathspec.h3
-rw-r--r--include/git2/push.h29
-rw-r--r--include/git2/reflog.h21
-rw-r--r--include/git2/refs.h223
-rw-r--r--include/git2/refspec.h7
-rw-r--r--include/git2/remote.h127
-rw-r--r--include/git2/repository.h105
-rw-r--r--include/git2/reset.h19
-rw-r--r--include/git2/revert.h86
-rw-r--r--include/git2/revwalk.h42
-rw-r--r--include/git2/signature.h7
-rw-r--r--include/git2/stash.h18
-rw-r--r--include/git2/status.h53
-rw-r--r--include/git2/submodule.h75
-rw-r--r--include/git2/sys/commit.h42
-rw-r--r--include/git2/sys/config.h16
-rw-r--r--include/git2/sys/diff.h91
-rw-r--r--include/git2/sys/filter.h13
-rw-r--r--include/git2/sys/mempack.h85
-rw-r--r--include/git2/sys/odb_backend.h24
-rw-r--r--include/git2/sys/refdb_backend.h32
-rw-r--r--include/git2/transport.h71
-rw-r--r--include/git2/tree.h24
-rw-r--r--include/git2/types.h50
-rw-r--r--include/git2/version.h6
51 files changed, 2482 insertions, 640 deletions
diff --git a/include/git2.h b/include/git2.h
index d00a20a2e..f74976061 100644
--- a/include/git2.h
+++ b/include/git2.h
@@ -14,6 +14,7 @@
#include "git2/branch.h"
#include "git2/buffer.h"
#include "git2/checkout.h"
+#include "git2/cherrypick.h"
#include "git2/clone.h"
#include "git2/commit.h"
#include "git2/common.h"
@@ -43,6 +44,7 @@
#include "git2/remote.h"
#include "git2/repository.h"
#include "git2/reset.h"
+#include "git2/revert.h"
#include "git2/revparse.h"
#include "git2/revwalk.h"
#include "git2/signature.h"
diff --git a/include/git2/attr.h b/include/git2/attr.h
index f256ff861..3adbb2c24 100644
--- a/include/git2/attr.h
+++ b/include/git2/attr.h
@@ -199,8 +199,9 @@ typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *pa
* 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.
+ * The value will be returned from `git_attr_foreach`.
* @param payload Passed on as extra parameter to callback function.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_attr_foreach(
git_repository *repo,
diff --git a/include/git2/blame.h b/include/git2/blame.h
index 73bcc5bc6..7f0de1731 100644
--- a/include/git2/blame.h
+++ b/include/git2/blame.h
@@ -40,6 +40,9 @@ typedef enum {
* commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES.
* NOT IMPLEMENTED. */
GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3),
+ /** Restrict the search of commits to those reachable following only the
+ * first parents. */
+ GIT_BLAME_FIRST_PARENT = (1<<4),
} git_blame_flag_t;
/**
@@ -80,6 +83,18 @@ typedef struct git_blame_options {
#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
/**
+ * Initializes a `git_blame_options` with default values. Equivalent to
+ * creating an instance with GIT_BLAME_OPTIONS_INIT.
+ *
+ * @param opts The `git_blame_options` struct to initialize
+ * @param version Version of struct; pass `GIT_BLAME_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_blame_init_options(
+ git_blame_options *opts,
+ unsigned int version);
+
+/**
* Structure that represents a blame hunk.
*
* - `lines_in_hunk` is the number of lines in this hunk
@@ -183,7 +198,7 @@ GIT_EXTERN(int) git_blame_buffer(
git_blame **out,
git_blame *reference,
const char *buffer,
- uint32_t buffer_len);
+ size_t buffer_len);
/**
* Free memory allocated by git_blame_file or git_blame_buffer.
diff --git a/include/git2/blob.h b/include/git2/blob.h
index dcab4fbe0..c24ff7e7f 100644
--- a/include/git2/blob.h
+++ b/include/git2/blob.h
@@ -84,7 +84,7 @@ GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob);
* time.
*
* @param blob pointer to the blob
- * @return the pointer; NULL if the blob has no contents
+ * @return the pointer
*/
GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
@@ -159,37 +159,32 @@ 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.
+ * If the `hintpath` parameter is filled, it will be used to determine
+ * what git filters should be applied to the object before it is written
+ * to the object database.
*
+ * The implementation of the callback MUST respect the following rules:
*
- * The implementation of the callback has to respect the
- * following rules:
+ * - `content` must be filled by the callback. 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 libgit2.
*
- * - `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` must return the number of bytes that have been
+ * written to the `content` buffer.
*
- * - 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.
+ * - When there is no more data to stream, `callback` should return
+ * 0. This will prevent it from being invoked anymore.
*
+ * - If an error occurs, the callback should return a negative value.
+ * This value will be returned to the caller.
*
* @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
+ * @param repo Repository where the blob will be written.
+ * This repository can be bare or not.
+ * @param hintpath If not NULL, will be used to select data filters
+ * to apply onto the content of the blob to be created.
+ * @return 0 or error code (from either libgit2 or callback function)
*/
GIT_EXTERN(int) git_blob_create_fromchunks(
git_oid *id,
@@ -201,26 +196,27 @@ GIT_EXTERN(int) git_blob_create_fromchunks(
/**
* Write an in-memory buffer to the ODB as a blob
*
- * @param oid return the oid of the written blob
+ * @param id return the id of the written blob
* @param repo repository where to blob will be written
* @param buffer data to be written into the blob
* @param len length of the data
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len);
+GIT_EXTERN(int) git_blob_create_frombuffer(
+ git_oid *id, git_repository *repo, const void *buffer, size_t len);
/**
* Determine if the blob content is most certainly binary or not.
*
* The heuristic used to guess if a file is binary is taken from core git:
* Searching for NUL bytes and looking for a reasonable ratio of printable
- * to non-printable characters among the first 4000 bytes.
+ * to non-printable characters among the first 8000 bytes.
*
* @param blob The blob which content should be analyzed
* @return 1 if the content of the blob is detected
* as binary; 0 otherwise.
*/
-GIT_EXTERN(int) git_blob_is_binary(git_blob *blob);
+GIT_EXTERN(int) git_blob_is_binary(const git_blob *blob);
/** @} */
GIT_END_DECL
diff --git a/include/git2/branch.h b/include/git2/branch.h
index 44d6fd9c3..f28410000 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -43,6 +43,12 @@ GIT_BEGIN_DECL
*
* @param force Overwrite existing branch.
*
+ * @param signature The identity that will used to populate the reflog entry
+ *
+ * @param log_message The one line long message to be appended to the reflog.
+ * If NULL, the default is "Branch: created"; if you want something more
+ * useful, provide a message.
+ *
* @return 0, GIT_EINVALIDSPEC or an error code.
* A proper reference is written in the refs/heads namespace
* pointing to the provided target commit.
@@ -52,7 +58,9 @@ GIT_EXTERN(int) git_branch_create(
git_repository *repo,
const char *branch_name,
const git_commit *target,
- int force);
+ int force,
+ const git_signature *signature,
+ const char *log_message);
/**
* Delete an existing branch reference.
@@ -76,7 +84,7 @@ typedef struct git_branch_iterator git_branch_iterator;
* @param repo Repository where to find the branches.
* @param list_flags Filtering flags for the branch
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
- * or a combination of the two.
+ * or GIT_BRANCH_ALL.
*
* @return 0 on success or an error code
*/
@@ -115,13 +123,19 @@ GIT_EXTERN(void) git_branch_iterator_free(git_branch_iterator *iter);
*
* @param force Overwrite existing branch.
*
+ * @param signature The identity that will used to populate the reflog entry
+ *
+ * @param log_message The one line long message to be appended to the reflog
+ *
* @return 0 on success, GIT_EINVALIDSPEC or an error code.
*/
GIT_EXTERN(int) git_branch_move(
git_reference **out,
git_reference *branch,
const char *new_branch_name,
- int force);
+ int force,
+ const git_signature *signature,
+ const char *log_message);
/**
* Lookup a branch by its name in a repository.
@@ -165,8 +179,9 @@ GIT_EXTERN(int) git_branch_lookup(
* @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);
+GIT_EXTERN(int) git_branch_name(
+ const char **out,
+ const git_reference *ref);
/**
* Return the reference supporting the remote tracking branch,
@@ -182,7 +197,7 @@ GIT_EXTERN(int) git_branch_name(const char **out,
*/
GIT_EXTERN(int) git_branch_upstream(
git_reference **out,
- git_reference *branch);
+ const git_reference *branch);
/**
* Set the upstream configuration for a given local branch
@@ -200,25 +215,20 @@ GIT_EXTERN(int) git_branch_set_upstream(git_reference *branch, const char *upstr
* 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 out Pointer to the user-allocated git_buf which will be
+ * filled with the name of the reference.
*
* @param repo the repository where the branches live
*
- * @param canonical_branch_name name of the local branch.
+ * @param refname reference 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.
+ * @return 0, 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_buf *out,
git_repository *repo,
- const char *canonical_branch_name);
+ const char *refname);
/**
* Determine if the current local branch is pointed at by HEAD.
@@ -229,30 +239,24 @@ GIT_EXTERN(int) git_branch_upstream_name(
* error code otherwise.
*/
GIT_EXTERN(int) git_branch_is_head(
- git_reference *branch);
+ const 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 out Pointer to the user-allocated git_buf which will be filled iwth the name of the remote.
*
* @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
+ * @return 0, GIT_ENOTFOUND
* when no remote matching remote was found,
* 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_buf *out,
git_repository *repo,
const char *canonical_branch_name);
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
index efafdc3e4..ad44173e6 100644
--- a/include/git2/checkout.h
+++ b/include/git2/checkout.h
@@ -43,17 +43,17 @@ GIT_BEGIN_DECL
* 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 | |
- * ---------------------|-----------------------|----------------------|
+ * | 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
@@ -99,9 +99,14 @@ GIT_BEGIN_DECL
* files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and
* GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the
* stage 2 ("ours") or stage 3 ("theirs") version of files in the index.
+ *
+ * - GIT_CHECKOUT_DONT_OVERWRITE_IGNORED prevents ignored files from being
+ * overwritten. Normally, files that are ignored in the working directory
+ * are not considered "precious" and may be overwritten if the checkout
+ * target contains that file.
*/
typedef enum {
- GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */
+ 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),
@@ -144,6 +149,15 @@ typedef enum {
/** Ignore directories in use, they will be left empty */
GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
+ /** Don't overwrite ignored files that exist in the checkout target */
+ GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19),
+
+ /** Write normal merge files for conflicts */
+ GIT_CHECKOUT_CONFLICT_STYLE_MERGE = (1u << 20),
+
+ /** Include common ancestor data in diff3 format files for conflicts */
+ GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 = (1u << 21),
+
/**
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
*/
@@ -174,7 +188,12 @@ typedef enum {
* - 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.
+ * The non-zero return value will be propagated back and returned by the
+ * git_checkout_... call.
+ *
+ * Notification callbacks are made prior to modifying any files on disk,
+ * so canceling on any notification will still happen prior to any files
+ * being modified.
*/
typedef enum {
GIT_CHECKOUT_NOTIFY_NONE = 0,
@@ -206,12 +225,12 @@ typedef void (*git_checkout_progress_cb)(
/**
* Checkout options structure
*
- * Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTS_INIT` macro to
+ * Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTIONS_INIT` macro to
* correctly set the `version` field. E.g.
*
- * git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
+ * git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
*/
-typedef struct git_checkout_opts {
+typedef struct git_checkout_options {
unsigned int version;
unsigned int checkout_strategy; /** default will be a dry run */
@@ -239,12 +258,25 @@ typedef struct git_checkout_opts {
const char *target_directory; /** alternative checkout path to workdir */
+ const char *ancestor_label; /** the name of the common ancestor side of conflicts */
const char *our_label; /** the name of the "our" side of conflicts */
const char *their_label; /** the name of the "their" side of conflicts */
-} git_checkout_opts;
+} git_checkout_options;
+
+#define GIT_CHECKOUT_OPTIONS_VERSION 1
+#define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION}
-#define GIT_CHECKOUT_OPTS_VERSION 1
-#define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION}
+/**
+* Initializes a `git_checkout_options` with default values. Equivalent to
+* creating an instance with GIT_CHECKOUT_OPTIONS_INIT.
+*
+* @param opts the `git_checkout_options` struct to initialize.
+* @param version Version of struct; pass `GIT_CHECKOUT_OPTIONS_VERSION`
+* @return Zero on success; -1 on failure.
+*/
+GIT_EXTERN(int) git_checkout_init_options(
+ git_checkout_options *opts,
+ unsigned int version);
/**
* Updates files in the index and the working tree to match the content of
@@ -252,13 +284,13 @@ typedef struct git_checkout_opts {
*
* @param repo repository to check out (must be non-bare)
* @param opts specifies checkout options (may be NULL)
- * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
- * branch, GIT_ERROR otherwise (use giterr_last for information
- * about the error)
+ * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non
+ * existing branch, non-zero value returned by `notify_cb`, or
+ * other error code < 0 (use giterr_last for error details)
*/
GIT_EXTERN(int) git_checkout_head(
git_repository *repo,
- const git_checkout_opts *opts);
+ const git_checkout_options *opts);
/**
* Updates files in the working tree to match the content of the index.
@@ -266,13 +298,13 @@ GIT_EXTERN(int) git_checkout_head(
* @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)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ * code < 0 (use giterr_last for error details)
*/
GIT_EXTERN(int) git_checkout_index(
git_repository *repo,
git_index *index,
- const git_checkout_opts *opts);
+ const git_checkout_options *opts);
/**
* Updates files in the index and working tree to match the content of the
@@ -282,13 +314,13 @@ GIT_EXTERN(int) git_checkout_index(
* @param treeish a commit, tag or tree which content will be used to update
* the working directory (or NULL to use HEAD)
* @param opts specifies checkout options (may be NULL)
- * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
- * about the error)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ * code < 0 (use giterr_last for error details)
*/
GIT_EXTERN(int) git_checkout_tree(
git_repository *repo,
const git_object *treeish,
- const git_checkout_opts *opts);
+ const git_checkout_options *opts);
/** @} */
GIT_END_DECL
diff --git a/include/git2/cherrypick.h b/include/git2/cherrypick.h
new file mode 100644
index 000000000..9eccb0af9
--- /dev/null
+++ b/include/git2/cherrypick.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_cherrypick_h__
+#define INCLUDE_git_cherrypick_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/cherrypick.h
+ * @brief Git cherry-pick routines
+ * @defgroup git_cherrypick Git cherry-pick routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef struct {
+ unsigned int version;
+
+ /** For merge commits, the "mainline" is treated as the parent. */
+ unsigned int mainline;
+
+ git_merge_options merge_opts;
+ git_checkout_options checkout_opts;
+} git_cherry_pick_options;
+
+#define GIT_CHERRY_PICK_OPTIONS_VERSION 1
+#define GIT_CHERRY_PICK_OPTIONS_INIT {GIT_CHERRY_PICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initializes a `git_cherry_pick_options` with default values. Equivalent to
+ * creating an instance with GIT_CHERRY_PICK_OPTIONS_INIT.
+ *
+ * @param opts the `git_cherry_pick_options` struct to initialize
+ * @param version Version of struct; pass `GIT_CHERRY_PICK_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick_init_options(
+ git_cherry_pick_options *opts,
+ unsigned int version);
+
+/**
+ * Cherry-picks the given commit against the given "our" commit, producing an
+ * index that reflects the result of the cherry-pick.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param cherry_pick_commit the commit to cherry-pick
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *cherry_pick_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_options);
+
+/**
+ * Cherry-pick the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to cherry-pick
+ * @param commit the commit to cherry-pick
+ * @param cherry_pick_options the cherry-pick options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick(
+ git_repository *repo,
+ git_commit *commit,
+ const git_cherry_pick_options *cherry_pick_options);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/clone.h b/include/git2/clone.h
index 331cf92e7..05b7522ce 100644
--- a/include/git2/clone.h
+++ b/include/git2/clone.h
@@ -24,41 +24,108 @@
GIT_BEGIN_DECL
/**
+ * Options for bypassing the git-aware transport on clone. Bypassing
+ * it means that instead of a fetch, libgit2 will copy the object
+ * database directory instead of figuring out what it needs, which is
+ * faster. If possible, it will hardlink the files to save space.
+ */
+typedef enum {
+ /**
+ * Auto-detect (default), libgit2 will bypass the git-aware
+ * transport for local paths, but use a normal fetch for
+ * `file://` urls.
+ */
+ GIT_CLONE_LOCAL_AUTO,
+ /**
+ * Bypass the git-aware transport even for a `file://` url.
+ */
+ GIT_CLONE_LOCAL,
+ /**
+ * Do no bypass the git-aware transport
+ */
+ GIT_CLONE_NO_LOCAL,
+ /**
+ * Bypass the git-aware transport, but do not try to use
+ * hardlinks.
+ */
+ GIT_CLONE_LOCAL_NO_LINKS,
+} git_clone_local_t;
+
+/**
* Clone options structure
*
- * Use zeros to indicate default settings. It's easiest to use the
- * `GIT_CLONE_OPTIONS_INIT` macro:
+ * Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this:
*
* 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
- * - `ignore_cert_errors` should be set to 1 if errors validating the remote host's
- * certificate should be ignored.
- *
- * ** "origin" remote options: **
- * - `remote_name` is the name given to the "origin" remote. The default is
- * "origin".
- * - `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;
+ /**
+ * These options are passed to the checkout step. To disable
+ * checkout, set the `checkout_strategy` to
+ * `GIT_CHECKOUT_NONE`. Generally you will want the use
+ * GIT_CHECKOUT_SAFE_CREATE to create all files in the working
+ * directory for the newly cloned repository.
+ */
+ git_checkout_options checkout_opts;
+
+ /**
+ * Callbacks to use for reporting fetch progress.
+ */
git_remote_callbacks remote_callbacks;
+ /**
+ * Set to zero (false) to create a standard repo, or non-zero
+ * for a bare repo
+ */
int bare;
+
+ /**
+ * Set to 1 if errors validating the remote host's certificate
+ * should be ignored.
+ */
int ignore_cert_errors;
+
+ /**
+ * Whether to use a fetch or copy the object database.
+ */
+ git_clone_local_t local;
+
+ /**
+ * The name to be given to the remote that will be
+ * created. The default is "origin".
+ */
const char *remote_name;
+
+ /**
+ * The name of the branch to checkout. NULL means use the
+ * remote's default branch.
+ */
const char* checkout_branch;
+
+ /**
+ * The identity used when updating the reflog. NULL means to
+ * use the default signature using the config.
+ */
+ git_signature *signature;
} 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}, GIT_REMOTE_CALLBACKS_INIT}
+#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE_CREATE}, GIT_REMOTE_CALLBACKS_INIT}
+
+/**
+ * Initializes a `git_clone_options` with default values. Equivalent to
+ * creating an instance with GIT_CLONE_OPTIONS_INIT.
+ *
+ * @param opts The `git_clone_options` struct to initialize
+ * @param version Version of struct; pass `GIT_CLONE_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_clone_init_options(
+ git_clone_options *opts,
+ unsigned int version);
/**
* Clone a remote repository.
@@ -70,16 +137,17 @@ typedef struct git_clone_options {
* @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)
+ * @param options configuration options for the clone. If NULL, the
+ * function works as though GIT_OPTIONS_INIT were passed.
+ * @return 0 on success, any non-zero return value from a callback
+ * function, or a negative value to indicate an error (use
+ * `giterr_last` for a detailed error message)
*/
GIT_EXTERN(int) git_clone(
- git_repository **out,
- const char *url,
- const char *local_path,
- const git_clone_options *options);
+ git_repository **out,
+ const char *url,
+ const char *local_path,
+ const git_clone_options *options);
/**
* Clone into a repository
@@ -91,11 +159,48 @@ GIT_EXTERN(int) git_clone(
* @param repo the repository to use
* @param remote the remote repository to clone from
* @param co_opts options to use during checkout
- * @param branch the branch to checkout after the clone, pass NULL for the remote's
- * default branch
- * @return 0 on success or an error code
+ * @param branch the branch to checkout after the clone, pass NULL for the
+ * remote's default branch
+ * @param signature The identity used when updating the reflog.
+ * @return 0 on success, any non-zero return value from a callback
+ * function, or a negative value to indicate an error (use
+ * `giterr_last` for a detailed error message)
+ */
+GIT_EXTERN(int) git_clone_into(
+ git_repository *repo,
+ git_remote *remote,
+ const git_checkout_options *co_opts,
+ const char *branch,
+ const git_signature *signature);
+
+/**
+ * Perform a local clone into a repository
+ *
+ * A "local clone" bypasses any git-aware protocols and simply copies
+ * over the object database from the source repository. It is often
+ * faster than a git-aware clone, but no verification of the data is
+ * performed, and can copy over too much data.
+ *
+ * @param repo the repository to use
+ * @param remote the remote repository to clone from
+ * @param co_opts options to use during checkout
+ * @param branch the branch to checkout after the clone, pass NULL for the
+ * remote's default branch
+ * @param link wether to use hardlinks instead of copying
+ * objects. This is only possible if both repositories are on the same
+ * filesystem.
+ * @param signature the identity used when updating the reflog
+ * @return 0 on success, any non-zero return value from a callback
+ * function, or a negative value to indicate an error (use
+ * `giterr_last` for a detailed error message)
*/
-GIT_EXTERN(int) git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch);
+GIT_EXTERN(int) git_clone_local_into(
+ git_repository *repo,
+ git_remote *remote,
+ const git_checkout_options *co_opts,
+ const char *branch,
+ int link,
+ const git_signature *signature);
/** @} */
GIT_END_DECL
diff --git a/include/git2/commit.h b/include/git2/commit.h
index a08cf1c6c..fb53a701b 100644
--- a/include/git2/commit.h
+++ b/include/git2/commit.h
@@ -117,6 +117,17 @@ GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
GIT_EXTERN(const char *) git_commit_message_raw(const git_commit *commit);
/**
+ * Get the short "summary" of the git commit message.
+ *
+ * The returned message is the summary of the commit, comprising the
+ * first paragraph of the message with whitespace trimmed and squashed.
+ *
+ * @param commit a previously loaded commit.
+ * @return the summary of a commit or NULL on error
+ */
+GIT_EXTERN(const char *) git_commit_summary(git_commit *commit);
+
+/**
* Get the commit time (i.e. committer time) of a commit.
*
* @param commit a previously loaded commit.
@@ -231,8 +242,8 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
/**
* Create new commit in the repository from a list of `git_object` pointers
*
- * The message will not be cleaned up automatically. You can do that with
- * the `git_message_prettify()` function.
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
*
* @param id Pointer in which to store the OID of the newly created commit
*
@@ -243,7 +254,8 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
* is not direct, it will be resolved to a direct reference.
* Use "HEAD" to update the HEAD of the current branch and
* make it point to this commit. If the reference doesn't
- * exist yet, it will be created.
+ * exist yet, it will be created. If it does exist, the first
+ * parent must be the tip of this branch.
*
* @param author Signature with author and author time of commit
*
@@ -280,20 +292,20 @@ GIT_EXTERN(int) git_commit_create(
const char *message_encoding,
const char *message,
const git_tree *tree,
- int parent_count,
+ size_t parent_count,
const git_commit *parents[]);
/**
* Create new commit in the repository using a variable argument list.
*
- * The message will be cleaned up from excess whitespace and it will be made
- * sure that the last line ends with a '\n'.
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
*
* The parents for the commit are specified as a variable list of pointers
* to `const git_commit *`. Note that this is a convenience method which may
* not be safe to export for certain languages or compilers
*
- * All other parameters remain the same at `git_commit_create()`.
+ * All other parameters remain the same as `git_commit_create()`.
*
* @see git_commit_create
*/
@@ -306,9 +318,40 @@ GIT_EXTERN(int) git_commit_create_v(
const char *message_encoding,
const char *message,
const git_tree *tree,
- int parent_count,
+ size_t parent_count,
...);
+/**
+ * Amend an existing commit by replacing only non-NULL values.
+ *
+ * This creates a new commit that is exactly the same as the old commit,
+ * except that any non-NULL values will be updated. The new commit has
+ * the same parents as the old commit.
+ *
+ * The `update_ref` value works as in the regular `git_commit_create()`,
+ * updating the ref to point to the newly rewritten commit. If you want
+ * to amend a commit that is not currently the tip of the branch and then
+ * rewrite the following commits to reach a ref, pass this as NULL and
+ * update the rest of the commit chain and ref separately.
+ *
+ * Unlike `git_commit_create()`, the `author`, `committer`, `message`,
+ * `message_encoding`, and `tree` parameters can be NULL in which case this
+ * will use the values from the original `commit_to_amend`.
+ *
+ * All parameters have the same meanings as in `git_commit_create()`.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_amend(
+ git_oid *id,
+ const git_commit *commit_to_amend,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/common.h b/include/git2/common.h
index dca0c9c21..32237efed 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -37,13 +37,6 @@
# define GIT_EXTERN(type) extern type
#endif
-/** Declare a function as always inlined. */
-#if defined(_MSC_VER)
-# define GIT_INLINE(type) static __inline type
-#else
-# define GIT_INLINE(type) static inline type
-#endif
-
/** Declare a function's takes printf style arguments. */
#ifdef __GNUC__
# define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b)))
@@ -101,29 +94,34 @@ GIT_BEGIN_DECL
GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
/**
- * Combinations of these values describe the capabilities of libgit2.
+ * Combinations of these values describe the features with which libgit2
+ * was compiled
*/
typedef enum {
- GIT_CAP_THREADS = ( 1 << 0 ),
- GIT_CAP_HTTPS = ( 1 << 1 ),
- GIT_CAP_SSH = ( 1 << 2 ),
-} git_cap_t;
+ GIT_FEATURE_THREADS = (1 << 0),
+ GIT_FEATURE_HTTPS = (1 << 1),
+ GIT_FEATURE_SSH = (1 << 2),
+} git_feature_t;
/**
* Query compile time options for libgit2.
*
- * @return A combination of GIT_CAP_* values.
+ * @return A combination of GIT_FEATURE_* values.
*
- * - GIT_CAP_THREADS
+ * - GIT_FEATURE_THREADS
* Libgit2 was compiled with thread support. Note that thread support is
* still to be seen as a 'work in progress' - basic object lookups are
* believed to be threadsafe, but other operations may not be.
*
- * - GIT_CAP_HTTPS
+ * - GIT_FEATURE_HTTPS
* Libgit2 supports the https:// protocol. This requires the openssl
* library to be found when compiling libgit2.
+ *
+ * - GIT_FEATURE_SSH
+ * Libgit2 supports the SSH protocol for network operations. This requires
+ * the libssh2 library to be found when compiling libgit2
*/
-GIT_EXTERN(int) git_libgit2_capabilities(void);
+GIT_EXTERN(int) git_libgit2_features(void);
typedef enum {
@@ -163,12 +161,12 @@ typedef enum {
* >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)
+ * * opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)
*
* > Get the search path for a given level of config data. "level" must
* > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, 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.
+ * > buffer.
*
* * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
*
@@ -197,7 +195,7 @@ typedef enum {
* > across all repositories before libgit2 starts evicting objects
* > from the cache. This is a soft limit, in that the library might
* > briefly exceed it, but will start aggressively evicting objects
- * > from cache when that happens. The default cache size is 256Mb.
+ * > from cache when that happens. The default cache size is 256MB.
*
* * opts(GIT_OPT_ENABLE_CACHING, int enabled)
*
@@ -212,11 +210,10 @@ typedef enum {
* > Get the current bytes in cache and the maximum that would be
* > allowed in the cache.
*
- * * opts(GIT_OPT_GET_TEMPLATE_PATH, char *out, size_t len)
+ * * opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)
*
* > Get the default template path.
- * > The path is written to the `out`
- * > buffer up to size `len`. Returns GIT_EBUFS if buffer is too small.
+ * > The path is written to the `out` buffer.
*
* * opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)
*
diff --git a/include/git2/config.h b/include/git2/config.h
index 95da4bc03..21a5825a5 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -9,6 +9,7 @@
#include "common.h"
#include "types.h"
+#include "buffer.h"
/**
* @file git2/config.h
@@ -90,11 +91,10 @@ typedef struct {
* 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`.
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a global configuration file has been found. Its path will be stored in `out`.
*/
-GIT_EXTERN(int) git_config_find_global(char *out, size_t length);
+GIT_EXTERN(int) git_config_find_global(git_buf *out);
/**
* Locate the path to the global xdg compatible configuration file
@@ -107,25 +107,23 @@ GIT_EXTERN(int) git_config_find_global(char *out, size_t length);
* 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
+ * @param out Pointer to a user-allocated git_buf in which to store the path
* @return 0 if a xdg compatible configuration file has been
- * found. Its path will be stored in `buffer`.
+ * found. Its path will be stored in `out`.
*/
-GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length);
+GIT_EXTERN(int) git_config_find_xdg(git_buf *out);
/**
* Locate the path to the system configuration file
*
* If /etc/gitconfig doesn't exist, it will look for
* %PROGRAMFILES%\Git\etc\gitconfig.
-
- * @param out Buffer to store the path in
- * @param length size of the buffer in bytes
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
* @return 0 if a system configuration file has been
- * found. Its path will be stored in `buffer`.
+ * found. Its path will be stored in `out`.
*/
-GIT_EXTERN(int) git_config_find_system(char *out, size_t length);
+GIT_EXTERN(int) git_config_find_system(git_buf *out);
/**
* Open the global, XDG and system configuration files
@@ -228,6 +226,22 @@ GIT_EXTERN(int) git_config_open_level(
*/
GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
+/**
+ * Create a snapshot of the configuration
+ *
+ * Create a snapshot of the current state of a configuration, which
+ * allows you to look into a consistent view of the configuration for
+ * looking up complex values (e.g. a remote, submodule).
+ *
+ * The string returned when querying such a config object is valid
+ * until it is freed.
+ *
+ * @param out pointer in which to store the snapshot config object
+ * @param config configuration to snapshot
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_snapshot(git_config **out, git_config *config);
+
/**
* Reload changed config files
@@ -314,7 +328,8 @@ GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char
* Get the value of a string config variable.
*
* The string is owned by the variable and should not be freed by the
- * user.
+ * user. The pointer will be valid until the next operation on this
+ * config object.
*
* All config files will be looked into, in the order of their
* defined level. A higher level means a higher priority. The
@@ -355,6 +370,9 @@ GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, cons
/**
* Return the current entry and advance the iterator
*
+ * The pointers returned by this function are valid until the iterator
+ * is freed.
+ *
* @param entry pointer to store the entry
* @param iter the iterator
* @return 0 or an error code. GIT_ITEROVER if the iteration has completed
@@ -450,13 +468,16 @@ GIT_EXTERN(int) git_config_delete_multivar(git_config *cfg, const char *name, co
*
* 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 stops iterating and returns `GIT_EUSER`.
+ * If the callback returns a non-zero value, the function stops iterating
+ * and returns that value to the caller.
+ *
+ * The pointers passed to the callback are only valid as long as the
+ * iteration is ongoing.
*
* @param cfg where to get the variables from
* @param callback the function to call on each variable
* @param payload the data to pass to the callback
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_config_foreach(
const git_config *cfg,
@@ -493,6 +514,9 @@ GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const gi
* regular expression that filters which config keys are passed to the
* callback.
*
+ * The pointers passed to the callback are only valid as long as the
+ * iteration is ongoing.
+ *
* @param cfg where to get the variables from
* @param regexp regular expression to match against config names
* @param callback the function to call on each variable
@@ -612,8 +636,8 @@ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
GIT_EXTERN(int) git_config_backend_foreach_match(
git_config_backend *backend,
const char *regexp,
- int (*fn)(const git_config_entry *, void *),
- void *data);
+ git_config_foreach_cb callback,
+ void *payload);
/** @} */
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 61d288380..675c209be 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -145,6 +145,13 @@ typedef enum {
*/
GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
+ /** When diff finds a file in the working directory with stat
+ * information different from the index, but the OID ends up being the
+ * same, write the correct stat information into the index. Note:
+ * without this flag, diff will always leave the index untouched.
+ */
+ GIT_DIFF_UPDATE_INDEX = (1u << 15),
+
/*
* Options controlling how output will be generated
*/
@@ -180,6 +187,10 @@ typedef enum {
/** Take extra time to find minimal diff */
GIT_DIFF_MINIMAL = (1 << 29),
+ /** Include the necessary deflate / delta information so that `git-apply`
+ * can apply given diff information to binary files.
+ */
+ GIT_DIFF_SHOW_BINARY = (1 << 30),
} git_diff_option_t;
/**
@@ -201,9 +212,9 @@ typedef struct git_diff git_diff;
* considered reserved for internal or future use.
*/
typedef enum {
- GIT_DIFF_FLAG_BINARY = (1u << 0), /** file(s) treated as binary data */
- GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /** file(s) treated as text data */
- GIT_DIFF_FLAG_VALID_OID = (1u << 2), /** `oid` value is known correct */
+ GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */
+ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */
+ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */
} git_diff_flag_t;
/**
@@ -217,15 +228,15 @@ typedef enum {
* DELETED pairs).
*/
typedef enum {
- GIT_DELTA_UNMODIFIED = 0, /** no changes */
- GIT_DELTA_ADDED = 1, /** entry does not exist in old version */
- GIT_DELTA_DELETED = 2, /** entry does not exist in new version */
- GIT_DELTA_MODIFIED = 3, /** entry content changed between old and new */
- GIT_DELTA_RENAMED = 4, /** entry was renamed between old and new */
- GIT_DELTA_COPIED = 5, /** entry was copied from another old entry */
- GIT_DELTA_IGNORED = 6, /** entry is ignored item in workdir */
- GIT_DELTA_UNTRACKED = 7, /** entry is untracked item in workdir */
- GIT_DELTA_TYPECHANGE = 8, /** type of entry changed between old and new */
+ GIT_DELTA_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;
/**
@@ -250,7 +261,7 @@ typedef enum {
* be restricted to one of the `git_filemode_t` values.
*/
typedef struct {
- git_oid oid;
+ git_oid id;
const char *path;
git_off_t size;
uint32_t flags;
@@ -361,7 +372,7 @@ typedef struct {
uint16_t context_lines; /**< defaults to 3 */
uint16_t interhunk_lines; /**< defaults to 0 */
- uint16_t oid_abbrev; /**< default 'core.abbrev' or 7 if unset */
+ uint16_t id_abbrev; /**< default 'core.abbrev' or 7 if unset */
git_off_t max_size; /**< defaults to 512MB */
const char *old_prefix; /**< defaults to "a" */
const char *new_prefix; /**< defaults to "b" */
@@ -377,6 +388,18 @@ typedef struct {
{GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_DEFAULT, {NULL,0}, NULL, NULL, 3}
/**
+ * Initializes a `git_diff_options` with default values. Equivalent to
+ * creating an instance with GIT_DIFF_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_init_options(
+ git_diff_options *opts,
+ unsigned int version);
+
+/**
* When iterating over a diff, callback that will be made per file.
*
* @param delta A pointer to the delta data for the file
@@ -393,12 +416,12 @@ typedef int (*git_diff_file_cb)(
*/
typedef struct git_diff_hunk git_diff_hunk;
struct git_diff_hunk {
- int old_start; /** Starting line number in old_file */
- int old_lines; /** Number of lines in old_file */
- int new_start; /** Starting line number in new_file */
- int new_lines; /** Number of lines in new_file */
- size_t header_len; /** Number of bytes in header text */
- char header[128]; /** Header text, NUL-byte terminated */
+ int old_start; /**< Starting line number in old_file */
+ int old_lines; /**< Number of lines in old_file */
+ int new_start; /**< Starting line number in new_file */
+ int new_lines; /**< Number of lines in new_file */
+ size_t header_len; /**< Number of bytes in header text */
+ char header[128]; /**< Header text, NUL-byte terminated */
};
/**
@@ -441,13 +464,13 @@ typedef enum {
*/
typedef struct git_diff_line git_diff_line;
struct git_diff_line {
- char origin; /** A git_diff_line_t value */
- int old_lineno; /** Line number in old file or -1 for added line */
- int new_lineno; /** Line number in new file or -1 for deleted line */
- int num_lines; /** Number of newline characters in content */
- size_t content_len; /** Number of bytes of data */
- git_off_t content_offset; /** Offset in the original file to the content */
- const char *content; /** Pointer to diff text, not NUL-byte terminated */
+ char origin; /**< A git_diff_line_t value */
+ int old_lineno; /**< Line number in old file or -1 for added line */
+ int new_lineno; /**< Line number in new file or -1 for deleted line */
+ int num_lines; /**< Number of newline characters in content */
+ size_t content_len; /**< Number of bytes of data */
+ git_off_t content_offset; /**< Offset in the original file to the content */
+ const char *content; /**< Pointer to diff text, not NUL-byte terminated */
};
/**
@@ -459,50 +482,83 @@ struct git_diff_line {
* of lines of file and hunk headers.
*/
typedef int (*git_diff_line_cb)(
- const git_diff_delta *delta, /** delta that contains this data */
- const git_diff_hunk *hunk, /** hunk containing this data */
- const git_diff_line *line, /** line data */
- void *payload); /** user reference data */
+ const git_diff_delta *delta, /**< delta that contains this data */
+ const git_diff_hunk *hunk, /**< hunk containing this data */
+ const git_diff_line *line, /**< line data */
+ void *payload); /**< user reference data */
/**
* Flags to control the behavior of diff rename/copy detection.
*/
typedef enum {
- /** look for renames? (`--find-renames`) */
+ /** Obey `diff.renames`. Overridden by any other GIT_DIFF_FIND_... flag. */
+ GIT_DIFF_FIND_BY_CONFIG = 0,
+
+ /** Look for renames? (`--find-renames`) */
GIT_DIFF_FIND_RENAMES = (1u << 0),
- /** consider old side of modified for renames? (`--break-rewrites=N`) */
+
+ /** Consider old side of MODIFIED for renames? (`--break-rewrites=N`) */
GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1u << 1),
- /** look for copies? (a la `--find-copies`) */
+ /** Look for copies? (a la `--find-copies`). */
GIT_DIFF_FIND_COPIES = (1u << 2),
- /** consider unmodified as copy sources? (`--find-copies-harder`) */
+
+ /** Consider UNMODIFIED as copy sources? (`--find-copies-harder`).
+ *
+ * For this to work correctly, use GIT_DIFF_INCLUDE_UNMODIFIED when
+ * the initial `git_diff` is being generated.
+ */
GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1u << 3),
- /** mark large rewrites for split (`--break-rewrites=/M`) */
+ /** Mark significant rewrites for split (`--break-rewrites=/M`) */
GIT_DIFF_FIND_REWRITES = (1u << 4),
- /** actually split large rewrites into delete/add pairs */
+ /** Actually split large rewrites into delete/add pairs */
GIT_DIFF_BREAK_REWRITES = (1u << 5),
- /** mark rewrites for split and break into delete/add pairs */
+ /** Mark rewrites for split and break into delete/add pairs */
GIT_DIFF_FIND_AND_BREAK_REWRITES =
(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES),
- /** find renames/copies for untracked items in working directory */
+ /** Find renames/copies for UNTRACKED items in working directory.
+ *
+ * For this to work correctly, use GIT_DIFF_INCLUDE_UNTRACKED when the
+ * initial `git_diff` is being generated (and obviously the diff must
+ * be against the working directory for this to make sense).
+ */
GIT_DIFF_FIND_FOR_UNTRACKED = (1u << 6),
- /** turn on all finding features */
+ /** Turn on all finding features. */
GIT_DIFF_FIND_ALL = (0x0ff),
- /** measure similarity ignoring leading whitespace (default) */
+ /** Measure similarity ignoring leading whitespace (default) */
GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
- /** measure similarity ignoring all whitespace */
+ /** Measure similarity ignoring all whitespace */
GIT_DIFF_FIND_IGNORE_WHITESPACE = (1u << 12),
- /** measure similarity including all data */
+ /** Measure similarity including all data */
GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1u << 13),
- /** measure similarity only by comparing SHAs (fast and cheap) */
+ /** Measure similarity only by comparing SHAs (fast and cheap) */
GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1u << 14),
- /** do not break rewrites unless they contribute to a rename */
+ /** Do not break rewrites unless they contribute to a rename.
+ *
+ * Normally, GIT_DIFF_FIND_AND_BREAK_REWRITES will measure the self-
+ * similarity of modified files and split the ones that have changed a
+ * lot into a DELETE / ADD pair. Then the sides of that pair will be
+ * considered candidates for rename and copy detection.
+ *
+ * If you add this flag in and the split pair is *not* used for an
+ * actual rename or copy, then the modified record will be restored to
+ * a regular MODIFIED record instead of being split.
+ */
GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1u << 15),
+
+ /** Remove any UNMODIFIED deltas after find_similar is done.
+ *
+ * Using GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED to emulate the
+ * --find-copies-harder behavior requires building a diff with the
+ * GIT_DIFF_INCLUDE_UNMODIFIED flag. If you do not want UNMODIFIED
+ * records in the final result, pass this flag to have them removed.
+ */
+ GIT_DIFF_FIND_REMOVE_UNMODIFIED = (1u << 16),
} git_diff_find_t;
/**
@@ -543,7 +599,11 @@ typedef struct {
typedef struct {
unsigned int version;
- /** Combination of git_diff_find_t values (default FIND_RENAMES) */
+ /**
+ * Combination of git_diff_find_t values (default GIT_DIFF_FIND_BY_CONFIG).
+ * NOTE: if you don't explicitly set this, `diff.renames` could be set
+ * to false, resulting in `git_diff_find_similar` doing nothing.
+ */
uint32_t flags;
/** Similarity to consider a file renamed (default 50) */
@@ -567,6 +627,18 @@ typedef struct {
#define GIT_DIFF_FIND_OPTIONS_VERSION 1
#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
+/**
+ * Initializes a `git_diff_find_options` with default values. Equivalent to
+ * creating an instance with GIT_DIFF_FIND_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_find_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_FIND_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_find_init_options(
+ git_diff_find_options *opts,
+ unsigned int version);
+
/** @name Diff Generator Functions
*
* These are the functions you would use to create (or destroy) a
@@ -662,24 +734,17 @@ GIT_EXTERN(int) git_diff_index_to_workdir(
* 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 is not the same as `git diff <treeish>` or `git diff-index
+ * <treeish>`. Those commands use information from the index, whereas this
+ * function strictly returns the differences between the tree and the files
+ * in the working directory, regardless of the state of the index. Use
+ * `git_diff_tree_to_workdir_with_index` to emulate those commands.
*
- * 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.
- *
- * To emulate `git diff <tree>`, use `git_diff_tree_to_workdir_with_index`
- * (or `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` that
- * matches the git output.
- *
- * 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.
+ * To see difference between this and `git_diff_tree_to_workdir_with_index`,
+ * consider the example of a staged file deletion where the file has then
+ * been put back into the working dir and further modified. The
+ * tree-to-workdir diff for that file is 'modified', but `git diff` would
+ * show status 'deleted' since there is a staged delete.
*
* @param diff A pointer to a git_diff pointer that will be allocated.
* @param repo The repository containing the tree.
@@ -744,23 +809,6 @@ GIT_EXTERN(int) git_diff_find_similar(
git_diff *diff,
const git_diff_find_options *options);
-/**
- * Initialize diff options structure
- *
- * In most cases, you can probably just use `GIT_DIFF_OPTIONS_INIT` to
- * initialize the diff options structure, but in some cases that is not
- * going to work. You can call this function instead. Note that you
- * must pass both a pointer to the structure to be initialized and the
- * `GIT_DIFF_OPTIONS_VERSION` value from the header you compiled with.
- *
- * @param options Pointer to git_diff_options memory to be initialized
- * @param version Should be `GIT_DIFF_OPTIONS_VERSION`
- * @return 0 on success, negative on failure (such as unsupported version)
- */
-GIT_EXTERN(int) git_diff_options_init(
- git_diff_options *options,
- unsigned int version);
-
/**@}*/
@@ -833,7 +881,7 @@ GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
* files whose only changed is a file mode change.
*
* Returning a non-zero value from any of the callbacks will terminate
- * the iteration and cause this return `GIT_EUSER`.
+ * the iteration and return the value to the user.
*
* @param diff A git_diff generated by one of the above functions.
* @param file_cb Callback function to make per file in the diff.
@@ -844,7 +892,7 @@ GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
* 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
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_diff_foreach(
git_diff *diff,
@@ -881,13 +929,13 @@ typedef enum {
* Iterate over a diff generating formatted text output.
*
* Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
+ * iteration and return the non-zero value to the caller.
*
* @param diff A git_diff generated by one of the above functions.
* @param format A git_diff_format_t value to pick the text format.
* @param print_cb Callback to make per line of diff text.
* @param payload Reference pointer that will be passed to your callback.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_diff_print(
git_diff *diff,
@@ -927,7 +975,7 @@ GIT_EXTERN(int) git_diff_print(
* @param hunk_cb Callback for each hunk in diff; can be NULL
* @param line_cb Callback for each line in diff; can be NULL
* @param payload Payload passed to each callback function
- * @return 0 on success, GIT_EUSER on non-zero callback return, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_diff_blobs(
const git_blob *old_blob,
@@ -962,7 +1010,7 @@ GIT_EXTERN(int) git_diff_blobs(
* @param hunk_cb Callback for each hunk in diff; can be NULL
* @param line_cb Callback for each line in diff; can be NULL
* @param payload Payload passed to each callback function
- * @return 0 on success, GIT_EUSER on non-zero callback return, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_diff_blob_to_buffer(
const git_blob *old_blob,
@@ -976,6 +1024,214 @@ GIT_EXTERN(int) git_diff_blob_to_buffer(
git_diff_line_cb line_cb,
void *payload);
+/**
+ * Directly run a diff between two buffers.
+ *
+ * Even more than with `git_diff_blobs`, comparing two buffer lacks
+ * context, so the `git_diff_file` parameters to the callbacks will be
+ * faked a la the rules for `git_diff_blobs()`.
+ *
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_buffers(
+ const void *old_buffer,
+ size_t old_len,
+ const char *old_as_path,
+ const void *new_buffer,
+ size_t new_len,
+ const char *new_as_path,
+ const git_diff_options *options,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
+
+/**
+ * This is an opaque structure which is allocated by `git_diff_get_stats`.
+ * You are responsible for releasing the object memory when done, using the
+ * `git_diff_stats_free()` function.
+ */
+typedef struct git_diff_stats git_diff_stats;
+
+/**
+ * Formatting options for diff stats
+ */
+typedef enum {
+ /** No stats*/
+ GIT_DIFF_STATS_NONE = 0,
+
+ /** Full statistics, equivalent of `--stat` */
+ GIT_DIFF_STATS_FULL = (1u << 0),
+
+ /** Short statistics, equivalent of `--shortstat` */
+ GIT_DIFF_STATS_SHORT = (1u << 1),
+
+ /** Number statistics, equivalent of `--numstat` */
+ GIT_DIFF_STATS_NUMBER = (1u << 2),
+
+ /** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */
+ GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3),
+} git_diff_stats_format_t;
+
+/**
+ * Accumlate diff statistics for all patches.
+ *
+ * @param out Structure containg the diff statistics.
+ * @param diff A git_diff generated by one of the above functions.
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_get_stats(
+ git_diff_stats **out,
+ git_diff *diff);
+
+/**
+ * Get the total number of files changed in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of files changed in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_files_changed(
+ const git_diff_stats *stats);
+
+/**
+ * Get the total number of insertions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of insertions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_insertions(
+ const git_diff_stats *stats);
+
+/**
+ * Get the total number of deletions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of deletions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_deletions(
+ const git_diff_stats *stats);
+
+/**
+ * Print diff statistics to a `git_buf`.
+ *
+ * @param out buffer to store the formatted diff statistics in.
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @param format Formatting option.
+ * @param width Target width for output (only affects GIT_DIFF_STATS_FULL)
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_stats_to_buf(
+ git_buf *out,
+ const git_diff_stats *stats,
+ git_diff_stats_format_t format,
+ size_t width);
+
+/**
+ * Deallocate a `git_diff_stats`.
+ *
+ * @param stats The previously created statistics object;
+ * cannot be used after free.
+ */
+GIT_EXTERN(void) git_diff_stats_free(git_diff_stats *stats);
+
+/**
+ * Formatting options for diff e-mail generation
+ */
+typedef enum {
+ /** Normal patch, the default */
+ GIT_DIFF_FORMAT_EMAIL_NONE = 0,
+
+ /** Don't insert "[PATCH]" in the subject header*/
+ GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0),
+
+} git_diff_format_email_flags_t;
+
+/**
+ * Options for controlling the formatting of the generated e-mail.
+ */
+typedef struct {
+ unsigned int version;
+
+ git_diff_format_email_flags_t flags;
+
+ /** This patch number */
+ size_t patch_no;
+
+ /** Total number of patches in this series */
+ size_t total_patches;
+
+ /** id to use for the commit */
+ const git_oid *id;
+
+ /** Summary of the change */
+ const char *summary;
+
+ /** Author of the change */
+ const git_signature *author;
+} git_diff_format_email_options;
+
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL}
+
+/**
+ * Create an e-mail ready patch from a diff.
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param diff containing the commit
+ * @param opts structure with options to influence content and formatting.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_diff_format_email(
+ git_buf *out,
+ git_diff *diff,
+ const git_diff_format_email_options *opts);
+
+/**
+ * Create an e-mail ready patch for a commit.
+ *
+ * Does not support creating patches for merge commits (yet).
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param repo containing the commit
+ * @param commit pointer to up commit
+ * @param patch_no patch number of the commit
+ * @param total_patches total number of patches in the patch set
+ * @param flags determines the formatting of the e-mail
+ * @param diff_opts structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_diff_commit_as_email(
+ git_buf *out,
+ git_repository *repo,
+ git_commit *commit,
+ size_t patch_no,
+ size_t total_patches,
+ git_diff_format_email_flags_t flags,
+ const git_diff_options *diff_opts);
+
+/**
+ * Initializes a `git_diff_format_email_options` with default values.
+ *
+ * Equivalent to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_format_email_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_format_email_init_options(
+ git_diff_format_email_options *opts,
+ unsigned int version);
GIT_END_DECL
diff --git a/include/git2/errors.h b/include/git2/errors.h
index be7a31d8e..c914653fc 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -8,7 +8,6 @@
#define INCLUDE_git_errors_h__
#include "common.h"
-#include "buffer.h"
/**
* @file git2/errors.h
@@ -20,25 +19,39 @@ GIT_BEGIN_DECL
/** Generic return codes */
typedef enum {
- GIT_OK = 0,
- GIT_ERROR = -1,
- GIT_ENOTFOUND = -3,
- GIT_EEXISTS = -4,
- GIT_EAMBIGUOUS = -5,
- GIT_EBUFS = -6,
- GIT_EUSER = -7,
- GIT_EBAREREPO = -8,
- GIT_EUNBORNBRANCH = -9,
- GIT_EUNMERGED = -10,
- GIT_ENONFASTFORWARD = -11,
- GIT_EINVALIDSPEC = -12,
- GIT_EMERGECONFLICT = -13,
- GIT_ELOCKED = -14,
+ GIT_OK = 0, /**< No error */
- GIT_PASSTHROUGH = -30,
- GIT_ITEROVER = -31,
+ GIT_ERROR = -1, /**< Generic error */
+ GIT_ENOTFOUND = -3, /**< Requested object could not be found */
+ GIT_EEXISTS = -4, /**< Object exists preventing operation */
+ GIT_EAMBIGUOUS = -5, /**< More than one object matches */
+ GIT_EBUFS = -6, /**< Output buffer too short to hold data */
+
+ /* GIT_EUSER is a special error that is never generated by libgit2
+ * code. You can return it from a callback (e.g to stop an iteration)
+ * to know that it was generated by the callback and not by libgit2.
+ */
+ GIT_EUSER = -7,
+
+ GIT_EBAREREPO = -8, /**< Operation not allowed on bare repository */
+ GIT_EUNBORNBRANCH = -9, /**< HEAD refers to branch with no commits */
+ GIT_EUNMERGED = -10, /**< Merge in progress prevented operation */
+ GIT_ENONFASTFORWARD = -11, /**< Reference was not fast-forwardable */
+ GIT_EINVALIDSPEC = -12, /**< Name/ref spec was not in a valid format */
+ GIT_EMERGECONFLICT = -13, /**< Merge conflicts prevented operation */
+ GIT_ELOCKED = -14, /**< Lock file prevented operation */
+ GIT_EMODIFIED = -15, /**< Reference value does not match expected */
+
+ GIT_PASSTHROUGH = -30, /**< Internal only */
+ GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
} git_error_code;
+/**
+ * Structure to store extra details of the last error that occurred.
+ *
+ * This is kept on a per-thread basis if GIT_THREADS was defined when the
+ * library was build, otherwise one is kept globally for the library
+ */
typedef struct {
char *message;
int klass;
@@ -71,6 +84,9 @@ typedef enum {
GITERR_MERGE,
GITERR_SSH,
GITERR_FILTER,
+ GITERR_REVERT,
+ GITERR_CALLBACK,
+ GITERR_CHERRYPICK,
} git_error_t;
/**
@@ -90,7 +106,7 @@ GIT_EXTERN(void) giterr_clear(void);
* Get the last error data and clear it.
*
* This copies the last error into the given `git_error` struct
- * and returns 0 if the copy was successful, leaving the error
+ * and returns 0 if the copy was successful, leaving the error
* cleared as if `giterr_clear` had been called.
*
* If there was no existing error in the library, -1 will be returned
diff --git a/include/git2/filter.h b/include/git2/filter.h
index f96b6766b..e57a67e73 100644
--- a/include/git2/filter.h
+++ b/include/git2/filter.h
@@ -35,6 +35,11 @@ typedef enum {
GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB,
} git_filter_mode_t;
+typedef enum {
+ GIT_FILTER_OPT_DEFAULT = 0u,
+ GIT_FILTER_OPT_ALLOW_UNSAFE = (1u << 0),
+} git_filter_opt_t;
+
/**
* A filter that can transform file data
*
@@ -75,6 +80,7 @@ typedef struct git_filter_list git_filter_list;
* @param blob The blob to which the filter will be applied (if known)
* @param path Relative path of the file to be filtered
* @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @param options Combination of `git_filter_opt_t` flags
* @return 0 on success (which could still return NULL if no filters are
* needed for the requested file), <0 on error
*/
@@ -83,7 +89,8 @@ GIT_EXTERN(int) git_filter_list_load(
git_repository *repo,
git_blob *blob, /* can be NULL */
const char *path,
- git_filter_mode_t mode);
+ git_filter_mode_t mode,
+ uint32_t options);
/**
* Apply filter list to a data buffer.
diff --git a/include/git2/graph.h b/include/git2/graph.h
index a2710219e..c997d8ca9 100644
--- a/include/git2/graph.h
+++ b/include/git2/graph.h
@@ -36,6 +36,20 @@ GIT_BEGIN_DECL
*/
GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
+
+/**
+ * Determine if a commit is the descendant of another commit.
+ *
+ * @param commit a previously loaded commit.
+ * @param ancestor a potential ancestor commit.
+ * @return 1 if the given commit is a descendant of the potential ancestor,
+ * 0 if not, error code otherwise.
+ */
+GIT_EXTERN(int) git_graph_descendant_of(
+ git_repository *repo,
+ const git_oid *commit,
+ const git_oid *ancestor);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/index.h b/include/git2/index.h
index a60db370a..0b4476b4e 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -56,12 +56,12 @@ typedef struct git_index_entry {
unsigned int gid;
git_off_t file_size;
- git_oid oid;
+ git_oid id;
unsigned short flags;
unsigned short flags_extended;
- char *path;
+ const char *path;
} git_index_entry;
/**
@@ -73,11 +73,19 @@ typedef struct git_index_entry {
*/
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
#define GIT_IDXENTRY_STAGEMASK (0x3000)
-#define GIT_IDXENTRY_EXTENDED (0x4000)
-#define GIT_IDXENTRY_VALID (0x8000)
#define GIT_IDXENTRY_STAGESHIFT 12
-#define GIT_IDXENTRY_STAGE(E) (((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
+typedef enum {
+ GIT_IDXENTRY_EXTENDED = (0x4000),
+ GIT_IDXENTRY_VALID = (0x8000),
+} git_indxentry_flag_t;
+
+#define GIT_IDXENTRY_STAGE(E) \
+ (((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
+
+#define GIT_IDXENTRY_STAGE_SET(E,S) do { \
+ (E)->flags = ((E)->flags & ~GIT_IDXENTRY_STAGEMASK) | \
+ (((S) & 0x03) << GIT_IDXENTRY_STAGESHIFT); } while (0)
/**
* Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`
@@ -87,43 +95,43 @@ typedef struct git_index_entry {
* in-memory only and used by libgit2. Only the flags in
* `GIT_IDXENTRY_EXTENDED_FLAGS` will get saved on-disk.
*
- * These bitmasks match the three fields in the `git_index_entry`
- * `flags_extended` value that belong on disk. You can use them to
- * interpret the data in the `flags_extended`.
+ * Thee first three bitmasks match the three fields in the
+ * `git_index_entry` `flags_extended` value that belong on disk. You
+ * can use them to interpret the data in the `flags_extended`.
+ *
+ * The rest of the bitmasks match the other fields in the `git_index_entry`
+ * `flags_extended` value that are only used in-memory by libgit2.
+ * You can use them to interpret the data in the `flags_extended`.
+ *
*/
-#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
-#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
-/* GIT_IDXENTRY_EXTENDED2 is reserved for future extension */
-#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
+typedef enum {
-#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
+ GIT_IDXENTRY_INTENT_TO_ADD = (1 << 13),
+ GIT_IDXENTRY_SKIP_WORKTREE = (1 << 14),
+ /** Reserved for future extension */
+ GIT_IDXENTRY_EXTENDED2 = (1 << 15),
-/**
- * Bitmasks for in-memory only fields of `git_index_entry`'s `flags_extended`
- *
- * These bitmasks match the other fields in the `git_index_entry`
- * `flags_extended` value that are only used in-memory by libgit2. You
- * can use them to interpret the data in the `flags_extended`.
- */
-#define GIT_IDXENTRY_UPDATE (1 << 0)
-#define GIT_IDXENTRY_REMOVE (1 << 1)
-#define GIT_IDXENTRY_UPTODATE (1 << 2)
-#define GIT_IDXENTRY_ADDED (1 << 3)
+ GIT_IDXENTRY_EXTENDED_FLAGS = (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE),
+ GIT_IDXENTRY_UPDATE = (1 << 0),
+ GIT_IDXENTRY_REMOVE = (1 << 1),
+ GIT_IDXENTRY_UPTODATE = (1 << 2),
+ 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)
+ GIT_IDXENTRY_HASHED = (1 << 4),
+ GIT_IDXENTRY_UNHASHED = (1 << 5),
+ GIT_IDXENTRY_WT_REMOVE = (1 << 6), /**< remove in work directory */
+ GIT_IDXENTRY_CONFLICTED = (1 << 7),
-#define GIT_IDXENTRY_UNPACKED (1 << 8)
-#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
+ GIT_IDXENTRY_UNPACKED = (1 << 8),
+ GIT_IDXENTRY_NEW_SKIP_WORKTREE = (1 << 9),
+} git_idxentry_extended_flag_t;
/** Capabilities of system that affect index actions. */
typedef enum {
- GIT_INDEXCAP_IGNORE_CASE = 1u,
- GIT_INDEXCAP_NO_FILEMODE = 2u,
- GIT_INDEXCAP_NO_SYMLINKS = 4u,
- GIT_INDEXCAP_FROM_OWNER = ~0u
+ GIT_INDEXCAP_IGNORE_CASE = 1,
+ GIT_INDEXCAP_NO_FILEMODE = 2,
+ GIT_INDEXCAP_NO_SYMLINKS = 4,
+ GIT_INDEXCAP_FROM_OWNER = -1,
} git_indexcap_t;
/** Callback for APIs that add/remove/update files matching pathspec */
@@ -158,8 +166,8 @@ typedef enum {
* to back it.
*
* Since there is no ODB or working directory behind this index,
- * any Index methods which rely on these (e.g. index_add) will
- * fail with the GIT_EBAREINDEX error code.
+ * any Index methods which rely on these (e.g. index_add_bypath)
+ * will fail with the GIT_ERROR error code.
*
* If you need to access the index of an actual repository,
* use the `git_repository_index` wrapper.
@@ -206,7 +214,7 @@ GIT_EXTERN(git_repository *) git_index_owner(const git_index *index);
* @param index An existing index object
* @return A combination of GIT_INDEXCAP values
*/
-GIT_EXTERN(unsigned int) git_index_caps(const git_index *index);
+GIT_EXTERN(int) git_index_caps(const git_index *index);
/**
* Set index capabilities flags.
@@ -219,7 +227,7 @@ GIT_EXTERN(unsigned int) git_index_caps(const git_index *index);
* @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);
+GIT_EXTERN(int) git_index_set_caps(git_index *index, int caps);
/**
* Update the contents of an existing index object in memory by reading
@@ -255,7 +263,7 @@ GIT_EXTERN(int) git_index_write(git_index *index);
* @param index an existing index object
* @return path to index file or NULL for in-memory index
*/
-GIT_EXTERN(const char *) git_index_path(git_index *index);
+GIT_EXTERN(const char *) git_index_path(const git_index *index);
/**
* Read a tree into the index file with stats
@@ -327,12 +335,14 @@ GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
/**
* Clear the contents (all the entries) of an index object.
- * This clears the index object in memory; changes must be manually
- * written to disk for them to take effect.
+ *
+ * This clears the index object in memory; changes must be explicitly
+ * written to disk for them to take effect persistently.
*
* @param index an existing index object
+ * @return 0 on success, error code < 0 on failure
*/
-GIT_EXTERN(void) git_index_clear(git_index *index);
+GIT_EXTERN(int) git_index_clear(git_index *index);
/**
* Get a pointer to one of the entries in the index
@@ -405,10 +415,10 @@ GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_en
*
* This entry is calculated from the entry's flag attribute like this:
*
- * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
+ * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
*
* @param entry The entry
- * @returns the stage number
+ * @return the stage number
*/
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
@@ -493,7 +503,7 @@ GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
* item in the working directory immediately *before* it is added to /
* updated in the index. Returning zero will add the item to the index,
* greater than zero will skip the item, and less than zero will abort the
- * scan and cause GIT_EUSER to be returned.
+ * scan and return that value to the caller.
*
* @param index an existing index object
* @param pathspec array of path patterns
@@ -502,7 +512,7 @@ GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
* gets index of matching pathspec entry); can be NULL;
* return 0 to add, >0 to skip, <0 to abort scan.
* @param payload payload passed through to callback function
- * @return 0 or an error code
+ * @return 0 on success, negative callback return value, or error code
*/
GIT_EXTERN(int) git_index_add_all(
git_index *index,
@@ -524,7 +534,7 @@ GIT_EXTERN(int) git_index_add_all(
* gets index of matching pathspec entry); can be NULL;
* return 0 to add, >0 to skip, <0 to abort scan.
* @param payload payload passed through to callback function
- * @return 0 or an error code
+ * @return 0 on success, negative callback return value, or error code
*/
GIT_EXTERN(int) git_index_remove_all(
git_index *index,
@@ -553,7 +563,7 @@ GIT_EXTERN(int) git_index_remove_all(
* gets index of matching pathspec entry); can be NULL;
* return 0 to add, >0 to skip, <0 to abort scan.
* @param payload payload passed through to callback function
- * @return 0 or an error code
+ * @return 0 on success, negative callback return value, or error code
*/
GIT_EXTERN(int) git_index_update_all(
git_index *index,
@@ -568,8 +578,7 @@ GIT_EXTERN(int) git_index_update_all(
* @param at_pos the address to which the position of the index entry is written (optional)
* @param index an existing index object
* @param path path to search
- * @return a zero-based position in the index if found;
- * GIT_ENOTFOUND otherwise
+ * @return a zero-based position in the index if found; GIT_ENOTFOUND otherwise
*/
GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
@@ -613,6 +622,7 @@ GIT_EXTERN(int) git_index_conflict_add(
* @param their_out Pointer to store the their entry
* @param index an existing index object
* @param path path to search
+ * @return 0 or an error code
*/
GIT_EXTERN(int) git_index_conflict_get(
const git_index_entry **ancestor_out,
@@ -625,16 +635,18 @@ GIT_EXTERN(int) git_index_conflict_get(
* Removes the index entries that represent a conflict of a single file.
*
* @param index an existing index object
- * @param path to search
+ * @param path path to remove conflicts for
+ * @return 0 or an error code
*/
GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path);
/**
- * Remove all conflicts in the index (entries with a stage greater than 0.)
+ * Remove all conflicts in the index (entries with a stage greater than 0).
*
* @param index an existing index object
+ * @return 0 or an error code
*/
-GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index);
+GIT_EXTERN(int) git_index_conflict_cleanup(git_index *index);
/**
* Determine if the index contains entries representing file conflicts.
@@ -644,9 +656,12 @@ GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index);
GIT_EXTERN(int) git_index_has_conflicts(const git_index *index);
/**
- * Create an iterator for the conflicts in the index. You may not modify the
- * index while iterating, the results are undefined.
+ * Create an iterator for the conflicts in the index.
+ *
+ * The index must not be modified while iterating; the results are undefined.
*
+ * @param iterator_out The newly created conflict iterator
+ * @param index The index to scan
* @return 0 or an error code
*/
GIT_EXTERN(int) git_index_conflict_iterator_new(
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index e4c03ad06..d2d315e47 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -32,7 +32,7 @@ GIT_EXTERN(int) git_indexer_new(
const char *path,
unsigned int mode,
git_odb *odb,
- git_transfer_progress_callback progress_cb,
+ git_transfer_progress_cb progress_cb,
void *progress_cb_payload);
/**
diff --git a/include/git2/merge.h b/include/git2/merge.h
index 3354fbeab..9eb14ccb1 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -23,70 +23,287 @@
GIT_BEGIN_DECL
/**
+ * The file inputs to `git_merge_file`. Callers should populate the
+ * `git_merge_file_input` structure with descriptions of the files in
+ * each side of the conflict for use in producing the merge file.
+ */
+typedef struct {
+ unsigned int version;
+
+ /** Pointer to the contents of the file. */
+ const char *ptr;
+
+ /** Size of the contents pointed to in `ptr`. */
+ size_t size;
+
+ /** File name of the conflicted file, or `NULL` to not merge the path. */
+ const char *path;
+
+ /** File mode of the conflicted file, or `0` to not merge the mode. */
+ unsigned int mode;
+} git_merge_file_input;
+
+#define GIT_MERGE_FILE_INPUT_VERSION 1
+#define GIT_MERGE_FILE_INPUT_INIT {GIT_MERGE_FILE_INPUT_VERSION}
+
+/**
+ * Initializes a `git_merge_file_input` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_FILE_INPUT_INIT.
+ *
+ * @param opts the `git_merge_file_input` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_MERGE_FILE_INPUT_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_init_input(
+ git_merge_file_input *opts,
+ unsigned int version);
+
+/**
* Flags for `git_merge_tree` options. A combination of these flags can be
- * passed in via the `flags` value in the `git_merge_tree_opts`.
+ * passed in via the `flags` value in the `git_merge_options`.
*/
typedef enum {
- /** Detect renames */
+ /**
+ * Detect renames that occur between the common ancestor and the "ours"
+ * side or the common ancestor and the "theirs" side. This will enable
+ * the ability to merge between a modified and renamed file.
+ */
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
} git_merge_tree_flag_t;
/**
- * Automerge options for `git_merge_trees_opts`.
+ * Merge file favor options for `git_merge_options` instruct the file-level
+ * merging functionality how to deal with conflicting regions of the files.
*/
typedef enum {
- GIT_MERGE_AUTOMERGE_NORMAL = 0,
- GIT_MERGE_AUTOMERGE_NONE = 1,
- GIT_MERGE_AUTOMERGE_FAVOR_OURS = 2,
- GIT_MERGE_AUTOMERGE_FAVOR_THEIRS = 3,
-} git_merge_automerge_flags;
+ /**
+ * When a region of a file is changed in both branches, a conflict
+ * will be recorded in the index so that `git_checkout` can produce
+ * a merge file with conflict markers in the working directory.
+ * This is the default.
+ */
+ GIT_MERGE_FILE_FAVOR_NORMAL = 0,
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain the "ours" side of any conflicting
+ * region. The index will not record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_OURS = 1,
+
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain the "theirs" side of any conflicting
+ * region. The index will not record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_THEIRS = 2,
+
+ /**
+ * When a region of a file is changed in both branches, the file
+ * created in the index will contain each unique line from each side,
+ * which has the result of combining both files. The index will not
+ * record a conflict.
+ */
+ GIT_MERGE_FILE_FAVOR_UNION = 3,
+} git_merge_file_favor_t;
+
+typedef enum {
+ /* Defaults */
+ GIT_MERGE_FILE_DEFAULT = 0,
+
+ /* Create standard conflicted merge files */
+ GIT_MERGE_FILE_STYLE_MERGE = (1 << 0),
+
+ /* Create diff3-style files */
+ GIT_MERGE_FILE_STYLE_DIFF3 = (1 << 1),
+
+ /* Condense non-alphanumeric regions for simplified diff file */
+ GIT_MERGE_FILE_SIMPLIFY_ALNUM = (1 << 2),
+} git_merge_file_flags_t;
+
+typedef struct {
+ unsigned int version;
+
+ /**
+ * Label for the ancestor file side of the conflict which will be prepended
+ * to labels in diff3-format merge files.
+ */
+ const char *ancestor_label;
+
+ /**
+ * Label for our file side of the conflict which will be prepended
+ * to labels in merge files.
+ */
+ const char *our_label;
+
+ /**
+ * Label for their file side of the conflict which will be prepended
+ * to labels in merge files.
+ */
+ const char *their_label;
+
+ /** The file to favor in region conflicts. */
+ git_merge_file_favor_t favor;
+
+ /** Merge file flags. */
+ git_merge_file_flags_t flags;
+} git_merge_file_options;
+
+#define GIT_MERGE_FILE_OPTIONS_VERSION 1
+#define GIT_MERGE_FILE_OPTIONS_INIT {GIT_MERGE_FILE_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_merge_file_options` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_FILE_OPTIONS_INIT.
+ *
+ * @param opts the `git_merge_file_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_MERGE_FILE_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_init_options(
+ git_merge_file_options *opts,
+ unsigned int version);
+
+typedef struct {
+ /**
+ * True if the output was automerged, false if the output contains
+ * conflict markers.
+ */
+ unsigned int automergeable;
+
+ /**
+ * The path that the resultant merge file should use, or NULL if a
+ * filename conflict would occur.
+ */
+ const char *path;
+
+ /** The mode that the resultant merge file should use. */
+ unsigned int mode;
+
+ /** The contents of the merge. */
+ const char *ptr;
+
+ /** The length of the merge contents. */
+ size_t len;
+} git_merge_file_result;
typedef struct {
unsigned int version;
git_merge_tree_flag_t flags;
- /** Similarity to consider a file renamed (default 50) */
+ /**
+ * Similarity to consider a file renamed (default 50). If
+ * `GIT_MERGE_TREE_FIND_RENAMES` is enabled, added files will be compared
+ * with deleted files to determine their similarity. Files that are
+ * more similar than the rename threshold (percentage-wise) will be
+ * treated as a rename.
+ */
unsigned int rename_threshold;
- /** Maximum similarity sources to examine (overrides the
- * `merge.renameLimit` config) (default 200)
+ /**
+ * Maximum similarity sources to examine for renames (default 200).
+ * If the number of rename candidates (add / delete pairs) is greater
+ * than this value, inexact rename detection is aborted.
+ *
+ * This setting overrides the `merge.renameLimit` configuration value.
*/
unsigned int target_limit;
/** Pluggable similarity metric; pass NULL to use internal metric */
git_diff_similarity_metric *metric;
- /** Flags for automerging content. */
- git_merge_automerge_flags automerge_flags;
-} git_merge_tree_opts;
-
-#define GIT_MERGE_TREE_OPTS_VERSION 1
-#define GIT_MERGE_TREE_OPTS_INIT {GIT_MERGE_TREE_OPTS_VERSION}
+ /** Flags for handling conflicting content. */
+ git_merge_file_favor_t file_favor;
+} git_merge_options;
+#define GIT_MERGE_OPTIONS_VERSION 1
+#define GIT_MERGE_OPTIONS_INIT {GIT_MERGE_OPTIONS_VERSION}
/**
- * Option flags for `git_merge`.
+ * Initializes a `git_merge_options` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_OPTIONS_INIT.
*
- * GIT_MERGE_NO_FASTFORWARD - Do not fast-forward.
+ * @param opts the `git_merge_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_MERGE_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_init_options(
+ git_merge_options *opts,
+ unsigned int version);
+
+/**
+ * The results of `git_merge_analysis` indicate the merge opportunities.
*/
typedef enum {
- GIT_MERGE_NO_FASTFORWARD = 1,
- GIT_MERGE_FASTFORWARD_ONLY = 2,
-} git_merge_flags_t;
+ /** No merge is possible. (Unused.) */
+ GIT_MERGE_ANALYSIS_NONE = 0,
-typedef struct {
- unsigned int version;
+ /**
+ * A "normal" merge; both HEAD and the given merge input have diverged
+ * from their common ancestor. The divergent commits must be merged.
+ */
+ GIT_MERGE_ANALYSIS_NORMAL = (1 << 0),
+
+ /**
+ * All given merge inputs are reachable from HEAD, meaning the
+ * repository is up-to-date and no merge needs to be performed.
+ */
+ GIT_MERGE_ANALYSIS_UP_TO_DATE = (1 << 1),
+
+ /**
+ * The given merge input is a fast-forward from HEAD and no merge
+ * needs to be performed. Instead, the client can check out the
+ * given merge input.
+ */
+ GIT_MERGE_ANALYSIS_FASTFORWARD = (1 << 2),
+
+ /**
+ * The HEAD of the current repository is "unborn" and does not point to
+ * a valid commit. No merge can be performed, but the caller may wish
+ * to simply set HEAD to the target commit(s).
+ */
+ GIT_MERGE_ANALYSIS_UNBORN = (1 << 3),
+} git_merge_analysis_t;
- git_merge_flags_t merge_flags;
- git_merge_tree_opts merge_tree_opts;
+typedef enum {
+ /*
+ * No configuration was found that suggests a preferred behavior for
+ * merge.
+ */
+ GIT_MERGE_PREFERENCE_NONE = 0,
- git_checkout_opts checkout_opts;
-} git_merge_opts;
+ /**
+ * There is a `merge.ff=false` configuration setting, suggesting that
+ * the user does not want to allow a fast-forward merge.
+ */
+ GIT_MERGE_PREFERENCE_NO_FASTFORWARD = (1 << 0),
-#define GIT_MERGE_OPTS_VERSION 1
-#define GIT_MERGE_OPTS_INIT {GIT_MERGE_OPTS_VERSION, 0, GIT_MERGE_TREE_OPTS_INIT, GIT_CHECKOUT_OPTS_INIT}
+ /**
+ * There is a `merge.ff=only` configuration setting, suggesting that
+ * the user only wants fast-forward merges.
+ */
+ GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1),
+} git_merge_preference_t;
+/**
+ * Analyzes the given branch(es) and determines the opportunities for
+ * merging them into the HEAD of the repository.
+ *
+ * @param analysis_out analysis enumeration that the result is written into
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_analysis(
+ git_merge_analysis_t *analysis_out,
+ git_merge_preference_t *preference_out,
+ git_repository *repo,
+ const git_merge_head **their_heads,
+ size_t their_heads_len);
/**
* Find a merge base between two commits
@@ -95,7 +312,7 @@ typedef struct {
* @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.
+ * @return 0 on success, GIT_ENOTFOUND if not found or error code
*/
GIT_EXTERN(int) git_merge_base(
git_oid *out,
@@ -119,27 +336,44 @@ GIT_EXTERN(int) git_merge_base_many(
const git_oid input_array[]);
/**
- * Creates a `git_merge_head` from the given reference
+ * Find a merge base in preparation for an octopus merge
+ *
+ * @param out the OID of a merge base considering all the commits
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_octopus(
+ git_oid *out,
+ git_repository *repo,
+ size_t length,
+ const git_oid input_array[]);
+
+/**
+ * Creates a `git_merge_head` from the given reference. The resulting
+ * git_merge_head must be freed with `git_merge_head_free`.
*
* @param out pointer to store the git_merge_head result in
* @param repo repository that contains the given reference
* @param ref reference to use as a merge input
- * @return zero on success, -1 on failure.
+ * @return 0 on success or error code
*/
GIT_EXTERN(int) git_merge_head_from_ref(
git_merge_head **out,
git_repository *repo,
- git_reference *ref);
+ const git_reference *ref);
/**
- * Creates a `git_merge_head` from the given fetch head data
+ * Creates a `git_merge_head` from the given fetch head data. The resulting
+ * git_merge_head must be freed with `git_merge_head_free`.
*
* @param out pointer to store the git_merge_head result in
* @param repo repository that contains the given commit
* @param branch_name name of the (remote) branch
* @param remote_url url of the remote
* @param oid the commit object id to use as a merge input
- * @return zero on success, -1 on failure.
+ * @return 0 on success or error code
*/
GIT_EXTERN(int) git_merge_head_from_fetchhead(
git_merge_head **out,
@@ -149,20 +383,30 @@ GIT_EXTERN(int) git_merge_head_from_fetchhead(
const git_oid *oid);
/**
- * Creates a `git_merge_head` from the given commit id
+ * Creates a `git_merge_head` from the given commit id. The resulting
+ * git_merge_head must be freed with `git_merge_head_free`.
*
* @param out pointer to store the git_merge_head result in
* @param repo repository that contains the given commit
- * @param oid the commit object id to use as a merge input
- * @return zero on success, -1 on failure.
+ * @param id the commit object id to use as a merge input
+ * @return 0 on success or error code
*/
-GIT_EXTERN(int) git_merge_head_from_oid(
+GIT_EXTERN(int) git_merge_head_from_id(
git_merge_head **out,
git_repository *repo,
- const git_oid *oid);
+ const git_oid *id);
/**
- * Frees a `git_merge_head`
+ * Gets the commit ID that the given `git_merge_head` refers to.
+ *
+ * @param head the given merge head
+ * @return commit id
+ */
+GIT_EXTERN(const git_oid *) git_merge_head_id(
+ const git_merge_head *head);
+
+/**
+ * Frees a `git_merge_head`.
*
* @param head merge head to free
*/
@@ -170,8 +414,62 @@ GIT_EXTERN(void) git_merge_head_free(
git_merge_head *head);
/**
+ * Merge two files as they exist in the in-memory data structures, using
+ * the given common ancestor as the baseline, producing a
+ * `git_merge_file_result` that reflects the merge result. The
+ * `git_merge_file_result` must be freed with `git_merge_file_result_free`.
+ *
+ * Note that this function does not reference a repository and any
+ * configuration must be passed as `git_merge_file_options`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param ancestor The contents of the ancestor file
+ * @param ours The contents of the file in "our" side
+ * @param theirs The contents of the file in "their" side
+ * @param opts The merge file options or `NULL` for defaults
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file(
+ git_merge_file_result *out,
+ const git_merge_file_input *ancestor,
+ const git_merge_file_input *ours,
+ const git_merge_file_input *theirs,
+ const git_merge_file_options *opts);
+
+/**
+ * Merge two files as they exist in the index, using the given common
+ * ancestor as the baseline, producing a `git_merge_file_result` that
+ * reflects the merge result. The `git_merge_file_result` must be freed with
+ * `git_merge_file_result_free`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param repo The repository
+ * @param ancestor The index entry for the ancestor file (stage level 1)
+ * @param ours The index entry for our file (stage level 2)
+ * @param theirs The index entry for their file (stage level 3)
+ * @param opts The merge file options or NULL
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file_from_index(
+ git_merge_file_result *out,
+ git_repository *repo,
+ const git_index_entry *ancestor,
+ const git_index_entry *ours,
+ const git_index_entry *theirs,
+ const git_merge_file_options *opts);
+
+/**
+ * Frees a `git_merge_file_result`.
+ *
+ * @param result The result to free or `NULL`
+ */
+GIT_EXTERN(void) git_merge_file_result_free(git_merge_file_result *result);
+
+/**
* Merge two trees, producing a `git_index` that reflects the result of
- * the merge.
+ * the merge. The index may be written as-is to the working directory
+ * or checked out. If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
*
* The returned index must be freed explicitly with `git_index_free`.
*
@@ -181,7 +479,7 @@ GIT_EXTERN(void) git_merge_head_free(
* @param our_tree the tree that reflects the destination tree
* @param their_tree the tree to merge in to `our_tree`
* @param opts the merge tree options (or null for defaults)
- * @return zero on success, -1 on failure.
+ * @return 0 on success or error code
*/
GIT_EXTERN(int) git_merge_trees(
git_index **out,
@@ -189,44 +487,49 @@ GIT_EXTERN(int) git_merge_trees(
const git_tree *ancestor_tree,
const git_tree *our_tree,
const git_tree *their_tree,
- const git_merge_tree_opts *opts);
+ const git_merge_options *opts);
/**
- * Merges the given commits into HEAD, producing a new commit.
+ * Merge two commits, producing a `git_index` that reflects the result of
+ * the merge. The index may be written as-is to the working directory
+ * or checked out. If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
*
- * @param out the results of the merge
- * @param repo the repository to merge
- * @param merge_heads the heads to merge into
- * @param merge_heads_len the number of heads to merge
- * @param flags merge flags
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo repository that contains the given trees
+ * @param our_commit the commit that reflects the destination tree
+ * @param their_commit the commit to merge in to `our_commit`
+ * @param opts the merge tree options (or null for defaults)
+ * @return 0 on success or error code
*/
-GIT_EXTERN(int) git_merge(
- git_merge_result **out,
+GIT_EXTERN(int) git_merge_commits(
+ git_index **out,
git_repository *repo,
- const git_merge_head **their_heads,
- size_t their_heads_len,
- const git_merge_opts *opts);
-
-/**
- * Returns true if a merge is up-to-date (we were asked to merge the target
- * into itself.)
- */
-GIT_EXTERN(int) git_merge_result_is_uptodate(git_merge_result *merge_result);
-
-/**
- * Returns true if a merge is eligible for fastforward
- */
-GIT_EXTERN(int) git_merge_result_is_fastforward(git_merge_result *merge_result);
+ const git_commit *our_commit,
+ const git_commit *their_commit,
+ const git_merge_options *opts);
/**
- * Gets the fast-forward OID if the merge was a fastforward.
+ * Merges the given commit(s) into HEAD, writing the results into the working
+ * directory. Any changes are staged for commit and any conflicts are written
+ * to the index. Callers should inspect the repository's index after this
+ * completes, resolve any conflicts and prepare a commit.
*
- * @param out the OID of the fast-forward
- * @param merge_result the results of the merge
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @param merge_opts merge options
+ * @param checkout_opts checkout options
+ * @return 0 on success or error code
*/
-GIT_EXTERN(int) git_merge_result_fastforward_oid(git_oid *out, git_merge_result *merge_result);
-
-GIT_EXTERN(void) git_merge_result_free(git_merge_result *merge_result);
+GIT_EXTERN(int) git_merge(
+ git_repository *repo,
+ const git_merge_head **their_heads,
+ size_t their_heads_len,
+ const git_merge_options *merge_opts,
+ const git_checkout_options *checkout_opts);
/** @} */
GIT_END_DECL
diff --git a/include/git2/message.h b/include/git2/message.h
index 395c88690..d78b1dce5 100644
--- a/include/git2/message.h
+++ b/include/git2/message.h
@@ -8,6 +8,7 @@
#define INCLUDE_git_message_h__
#include "common.h"
+#include "buffer.h"
/**
* @file git2/message.h
@@ -23,25 +24,19 @@ GIT_BEGIN_DECL
*
* 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 out The user-allocated git_buf which will be filled with the
+ * cleaned up message.
*
* @param message The message to be prettified.
*
- * @param strip_comments Non-zero to remove lines starting with "#", 0 to
- * leave them in.
+ * @param strip_comments Non-zero to remove comment lines, 0 to leave them in.
+ *
+ * @param comment_char Comment character. Lines starting with this character
+ * are considered to be comments and removed if `strip_comments` is non-zero.
*
- * @return -1 on error, else number of characters in prettified message
- * including the trailing NUL byte
+ * @return 0 or an error code.
*/
-GIT_EXTERN(int) git_message_prettify(
- char *out,
- size_t out_size,
- const char *message,
- int strip_comments);
+GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
/** @} */
GIT_END_DECL
diff --git a/include/git2/net.h b/include/git2/net.h
index e70ba1f71..a727696a2 100644
--- a/include/git2/net.h
+++ b/include/git2/net.h
@@ -41,6 +41,11 @@ struct git_remote_head {
git_oid oid;
git_oid loid;
char *name;
+ /**
+ * If the server send a symref mapping for this ref, this will
+ * point to the target.
+ */
+ char *symref_target;
};
/**
diff --git a/include/git2/notes.h b/include/git2/notes.h
index 76361633b..98eb2aef3 100644
--- a/include/git2/notes.h
+++ b/include/git2/notes.h
@@ -106,12 +106,12 @@ GIT_EXTERN(const char *) git_note_message(const git_note *note);
/**
- * Get the note object OID
+ * Get the note object's id
*
* @param note the note
- * @return the note object OID
+ * @return the note object's id
*/
-GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note);
+GIT_EXTERN(const git_oid *) git_note_id(const git_note *note);
/**
* Add a note for an object
@@ -189,7 +189,7 @@ GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo);
*
* @param payload Extra parameter to callback function.
*
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_note_foreach(
git_repository *repo,
diff --git a/include/git2/object.h b/include/git2/object.h
index c40631fa6..9b13d824e 100644
--- a/include/git2/object.h
+++ b/include/git2/object.h
@@ -10,6 +10,7 @@
#include "common.h"
#include "types.h"
#include "oid.h"
+#include "buffer.h"
/**
* @file git2/object.h
@@ -104,6 +105,20 @@ GIT_EXTERN(int) git_object_lookup_bypath(
GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj);
/**
+ * Get a short abbreviated OID string for the object
+ *
+ * This starts at the "core.abbrev" length (default 7 characters) and
+ * iteratively extends to a longer string if that length is ambiguous.
+ * The result will be unambiguous (at least until new objects are added to
+ * the repository).
+ *
+ * @param out Buffer to write string into
+ * @param obj The object to get an ID for
+ * @return 0 on success, <0 for error
+ */
+GIT_EXTERN(int) git_object_short_id(git_buf *out, const git_object *obj);
+
+/**
* Get the object type of an object
*
* @param obj the repository object
@@ -143,7 +158,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
GIT_EXTERN(void) git_object_free(git_object *object);
/**
- * Convert an object type to it's string representation.
+ * Convert an object type to its string representation.
*
* The result is a pointer to a string in static memory and
* should not be free()'ed.
diff --git a/include/git2/odb.h b/include/git2/odb.h
index ad56384f0..114f6b317 100644
--- a/include/git2/odb.h
+++ b/include/git2/odb.h
@@ -159,6 +159,19 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_od
GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
/**
+ * Determine if objects can be found in the object database from a short OID.
+ *
+ * @param out The full OID of the found object if just one is found.
+ * @param db The database to be searched for the given object.
+ * @param short_id A prefix of the id of the object to read.
+ * @param len The length of the prefix.
+ * @return 0 if found, GIT_ENOTFOUND if not found, GIT_EAMBIGUOUS if multiple
+ * matches were found, other value < 0 if there was a read error.
+ */
+GIT_EXTERN(int) git_odb_exists_prefix(
+ git_oid *out, git_odb *db, const git_oid *short_id, size_t len);
+
+/**
* Refresh the object database to load newly added files.
*
* If the object databases have changed on disk while the library
@@ -189,7 +202,7 @@ GIT_EXTERN(int) git_odb_refresh(struct git_odb *db);
* @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
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload);
@@ -325,7 +338,7 @@ GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const gi
GIT_EXTERN(int) git_odb_write_pack(
git_odb_writepack **out,
git_odb *db,
- git_transfer_progress_callback progress_cb,
+ git_transfer_progress_cb progress_cb,
void *progress_payload);
/**
diff --git a/include/git2/oid.h b/include/git2/oid.h
index 384b656d7..1cfd4e5e2 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -167,10 +167,7 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
* @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);
-}
+GIT_EXTERN(int) git_oid_equal(const git_oid *a, const git_oid *b);
/**
* Compare the first 'len' hexadecimal characters (packets of 4 bits)
diff --git a/include/git2/pack.h b/include/git2/pack.h
index 88a2716bb..e7f060d12 100644
--- a/include/git2/pack.h
+++ b/include/git2/pack.h
@@ -52,7 +52,7 @@ typedef enum {
GIT_PACKBUILDER_ADDING_OBJECTS = 0,
GIT_PACKBUILDER_DELTAFICATION = 1,
} git_packbuilder_stage_t;
-
+
/**
* Initialize a new packbuilder
*
@@ -115,6 +115,17 @@ GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *
GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id);
/**
+ * Write the contents of the packfile to an in-memory buffer
+ *
+ * The contents of the buffer will become a valid packfile, even though there
+ * will be no attached index
+ *
+ * @param buf Buffer where to write the packfile
+ * @param pb The packbuilder
+ */
+GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
+
+/**
* Write the new pack and corresponding index file to path.
*
* @param pb The packbuilder
@@ -129,7 +140,7 @@ GIT_EXTERN(int) git_packbuilder_write(
git_packbuilder *pb,
const char *path,
unsigned int mode,
- git_transfer_progress_callback progress_cb,
+ git_transfer_progress_cb progress_cb,
void *progress_cb_payload);
/**
@@ -143,6 +154,7 @@ GIT_EXTERN(int) git_packbuilder_write(
GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
+
/**
* Create the new pack and pass each object to the callback
*
diff --git a/include/git2/patch.h b/include/git2/patch.h
index 6a6ad92d7..47c395669 100644
--- a/include/git2/patch.h
+++ b/include/git2/patch.h
@@ -106,6 +106,34 @@ GIT_EXTERN(int) git_patch_from_blob_and_buffer(
const git_diff_options *opts);
/**
+ * Directly generate a patch from the difference between two buffers.
+ *
+ * This is just like `git_diff_buffers()` except it generates a patch
+ * object for the difference instead of directly making callbacks. You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_buffers(
+ git_patch **out,
+ const void *old_buffer,
+ size_t old_len,
+ const char *old_as_path,
+ const char *new_buffer,
+ size_t new_len,
+ const char *new_as_path,
+ const git_diff_options *opts);
+
+/**
* Free a git_patch object.
*/
GIT_EXTERN(void) git_patch_free(git_patch *patch);
@@ -113,12 +141,12 @@ GIT_EXTERN(void) git_patch_free(git_patch *patch);
/**
* Get the delta associated with a patch
*/
-GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(git_patch *patch);
+GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch);
/**
* Get the number of hunks in a patch
*/
-GIT_EXTERN(size_t) git_patch_num_hunks(git_patch *patch);
+GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch);
/**
* Get line counts of each type in a patch.
@@ -169,7 +197,7 @@ GIT_EXTERN(int) git_patch_get_hunk(
* @return Number of lines in hunk or -1 if invalid hunk index
*/
GIT_EXTERN(int) git_patch_num_lines_in_hunk(
- git_patch *patch,
+ const git_patch *patch,
size_t hunk_idx);
/**
@@ -218,13 +246,13 @@ GIT_EXTERN(size_t) git_patch_size(
* 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`.
+ * and return that value to the caller.
*
* @param patch A git_patch representing changes to one file
* @param print_cb Callback function to output lines of the patch. Will be
* called for file headers, hunk headers, and diff lines.
* @param payload Reference pointer that will be passed to your callbacks.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_patch_print(
git_patch *patch,
@@ -234,15 +262,14 @@ GIT_EXTERN(int) git_patch_print(
/**
* Get the content of a patch as a single diff text.
*
- * @param string Allocated string; caller must free.
+ * @param out The git_buf to be filled in
* @param patch A git_patch representing changes to one file
* @return 0 on success, <0 on failure.
*/
-GIT_EXTERN(int) git_patch_to_str(
- char **string,
+GIT_EXTERN(int) git_patch_to_buf(
+ git_buf *out,
git_patch *patch);
-
GIT_END_DECL
/**@}*/
diff --git a/include/git2/pathspec.h b/include/git2/pathspec.h
index 2fb0bb716..de6f027c5 100644
--- a/include/git2/pathspec.h
+++ b/include/git2/pathspec.h
@@ -12,6 +12,8 @@
#include "strarray.h"
#include "diff.h"
+GIT_BEGIN_DECL
+
/**
* Compiled pathspec
*/
@@ -257,4 +259,5 @@ GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
const git_pathspec_match_list *m, size_t pos);
+GIT_END_DECL
#endif
diff --git a/include/git2/push.h b/include/git2/push.h
index 77ef74039..cbf115661 100644
--- a/include/git2/push.h
+++ b/include/git2/push.h
@@ -39,6 +39,19 @@ typedef struct {
#define GIT_PUSH_OPTIONS_VERSION 1
#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION }
+/**
+ * Initializes a `git_push_options` with default values. Equivalent to
+ * creating an instance with GIT_PUSH_OPTIONS_INIT.
+ *
+ * @param opts the `git_push_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_PUSH_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_push_init_options(
+ git_push_options *opts,
+ unsigned int version);
+
/** Push network progress notification function */
typedef int (*git_push_transfer_progress)(
unsigned int current,
@@ -103,10 +116,16 @@ GIT_EXTERN(int) git_push_add_refspec(git_push *push, const char *refspec);
* Update remote tips after a push
*
* @param push The push object
+ * @param signature The identity to use when updating reflogs
+ * @param reflog_message The message to insert into the reflogs. If NULL, the
+ * default is "update by push".
*
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_push_update_tips(git_push *push);
+GIT_EXTERN(int) git_push_update_tips(
+ git_push *push,
+ const git_signature *signature,
+ const char *reflog_message);
/**
* Actually push all given refspecs
@@ -129,20 +148,22 @@ GIT_EXTERN(int) git_push_finish(git_push *push);
*
* @return true if remote side successfully unpacked, false otherwise
*/
-GIT_EXTERN(int) git_push_unpack_ok(git_push *push);
+GIT_EXTERN(int) git_push_unpack_ok(const git_push *push);
/**
- * Call callback `cb' on each status
+ * Invoke callback `cb' on each status entry
*
* 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.
*
+ * Return a non-zero value from the callback to stop the loop.
+ *
* @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
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_push_status_foreach(git_push *push,
int (*cb)(const char *ref, const char *msg, void *data),
diff --git a/include/git2/reflog.h b/include/git2/reflog.h
index 2d1b6eeaa..ac42a231c 100644
--- a/include/git2/reflog.h
+++ b/include/git2/reflog.h
@@ -47,7 +47,7 @@ GIT_EXTERN(int) git_reflog_read(git_reflog **out, git_repository *repo, const c
GIT_EXTERN(int) git_reflog_write(git_reflog *reflog);
/**
- * Add a new entry to the reflog.
+ * Add a new entry to the in-memory reflog.
*
* `msg` is optional and can be NULL.
*
@@ -60,23 +60,6 @@ GIT_EXTERN(int) git_reflog_write(git_reflog *reflog);
GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg);
/**
- * Add a new entry to the named reflog.
- *
- * This utility function loads the named reflog, appends to it and
- * writes it back out to the backend.
- *
- * `msg` is optional and can be NULL.
- *
- * @param repo the repository to act on
- * @param name the reflog's name
- * @param id the OID the reference is now pointing to
- * @param committer the signature of the committer
- * @param msg the reflog message
- * @return 0 or an error code
- */
-GIT_EXTERN(int) git_reflog_append_to(git_repository *repo, const char *name, const git_oid *id, const git_signature *committer, const char *msg);
-
-/**
* Rename a reflog
*
* The reflog to be renamed is expected to already exist
@@ -86,7 +69,7 @@ GIT_EXTERN(int) git_reflog_append_to(git_repository *repo, const char *name, con
*
* @param repo the repository
* @param old_name the old name of the reference
- * @param new_name the new name of the reference
+ * @param name the new name of the reference
* @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_reflog_rename(git_repository *repo, const char *old_name, const char *name);
diff --git a/include/git2/refs.h b/include/git2/refs.h
index 4041947f6..e5bb15c7c 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -27,7 +27,7 @@ GIT_BEGIN_DECL
* The returned reference must be freed by the user.
*
* The name will be checked for validity.
- * See `git_reference_create_symbolic()` for rules about valid names.
+ * See `git_reference_symbolic_create()` for rules about valid names.
*
* @param out pointer to the looked-up reference
* @param repo the repository to look up the reference
@@ -68,6 +68,48 @@ GIT_EXTERN(int) git_reference_name_to_id(
GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, const char *shorthand);
/**
+ * Conditionally create a new symbolic reference.
+ *
+ * A symbolic reference is a reference name that refers to another
+ * reference name. If the other name moves, the symbolic name will move,
+ * too. As a simple example, the "HEAD" reference might refer to
+ * "refs/heads/master" while on the "master" branch of a repository.
+ *
+ * The symbolic reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The signature and message for the reflog will be ignored if the
+ * reference does not belong in the standard set (HEAD, branches and
+ * remote-tracking branches) and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_value`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param target The target of the reference
+ * @param force Overwrite existing references
+ * @param current_value The expected value of the reference when updating
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC, GIT_EMODIFIED or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_create_matching(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *current_value, const git_signature *signature, const char *log_message);
+
+/**
* Create a new symbolic reference.
*
* A symbolic reference is a reference name that refers to another
@@ -89,14 +131,20 @@ GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, co
* This function will return an error if a reference already exists with the
* given name unless `force` is true, in which case it will be overwritten.
*
+ * The signature and message for the reflog will be ignored if the
+ * reference does not belong in the standard set (HEAD, branches and
+ * remote-tracking branches) and it does not have a reflog.
+ *
* @param out Pointer to the newly created reference
* @param repo Repository where that reference will live
* @param name The name of the reference
* @param target The target of the reference
* @param force Overwrite existing references
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force);
+GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const git_signature *signature, const char *log_message);
/**
* Create a new direct reference.
@@ -121,14 +169,64 @@ GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repositor
* This function will return an error if a reference already exists with the
* given name unless `force` is true, in which case it will be overwritten.
*
+ * The signature and message for the reflog will be ignored if the
+ * reference does not belong in the standard set (HEAD, branches and
+ * remote-tracking branches) and and it does not have a reflog.
+ *
* @param out Pointer to the newly created reference
* @param repo Repository where that reference will live
* @param name The name of the reference
* @param id The object id pointed to by the reference.
* @param force Overwrite existing references
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force);
+GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_signature *signature, const char *log_message);
+
+/**
+ * Conditionally create new direct reference
+ *
+ * A direct reference (also called an object id reference) refers directly
+ * to a specific object id (a.k.a. OID or SHA) in the repository. The id
+ * permanently refers to the object (although the reference itself can be
+ * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"
+ * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
+ *
+ * The direct reference will be created in the repository and written to
+ * the disk. The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The signature and message for the reflog will be ignored if the
+ * reference does not belong in the standard set (HEAD, branches and
+ * remote-tracking branches) and and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_id`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param id The object id pointed to by the reference.
+ * @param force Overwrite existing references
+ * @param current_id The expected value of the reference at the time of update
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_create_matching(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_oid *current_id, const git_signature *signature, const char *log_message);
/**
* Get the OID pointed to by a direct reference.
@@ -179,7 +277,7 @@ GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref);
/**
* Get the full name of a reference.
*
- * See `git_reference_create_symbolic()` for rules about valid names.
+ * See `git_reference_symbolic_create()` for rules about valid names.
*
* @param ref The reference
* @return the full name for the ref
@@ -220,20 +318,28 @@ GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
* The new reference will be written to disk, overwriting the given reference.
*
* The target name will be checked for validity.
- * See `git_reference_create_symbolic()` for rules about valid names.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * The signature and message for the reflog will be ignored if the
+ * reference does not belong in the standard set (HEAD, branches and
+ * remote-tracking branches) and and it does not have a reflog.
*
* @param out Pointer to the newly created reference
* @param ref The reference
* @param target The new target for the reference
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_reference_symbolic_set_target(
git_reference **out,
git_reference *ref,
- const char *target);
+ const char *target,
+ const git_signature *signature,
+ const char *log_message);
/**
- * Create a new reference with the same name as the given reference but a
+ * Conditionally create a new reference with the same name as the given reference but a
* different OID target. The reference must be a direct reference, otherwise
* this will fail.
*
@@ -242,12 +348,17 @@ GIT_EXTERN(int) git_reference_symbolic_set_target(
* @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
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed since it was read, or an error code
*/
GIT_EXTERN(int) git_reference_set_target(
git_reference **out,
git_reference *ref,
- const git_oid *id);
+ const git_oid *id,
+ const git_signature *signature,
+ const char *log_message);
/**
* Rename an existing reference.
@@ -255,7 +366,7 @@ GIT_EXTERN(int) git_reference_set_target(
* This method works for both direct and symbolic references.
*
* The new name will be checked for validity.
- * See `git_reference_create_symbolic()` for rules about valid names.
+ * See `git_reference_symbolic_create()` for rules about valid names.
*
* If the `force` flag is not enabled, and there's already
* a reference with the given name, the renaming will fail.
@@ -268,6 +379,8 @@ GIT_EXTERN(int) git_reference_set_target(
* @param ref The reference to rename
* @param new_name The new name for the reference
* @param force Overwrite an existing reference
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
*
*/
@@ -275,7 +388,9 @@ GIT_EXTERN(int) git_reference_rename(
git_reference **new_ref,
git_reference *ref,
const char *new_name,
- int force);
+ int force,
+ const git_signature *signature,
+ const char *log_message);
/**
* Delete an existing reference.
@@ -284,12 +399,26 @@ GIT_EXTERN(int) git_reference_rename(
* will be immediately removed on disk but the memory will not be freed.
* Callers must call `git_reference_free`.
*
+ * This function will return an error if the reference has changed
+ * from the time it was looked up.
+ *
* @param ref The reference to remove
- * @return 0 or an error code
+ * @return 0, GIT_EMODIFIED or an error code
*/
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
/**
+ * Delete an existing reference by name
+ *
+ * This method removes the named reference from the repository without
+ * looking at its old value.
+ *
+ * @param name The reference to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_remove(git_repository *repo, const char *name);
+
+/**
* Fill a list with all the references that can be found in a repository.
*
* The string array will be filled with the names of all references; these
@@ -310,20 +439,33 @@ typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload);
* Perform a callback on each reference in the repository.
*
* The `callback` function will be called for each reference in the
- * repository, receiving the name of the reference and the `payload` value
+ * repository, receiving the reference object and the `payload` value
* passed to this method. Returning a non-zero value from the callback
* will terminate the iteration.
*
* @param repo Repository where to find the refs
* @param callback Function which will be called for every listed ref
* @param payload Additional data to pass to the callback
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_reference_foreach(
git_repository *repo,
git_reference_foreach_cb callback,
void *payload);
+/**
+ * Perform a callback on the fully-qualified name of each reference.
+ *
+ * The `callback` function will be called for each reference in the
+ * repository, receiving the name of the reference and the `payload` value
+ * passed to this method. Returning a non-zero value from the callback
+ * will terminate the iteration.
+ *
+ * @param repo Repository where to find the refs
+ * @param callback Function which will be called for every listed ref name
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
GIT_EXTERN(int) git_reference_foreach_name(
git_repository *repo,
git_reference_foreach_name_cb callback,
@@ -343,7 +485,9 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref);
* @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);
+GIT_EXTERN(int) git_reference_cmp(
+ const git_reference *ref1,
+ const git_reference *ref2);
/**
* Create an iterator for the repo's references
@@ -379,6 +523,17 @@ GIT_EXTERN(int) git_reference_iterator_glob_new(
*/
GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter);
+/**
+ * Get the next reference's name
+ *
+ * This function is provided for convenience in case only the names
+ * are interesting as it avoids the allocation of the `git_reference`
+ * object which `git_reference_next()` needs.
+ *
+ * @param out pointer in which to store the string
+ * @param iter the iterator
+ * @return 0, GIT_ITEROVER if there are no more; or an error code
+ */
GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter);
/**
@@ -415,12 +570,24 @@ GIT_EXTERN(int) git_reference_foreach_glob(
/**
* Check if a reflog exists for the specified reference.
*
- * @param ref A git reference
- *
+ * @param repo the repository
+ * @param refname the reference's name
* @return 0 when no reflog can be found, 1 when it exists;
* otherwise an error code.
*/
-GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
+GIT_EXTERN(int) git_reference_has_log(git_repository *repo, const char *refname);
+
+/**
+ * Ensure there is a reflog for a particular reference.
+ *
+ * Make sure that successive updates to the reference will append to
+ * its log.
+ *
+ * @param repo the repository
+ * @param refname the reference's name
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_reference_ensure_log(git_repository *repo, const char *refname);
/**
* Check if a reference is a local branch.
@@ -430,7 +597,7 @@ GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
* @return 1 when the reference lives in the refs/heads
* namespace; 0 otherwise.
*/
-GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
+GIT_EXTERN(int) git_reference_is_branch(const git_reference *ref);
/**
* Check if a reference is a remote tracking branch
@@ -440,7 +607,7 @@ GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
* @return 1 when the reference lives in the refs/remotes
* namespace; 0 otherwise.
*/
-GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
+GIT_EXTERN(int) git_reference_is_remote(const git_reference *ref);
/**
* Check if a reference is a tag
@@ -450,7 +617,17 @@ GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
* @return 1 when the reference lives in the refs/tags
* namespace; 0 otherwise.
*/
-GIT_EXTERN(int) git_reference_is_tag(git_reference *ref);
+GIT_EXTERN(int) git_reference_is_tag(const git_reference *ref);
+
+/**
+ * Check if a reference is a note
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/notes
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_note(const git_reference *ref);
typedef enum {
GIT_REF_FORMAT_NORMAL = 0u,
@@ -490,7 +667,7 @@ typedef enum {
* Once normalized, if the reference name is valid, it will be returned in
* the user allocated buffer.
*
- * See `git_reference_create_symbolic()` for rules about valid names.
+ * See `git_reference_symbolic_create()` for rules about valid names.
*
* @param buffer_out User allocated buffer to store normalized name
* @param buffer_size Size of buffer_out
@@ -554,7 +731,7 @@ GIT_EXTERN(int) git_reference_is_valid_name(const char *refname);
* @param ref a reference
* @return the human-readable version of the name
*/
-GIT_EXTERN(const char *) git_reference_shorthand(git_reference *ref);
+GIT_EXTERN(const char *) git_reference_shorthand(const git_reference *ref);
/** @} */
diff --git a/include/git2/refspec.h b/include/git2/refspec.h
index d96b83ce2..9acdc72d5 100644
--- a/include/git2/refspec.h
+++ b/include/git2/refspec.h
@@ -10,6 +10,7 @@
#include "common.h"
#include "types.h"
#include "net.h"
+#include "buffer.h"
/**
* @file git2/refspec.h
@@ -82,23 +83,21 @@ GIT_EXTERN(int) git_refspec_dst_matches(const git_refspec *refspec, const char *
* Transform a reference to its target following the refspec's rules
*
* @param out where to store the target 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_transform(char *out, size_t outlen, const git_refspec *spec, const char *name);
+GIT_EXTERN(int) git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name);
/**
* Transform a target reference to its source reference following the refspec's rules
*
* @param out where to store the source reference name
- * @param 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_EXTERN(int) git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name);
GIT_END_DECL
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 7410909dc..c72c9c8cc 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -62,10 +62,10 @@ GIT_EXTERN(int) git_remote_create_with_fetchspec(
const char *fetch);
/**
- * Create a remote in memory
+ * Create an anonymous remote
*
- * 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
+ * Create a remote with the given url and refspec in memory. You can use
+ * this when you have a URL instead of a remote's name. Note that anonymous
* remotes cannot be converted to persisted remotes.
*
* The name, when provided, will be checked for validity.
@@ -73,15 +73,15 @@ GIT_EXTERN(int) git_remote_create_with_fetchspec(
*
* @param out pointer to the new remote object
* @param repo the associated repository
- * @param fetch the fetch refspec to use for this remote.
* @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_create_inmemory(
+GIT_EXTERN(int) git_remote_create_anonymous(
git_remote **out,
git_repository *repo,
- const char *fetch,
- const char *url);
+ const char *url,
+ const char *fetch);
/**
* Get the information for a particular remote
@@ -108,6 +108,18 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
/**
+ * Create a copy of an existing remote. All internal strings are also
+ * duplicated. Callbacks are not duplicated.
+ *
+ * Call `git_remote_free` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_dup(git_remote **dest, git_remote *source);
+
+/**
* Get the remote's repository
*
* @param remote the remote
@@ -182,7 +194,7 @@ GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
* @param array pointer to the array in which to store the strings
* @param remote the remote to query
*/
-GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote);
+GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote);
/**
* Set the remote's list of fetch refspecs
@@ -215,7 +227,7 @@ GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec);
* @param array pointer to the array in which to store the strings
* @param remote the remote to query
*/
-GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *remote);
+GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote);
/**
* Set the remote's list of push refspecs
@@ -242,7 +254,7 @@ GIT_EXTERN(void) git_remote_clear_refspecs(git_remote *remote);
* @param remote the remote
* @return the amount of refspecs configured in this remote
*/
-GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote);
+GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote);
/**
* Get a refspec from the remote
@@ -251,7 +263,7 @@ GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote);
* @param n the refspec to get
* @return the nth refspec
*/
-GIT_EXTERN(const git_refspec *)git_remote_get_refspec(git_remote *remote, size_t n);
+GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, size_t n);
/**
* Open a connection to a remote
@@ -307,7 +319,7 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote);
* @param remote the remote
* @return 1 if it's connected, 0 otherwise.
*/
-GIT_EXTERN(int) git_remote_connected(git_remote *remote);
+GIT_EXTERN(int) git_remote_connected(const git_remote *remote);
/**
* Cancel the operation
@@ -343,9 +355,16 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
* Update the tips to the new state
*
* @param remote the remote to update
+ * @param signature The identity to use when updating reflogs
+ * @param reflog_message The message to insert into the reflogs. If NULL, the
+ * default is "fetch <name>", where <name> is the name of
+ * the remote (or its url, for in-memory remotes).
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
+GIT_EXTERN(int) git_remote_update_tips(
+ git_remote *remote,
+ const git_signature *signature,
+ const char *reflog_message);
/**
* Download new data and update tips
@@ -354,9 +373,15 @@ GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
* disconnect and update the remote-tracking branches.
*
* @param remote the remote to fetch from
+ * @param signature The identity to use when updating reflogs
+ * @param reflog_message The message to insert into the reflogs. If NULL, the
+ * default is "fetch"
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_fetch(git_remote *remote);
+GIT_EXTERN(int) git_remote_fetch(
+ git_remote *remote,
+ const git_signature *signature,
+ const char *reflog_message);
/**
* Return whether a string is a valid remote URL
@@ -432,7 +457,7 @@ struct git_remote_callbacks {
* progress side-band will be passed to this function (this is
* the 'counting objects' output.
*/
- int (*progress)(const char *str, int len, void *data);
+ git_transport_message_cb sideband_progress;
/**
* Completion is called when different parts of the download
@@ -443,15 +468,18 @@ struct git_remote_callbacks {
/**
* This will be called if the remote host requires
* authentication in order to connect to it.
+ *
+ * Returning GIT_PASSTHROUGH will make libgit2 behave as
+ * though this field isn't set.
*/
- int (*credentials)(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data);
+ git_cred_acquire_cb credentials;
/**
* During the download of new data, this will be regularly
* called with the current count of progress done by the
* indexer.
*/
- int (*transfer_progress)(const git_transfer_progress *stats, void *data);
+ git_transfer_progress_cb transfer_progress;
/**
* Each time a reference is updated locally, this function
@@ -470,6 +498,18 @@ struct git_remote_callbacks {
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
/**
+ * Initializes a `git_remote_callbacks` with default values. Equivalent to
+ * creating an instance with GIT_REMOTE_CALLBACKS_INIT.
+ *
+ * @param opts the `git_remote_callbacks` struct to initialize
+ * @param version Version of struct; pass `GIT_REMOTE_CALLBACKS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_init_callbacks(
+ git_remote_callbacks *opts,
+ unsigned int version);
+
+/**
* Set the callbacks for a remote
*
* Note that the remote keeps its own copy of the data and you need to
@@ -482,6 +522,17 @@ struct git_remote_callbacks {
GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks);
/**
+ * Retrieve the current callback structure
+ *
+ * This provides read access to the callbacks structure as the remote
+ * sees it.
+ *
+ * @param remote the remote to query
+ * @return a pointer to the callbacks structure
+ */
+GIT_EXTERN(const git_remote_callbacks *) git_remote_get_callbacks(git_remote *remote);
+
+/**
* Get the statistics structure that is filled in by the fetch operation.
*/
GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote);
@@ -498,7 +549,7 @@ typedef enum {
* @param remote the remote to query
* @return the auto-follow setting
*/
-GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(git_remote *remote);
+GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *remote);
/**
* Set the tag auto-follow setting
@@ -521,18 +572,17 @@ GIT_EXTERN(void) git_remote_set_autotag(
*
* A temporary in-memory remote cannot be given a name with this method.
*
+ * @param problems non-default refspecs cannot be renamed and will be
+ * stored here for further processing by the caller. Always free this
+ * strarray on succesful return.
* @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_strarray *problems,
git_remote *remote,
- const char *new_name,
- git_remote_rename_problem_cb callback,
- void *payload);
+ const char *new_name);
/**
* Retrieve the update FETCH_HEAD setting.
@@ -559,6 +609,35 @@ GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value);
*/
GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
+/**
+* Delete an existing persisted remote.
+*
+* All remote-tracking branches and configuration settings
+* for the remote will be removed.
+*
+* @param remote A valid remote
+* @return 0 on success, or an error code.
+*/
+GIT_EXTERN(int) git_remote_delete(git_remote *remote);
+
+/**
+ * Retrieve the name of the remote's default branch
+ *
+ * The default branch of a repository is the branch which HEAD points
+ * to. If the remote does not support reporting this information
+ * directly, it performs the guess as git does; that is, if there are
+ * multiple branches which point to the same commit, the first one is
+ * chosen. If the master branch is a candidate, it wins.
+ *
+ * This function must only be called after connecting.
+ *
+ * @param out the buffern in which to store the reference name
+ * @param remote the remote
+ * @return 0, GIT_ENOTFOUND if the remote does not have any references
+ * or none of them point to HEAD's commit, or an error message.
+ */
+GIT_EXTERN(int) git_remote_default_branch(git_buf *out, git_remote *remote);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/repository.h b/include/git2/repository.h
index b4d561992..6a8ff4545 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -10,6 +10,7 @@
#include "common.h"
#include "types.h"
#include "oid.h"
+#include "buffer.h"
/**
* @file git2/repository.h
@@ -58,10 +59,8 @@ GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
* The method will automatically detect if the repository is bare
* (if there is a repository).
*
- * @param path_out The user allocated buffer which will
- * contain the found path.
- *
- * @param path_size repository_path size
+ * @param out A pointer to a user-allocated git_buf which will contain
+ * the found path.
*
* @param start_path The base path where the lookup starts.
*
@@ -77,8 +76,7 @@ GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
* @return 0 or an error code
*/
GIT_EXTERN(int) git_repository_discover(
- char *path_out,
- size_t path_size,
+ git_buf *out,
const char *start_path,
int across_fs,
const char *ceiling_dirs);
@@ -270,6 +268,18 @@ typedef struct {
#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}
/**
+ * Initializes a `git_repository_init_options` with default values. Equivalent
+ * to creating an instance with GIT_REPOSITORY_INIT_OPTIONS_INIT.
+ *
+ * @param opts the `git_repository_init_options` struct to initialize
+ * @param version Version of struct; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_repository_init_init_options(
+ git_repository_init_options *opts,
+ unsigned int version);
+
+/**
* Create a new Git repository in the given folder with extended controls.
*
* This will initialize a new git repository (creating the repo_path
@@ -398,13 +408,29 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
* The configuration file must be freed once it's no longer
* being used by the user.
*
- * @param out Pointer to store the loaded config file
+ * @param out Pointer to store the loaded configuration
* @param repo A repository object
* @return 0, or an error code
*/
GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);
/**
+ * Get a snapshot of the repository's configuration
+ *
+ * Convenience function to take a snapshot from the repository's
+ * configuration. The contents of this snapshot will not change,
+ * even if the underlying config files are modified.
+ *
+ * The configuration file must be freed once it's no longer
+ * being used by the user.
+ *
+ * @param out Pointer to store the loaded configuration
+ * @param repo the repository
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_config_snapshot(git_config **out, git_repository *repo);
+
+/**
* Get the Object Database for this repository.
*
* If a custom ODB has not been set, the default
@@ -464,21 +490,11 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
* Use this function to get the contents of this file. Don't forget to
* remove the file after you create the commit.
*
- * If the repository message exists and there are no errors reading it, this
- * returns the bytes needed to store the message in memory (i.e. message
- * file size plus one terminating NUL byte). That value is returned even if
- * `out` is NULL or `len` is shorter than the necessary size.
- *
- * The `out` buffer will *always* be NUL terminated, even if truncation
- * occurs.
- *
- * @param out Buffer to write data into or NULL to just read required size
- * @param len Length of `out` buffer in bytes
+ * @param out git_buf to write data into
* @param repo Repository to read prepared message from
- * @return GIT_ENOTFOUND if no message exists, other value < 0 for other
- * errors, or total bytes in message (may be > `len`) on success
+ * @return 0, GIT_ENOTFOUND if no message exists or an error code
*/
-GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
+GIT_EXTERN(int) git_repository_message(git_buf *out, git_repository *repo);
/**
* Remove git's prepared message.
@@ -488,13 +504,13 @@ GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *re
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.
+ * Remove all the metadata associated with an ongoing command like merge,
+ * revert, cherry-pick, etc. For example: MERGE_HEAD, MERGE_MSG, etc.
*
* @param repo A repository object
* @return 0 on success, or error
*/
-GIT_EXTERN(int) git_repository_merge_cleanup(git_repository *repo);
+GIT_EXTERN(int) git_repository_state_cleanup(git_repository *repo);
typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
const char *remote_url,
@@ -503,14 +519,18 @@ typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
void *payload);
/**
- * Call callback 'callback' for each entry in the given FETCH_HEAD file.
+ * Invoke 'callback' for each entry in the given FETCH_HEAD file.
+ *
+ * Return a non-zero value from the callback to stop the loop.
*
* @param repo A repository object
* @param callback Callback function
* @param payload Pointer to callback data (optional)
- * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
+ * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
+ * there is no FETCH_HEAD file, or other error code.
*/
-GIT_EXTERN(int) git_repository_fetchhead_foreach(git_repository *repo,
+GIT_EXTERN(int) git_repository_fetchhead_foreach(
+ git_repository *repo,
git_repository_fetchhead_foreach_cb callback,
void *payload);
@@ -518,15 +538,19 @@ 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
+ * If a merge is in progress, invoke 'callback' for each commit ID in the
* MERGE_HEAD file.
*
+ * Return a non-zero value from the callback to stop the loop.
+ *
* @param repo A repository object
* @param callback Callback function
* @param payload Pointer to callback data (optional)
- * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
+ * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
+ * there is no MERGE_HEAD file, or other error code.
*/
-GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo,
+GIT_EXTERN(int) git_repository_mergehead_foreach(
+ git_repository *repo,
git_repository_mergehead_foreach_cb callback,
void *payload);
@@ -538,6 +562,10 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo,
* hash a file in the repository and you want to apply filtering rules (e.g.
* crlf filters) before generating the SHA, then use this function.
*
+ * Note: if the repository has `core.safecrlf` set to fail and the
+ * filtering triggers that failure, then this function will return an
+ * error and not calculate the hash of the file.
+ *
* @param out Output value of calculated SHA
* @param repo Repository pointer
* @param path Path to file on disk whose contents should be hashed. If the
@@ -547,6 +575,7 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo,
* NULL, then the `path` parameter will be used instead. If
* this is passed as the empty string, then no filters will be
* applied when calculating the hash.
+ * @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_repository_hashfile(
git_oid *out,
@@ -571,11 +600,15 @@ GIT_EXTERN(int) git_repository_hashfile(
*
* @param repo Repository pointer
* @param refname Canonical name of the reference the HEAD should point at
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_repository_set_head(
git_repository* repo,
- const char* refname);
+ const char* refname,
+ const git_signature *signature,
+ const char *log_message);
/**
* Make the repository HEAD directly point to the Commit.
@@ -591,11 +624,15 @@ GIT_EXTERN(int) git_repository_set_head(
*
* @param repo Repository pointer
* @param commitish Object id of the Commit the HEAD should point to
+ * @param signature The identity that will used to populate the reflog entry
+ * @param log_message The one line long message to be appended to the reflog
* @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_repository_set_head_detached(
git_repository* repo,
- const git_oid* commitish);
+ const git_oid* commitish,
+ const git_signature *signature,
+ const char *log_message);
/**
* Detach the HEAD.
@@ -611,11 +648,15 @@ GIT_EXTERN(int) git_repository_set_head_detached(
* Otherwise, the HEAD will be detached and point to the peeled Commit.
*
* @param repo Repository pointer
+ * @param signature The identity that will used to populate the reflog entry
+ * @param reflog_message The one line long message to be appended to the reflog
* @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
* branch or an error code
*/
GIT_EXTERN(int) git_repository_detach_head(
- git_repository* repo);
+ git_repository* repo,
+ const git_signature *signature,
+ const char *reflog_message);
typedef enum {
GIT_REPOSITORY_STATE_NONE,
diff --git a/include/git2/reset.h b/include/git2/reset.h
index c36781722..b8c580339 100644
--- a/include/git2/reset.h
+++ b/include/git2/reset.h
@@ -19,9 +19,9 @@ 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_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;
/**
@@ -48,10 +48,21 @@ typedef enum {
*
* @param reset_type Kind of reset operation to perform.
*
+ * @param signature The identity that will used to populate the reflog entry
+ *
+ * @param log_message The one line long message to be appended to the reflog.
+ * The reflog is only updated if the affected direct reference is actually
+ * changing. If NULL, the default is "reset: moving"; if you want something more
+ * useful, provide a message.
+ *
* @return 0 on success or an error code
*/
GIT_EXTERN(int) git_reset(
- git_repository *repo, git_object *target, git_reset_t reset_type);
+ git_repository *repo,
+ git_object *target,
+ git_reset_t reset_type,
+ git_signature *signature,
+ const char *log_message);
/**
* Updates some entries in the index from the target commit tree.
diff --git a/include/git2/revert.h b/include/git2/revert.h
new file mode 100644
index 000000000..fc1767c93
--- /dev/null
+++ b/include/git2/revert.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_revert_h__
+#define INCLUDE_git_revert_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/revert.h
+ * @brief Git revert routines
+ * @defgroup git_revert Git revert routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef struct {
+ unsigned int version;
+
+ /** For merge commits, the "mainline" is treated as the parent. */
+ unsigned int mainline;
+
+ git_merge_options merge_opts;
+ git_checkout_options checkout_opts;
+} git_revert_options;
+
+#define GIT_REVERT_OPTIONS_VERSION 1
+#define GIT_REVERT_OPTIONS_INIT {GIT_REVERT_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initializes a `git_revert_options` with default values. Equivalent to
+ * creating an instance with GIT_REVERT_OPTIONS_INIT.
+ *
+ * @param opts the `git_revert_options` struct to initialize
+ * @param version Version of struct; pass `GIT_REVERT_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_revert_init_options(
+ git_revert_options *opts,
+ unsigned int version);
+
+/**
+ * Reverts the given commit against the given "our" commit, producing an
+ * index that reflects the result of the revert.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param revert_commit the commit to revert
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+int git_revert_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *revert_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_options);
+
+/**
+ * Reverts the given commit, producing changes in the working directory.
+ *
+ * @param repo the repository to revert
+ * @param commit the commit to revert
+ * @param given_opts merge flags
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_revert(
+ git_repository *repo,
+ git_commit *commit,
+ const git_revert_options *given_opts);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h
index c59b79938..1bd6186f3 100644
--- a/include/git2/revwalk.h
+++ b/include/git2/revwalk.h
@@ -87,7 +87,7 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
/**
* Mark a commit to start traversal from.
*
- * The given OID must belong to a commit on the walked
+ * The given OID must belong to a committish on the walked
* repository.
*
* The given commit will be used as one of the roots
@@ -108,7 +108,10 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
* pattern will be pushed to the revision walker.
*
* A leading 'refs/' is implied if not present as well as a trailing
- * '/ *' if the glob lacks '?', '*' or '['.
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
*
* @param walk the walker being used for the traversal
* @param glob the glob pattern references should match
@@ -127,7 +130,7 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
/**
* Mark a commit (and its ancestors) uninteresting for the output.
*
- * The given OID must belong to a commit on the walked
+ * The given OID must belong to a committish on the walked
* repository.
*
* The resolved commit and all its parents will be hidden from the
@@ -147,7 +150,10 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
* revision walk.
*
* A leading 'refs/' is implied if not present as well as a trailing
- * '/ *' if the glob lacks '?', '*' or '['.
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
*
* @param walk the walker being used for the traversal
* @param glob the glob pattern references should match
@@ -166,7 +172,7 @@ GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
/**
* Push the OID pointed to by a reference
*
- * The reference must point to a commit.
+ * The reference must point to a committish.
*
* @param walk the walker being used for the traversal
* @param refname the reference to push
@@ -177,7 +183,7 @@ GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
/**
* Hide the OID pointed to by a reference
*
- * The reference must point to a commit.
+ * The reference must point to a committish.
*
* @param walk the walker being used for the traversal
* @param refname the reference to hide
@@ -255,6 +261,30 @@ GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk);
*/
GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk);
+/**
+ * This is a callback function that user can provide to hide a
+ * commit and its parents. If the callback function returns non-zero value,
+ * then this commit and its parents will be hidden.
+ *
+ * @param commit_id oid of Commit
+ * @param payload User-specified pointer to data to be passed as data payload
+ */
+typedef int(*git_revwalk_hide_cb)(
+ const git_oid *commit_id,
+ void *payload);
+
+/**
+ * Adds a callback function to hide a commit and its parents
+ *
+ * @param walk the revision walker
+ * @param hide_cb callback function to hide a commit and its parents
+ * @param payload data payload to be passed to callback function
+ */
+GIT_EXTERN(int) git_revwalk_add_hide_cb(
+ git_revwalk *walk,
+ git_revwalk_hide_cb hide_cb,
+ void *payload);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/signature.h b/include/git2/signature.h
index 2fa46d032..feb1b4073 100644
--- a/include/git2/signature.h
+++ b/include/git2/signature.h
@@ -68,10 +68,11 @@ GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo)
*
* Call `git_signature_free()` to free the data.
*
- * @param sig signature to duplicated
- * @return a copy of sig, NULL on out of memory
+ * @param dest pointer where to store the copy
+ * @param sig signature to duplicate
+ * @return 0 or an error code
*/
-GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig);
+GIT_EXTERN(int) git_signature_dup(git_signature **dest, const git_signature *sig);
/**
* Free an existing signature.
diff --git a/include/git2/stash.h b/include/git2/stash.h
index b48d33f5d..e2fe2cf0b 100644
--- a/include/git2/stash.h
+++ b/include/git2/stash.h
@@ -62,19 +62,15 @@ GIT_EXTERN(int) git_stash_save(
unsigned int flags);
/**
- * When iterating over all the stashed states, callback that will be
- * issued per entry.
+ * This is a callback function you can provide to iterate over all the
+ * stashed states that will be invoked per entry.
*
* @param index The position within the stash list. 0 points to the
- * most recent stashed state.
- *
+ * 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
+ * @return 0 to continue iterating or non-zero to stop
*/
typedef int (*git_stash_cb)(
size_t index,
@@ -89,12 +85,12 @@ typedef int (*git_stash_cb)(
*
* @param repo Repository where to find the stash.
*
- * @param callback Callback to invoke per found stashed state. The most recent
- * stash state will be enumerated first.
+ * @param callback Callback to invoke per found stashed state. The most
+ * recent stash state will be enumerated first.
*
* @param payload Extra parameter to callback function.
*
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_stash_foreach(
git_repository *repo,
diff --git a/include/git2/status.h b/include/git2/status.h
index 4ec3432df..effe5e1ea 100644
--- a/include/git2/status.h
+++ b/include/git2/status.h
@@ -121,6 +121,11 @@ typedef enum {
* - GIT_STATUS_OPT_NO_REFRESH bypasses the default status behavior of
* doing a "soft" index reload (i.e. reloading the index data if the
* file on disk has been modified outside libgit2).
+ * - GIT_STATUS_OPT_UPDATE_INDEX tells libgit2 to refresh the stat cache
+ * in the index for files that are unchanged but have out of date stat
+ * information in the index. It will result in less work being done on
+ * subsequent calls to get status. This is mutually exclusive with the
+ * NO_REFRESH option.
*
* Calling `git_status_foreach()` is like calling the extended version
* with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
@@ -141,6 +146,7 @@ typedef enum {
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10),
GIT_STATUS_OPT_RENAMES_FROM_REWRITES = (1u << 11),
GIT_STATUS_OPT_NO_REFRESH = (1u << 12),
+ GIT_STATUS_OPT_UPDATE_INDEX = (1u << 13),
} git_status_opt_t;
#define GIT_STATUS_OPT_DEFAULTS \
@@ -175,6 +181,18 @@ typedef struct {
#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION}
/**
+ * Initializes a `git_status_options` with default values. Equivalent to
+ * creating an instance with GIT_STATUS_OPTIONS_INIT.
+ *
+ * @param opts The `git_status_options` instance to initialize.
+ * @param version Version of struct; pass `GIT_STATUS_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_status_init_options(
+ git_status_options *opts,
+ unsigned int version);
+
+/**
* A status entry, providing the differences between the file as it exists
* in HEAD and the index, and providing the differences between the index
* and the working directory.
@@ -203,12 +221,12 @@ typedef struct {
* into this function.
*
* If the callback returns a non-zero value, this function will stop looping
- * and return GIT_EUSER.
+ * and return that value to caller.
*
* @param repo A repository object
* @param callback The function to call on each file
* @param payload Pointer to pass through to callback function
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_status_foreach(
git_repository *repo,
@@ -223,11 +241,16 @@ GIT_EXTERN(int) git_status_foreach(
* in what order. See the `git_status_options` structure for details
* about the additional controls that this makes available.
*
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate. To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
* @param repo Repository object
* @param opts Status options structure
* @param callback The function to call on each file
* @param payload Pointer to pass through to callback function
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_status_foreach_ext(
git_repository *repo,
@@ -238,8 +261,20 @@ GIT_EXTERN(int) git_status_foreach_ext(
/**
* 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.
+ * This tries to get status for the filename that you give. If no files
+ * match that name (in either the HEAD, index, or working directory), this
+ * returns GIT_ENOTFOUND.
+ *
+ * If the name matches multiple files (for example, if the `path` names a
+ * directory or if running on a case- insensitive filesystem and yet the
+ * HEAD has two entries that both match the path), then this returns
+ * GIT_EAMBIGUOUS because it cannot give correct results.
+ *
+ * This does not do any sort of rename detection. Renames require a set of
+ * targets and because of the path filtering, there is not enough
+ * information to check renames correctly. To check file status with rename
+ * detection, there is no choice but to do a full `git_status_list_new` and
+ * scan through looking for the path that you are interested in.
*
* @param status_flags Output combination of git_status_t values for file
* @param repo A repository object
@@ -256,6 +291,11 @@ GIT_EXTERN(int) git_status_file(
/**
* Gather file status information and populate the `git_status_list`.
*
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate. To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
* @param out Pointer to store the status results in
* @param repo Repository object
* @param opts Status options structure
@@ -269,6 +309,9 @@ GIT_EXTERN(int) git_status_list_new(
/**
* Gets the count of status entries in this list.
*
+ * If there are no changes in status (at least according the options given
+ * when the status list was created), this can return 0.
+ *
* @param statuslist Existing status list object
* @return the number of status entries
*/
diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index 186f263f5..864d1c58c 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -97,7 +97,8 @@ typedef enum {
(((S) & GIT_SUBMODULE_STATUS__INDEX_FLAGS) == 0)
#define GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(S) \
- (((S) & GIT_SUBMODULE_STATUS__WD_FLAGS) == 0)
+ (((S) & (GIT_SUBMODULE_STATUS__WD_FLAGS & \
+ ~GIT_SUBMODULE_STATUS_WD_UNINITIALIZED)) == 0)
#define GIT_SUBMODULE_STATUS_IS_WD_DIRTY(S) \
(((S) & (GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED | \
@@ -114,30 +115,36 @@ typedef enum {
*
* - 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
+ * that appears to be a Git repository). In this case, this function
+ * returns GIT_EEXISTS to indicate a sub-repository exists but not in a
* state where a git_submodule can be instantiated.
* - The submodule is not mentioned in the HEAD, index, or config and the
* working directory doesn't contain a value git repo at that path.
* There may or may not be anything else at that path, but nothing that
* looks like a submodule. In this case, this returns GIT_ENOTFOUND.
*
- * 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.
+ * You must call `git_submodule_free` when done with 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.
+ * @param out Output ptr to submodule; pass NULL to just get return code
+ * @param repo The parent repository
+ * @param name The name of or path to the submodule; trailing slashes okay
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
- * GIT_EEXISTS if submodule exists in working directory only, -1 on
- * other errors.
+ * GIT_EEXISTS if a repository is found in working directory only,
+ * -1 on other errors.
*/
GIT_EXTERN(int) git_submodule_lookup(
- git_submodule **submodule,
+ git_submodule **out,
git_repository *repo,
const char *name);
/**
+ * Release a submodule
+ *
+ * @param submodule Submodule object
+ */
+GIT_EXTERN(void) git_submodule_free(git_submodule *submodule);
+
+/**
* Iterate over all tracked submodules of a repository.
*
* See the note on `git_submodule` above. This iterates over the tracked
@@ -174,9 +181,11 @@ GIT_EXTERN(int) git_submodule_foreach(
* `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
+ * You must call `git_submodule_free` on the submodule object when done.
+ *
+ * @param out The newly created submodule ready to open for clone
+ * @param repo The repository in which you want to create the submodule
+ * @param url URL for the submodule's remote
* @param path Path at which the submodule should be created
* @param use_gitlink Should workdir contain a gitlink to the repo in
* .git/modules vs. repo directly in workdir.
@@ -184,7 +193,7 @@ GIT_EXTERN(int) git_submodule_foreach(
* -1 on other errors.
*/
GIT_EXTERN(int) git_submodule_add_setup(
- git_submodule **submodule,
+ git_submodule **out,
git_repository *repo,
const char *url,
const char *path,
@@ -271,6 +280,24 @@ GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule);
GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule);
/**
+ * Resolve a submodule url relative to the given repository.
+ *
+ * @param out buffer to store the absolute submodule url in
+ * @param repo Pointer to repository object
+ * @param url Relative url
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url);
+
+/**
+* Get the branch for the submodule.
+*
+* @param submodule Pointer to submodule object
+* @return Pointer to the submodule branch
+*/
+GIT_EXTERN(const char *) git_submodule_branch(git_submodule *submodule);
+
+/**
* Set the URL for the submodule.
*
* This sets the URL in memory for the submodule. This will be used for
@@ -410,7 +437,7 @@ GIT_EXTERN(git_submodule_update_t) git_submodule_set_update(
*
* @return 0 if fetchRecurseSubmodules is false, 1 if true
*/
-GIT_EXTERN(int) git_submodule_fetch_recurse_submodules(
+GIT_EXTERN(git_submodule_recurse_t) git_submodule_fetch_recurse_submodules(
git_submodule *submodule);
/**
@@ -424,9 +451,9 @@ GIT_EXTERN(int) git_submodule_fetch_recurse_submodules(
* @param fetch_recurse_submodules Boolean value
* @return old value for fetchRecurseSubmodules
*/
-GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
+GIT_EXTERN(git_submodule_recurse_t) git_submodule_set_fetch_recurse_submodules(
git_submodule *submodule,
- int fetch_recurse_submodules);
+ git_submodule_recurse_t fetch_recurse_submodules);
/**
* Copy submodule info into ".git/config" file.
@@ -474,15 +501,23 @@ GIT_EXTERN(int) git_submodule_open(
*
* Call this to reread cached submodule information for this submodule if
* you have reason to believe that it has changed.
+ *
+ * @param submodule The submodule to reload
+ * @param force Force reload even if the data doesn't seem out of date
+ * @return 0 on success, <0 on error
*/
-GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule);
+GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule, int force);
/**
* Reread all submodule info.
*
* Call this to reload all cached submodule information for the repo.
+ *
+ * @param repo The repository to reload submodule data for
+ * @param force Force full reload even if the data doesn't seem out of date
+ * @return 0 on success, <0 on error
*/
-GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo);
+GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo, int force);
/**
* Get the status for a submodule.
diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h
index 34a12fb15..627d3ae2e 100644
--- a/include/git2/sys/commit.h
+++ b/include/git2/sys/commit.h
@@ -21,16 +21,18 @@
GIT_BEGIN_DECL
/**
- * Create new commit in the repository from a list of `git_oid` values
+ * Create new commit in the repository from a list of `git_oid` values.
*
* See documentation for `git_commit_create()` for information about the
* parameters, as the meaning is identical excepting that `tree` and
* `parents` now take `git_oid`. This is a dangerous API in that nor
* the `tree`, neither the `parents` list of `git_oid`s are checked for
* validity.
+ *
+ * @see git_commit_create
*/
-GIT_EXTERN(int) git_commit_create_from_oids(
- git_oid *oid,
+GIT_EXTERN(int) git_commit_create_from_ids(
+ git_oid *id,
git_repository *repo,
const char *update_ref,
const git_signature *author,
@@ -38,9 +40,41 @@ GIT_EXTERN(int) git_commit_create_from_oids(
const char *message_encoding,
const char *message,
const git_oid *tree,
- int parent_count,
+ size_t parent_count,
const git_oid *parents[]);
+/**
+ * Callback function to return parents for commit.
+ *
+ * This is invoked with the count of the number of parents processed so far
+ * along with the user supplied payload. This should return a git_oid of
+ * the next parent or NULL if all parents have been provided.
+ */
+typedef const git_oid *(*git_commit_parent_callback)(size_t idx, void *payload);
+
+/**
+ * Create a new commit in the repository with an callback to supply parents.
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` takes a
+ * `git_oid` and doesn't check for validity, and `parent_cb` is invoked
+ * with `parent_payload` and should return `git_oid` values or NULL to
+ * indicate that all parents are accounted for.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_from_callback(
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_oid *tree,
+ git_commit_parent_callback parent_cb,
+ void *parent_payload);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h
index 419ad7ea7..85e0d6417 100644
--- a/include/git2/sys/config.h
+++ b/include/git2/sys/config.h
@@ -57,19 +57,33 @@ struct git_config_backend {
/* Open means open the file/database and parse if necessary */
int (*open)(struct git_config_backend *, git_config_level_t level);
- int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
+ int (*get)(struct git_config_backend *, const char *key, const git_config_entry **entry);
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 (*del_multivar)(struct git_config_backend *, const char *key, const char *regexp);
int (*iterator)(git_config_iterator **, struct git_config_backend *);
int (*refresh)(struct git_config_backend *);
+ /** Produce a read-only version of this backend */
+ int (*snapshot)(struct git_config_backend **, 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}
/**
+ * Initializes a `git_config_backend` with default values. Equivalent to
+ * creating an instance with GIT_CONFIG_BACKEND_INIT.
+ *
+ * @param opts the `git_config_backend` struct to initialize.
+ * @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_config_init_backend(
+ git_config_backend *backend,
+ unsigned int version);
+
+/**
* Add a generic config file instance to an existing config
*
* Note that the configuration object will free the file
diff --git a/include/git2/sys/diff.h b/include/git2/sys/diff.h
new file mode 100644
index 000000000..48d72f4f9
--- /dev/null
+++ b/include/git2/sys/diff.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_diff_h__
+#define INCLUDE_sys_git_diff_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/diff.h"
+#include "git2/status.h"
+
+/**
+ * @file git2/sys/diff.h
+ * @brief Low-level Git diff utilities
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Diff print callback that writes to a git_buf.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a `git_buf` buffer. You
+ * must pass a `git_buf *` value as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. The data will be appended to the
+ * buffer (after any existing content).
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_buf(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /*< payload must be a `git_buf *` */
+
+/**
+ * Diff print callback that writes to stdio FILE handle.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a stdio FILE handle. You
+ * must pass a `FILE *` value (such as `stdout` or `stderr` or the return
+ * value from `fopen()`) as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. If you pass NULL, this will write
+ * data to `stdout`.
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /*< payload must be a `FILE *` */
+
+
+typedef struct {
+ unsigned int version;
+ size_t stat_calls;
+ size_t oid_calculations;
+} git_diff_perfdata;
+
+#define GIT_DIFF_PERFDATA_VERSION 1
+#define GIT_DIFF_PERFDATA_INIT {GIT_DIFF_PERFDATA_VERSION,0,0}
+
+/**
+ * Get performance data for a diff object.
+ *
+ * @param out Structure to be filled with diff performance data
+ * @param diff Diff to read performance data from
+ * @return 0 for success, <0 for error
+ */
+GIT_EXTERN(int) git_diff_get_perfdata(
+ git_diff_perfdata *out, const git_diff *diff);
+
+/**
+ * Get performance data for diffs from a git_status_list
+ */
+GIT_EXTERN(int) git_status_list_get_perfdata(
+ git_diff_perfdata *out, const git_status_list *status);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h
index 94ad3aed4..60248271a 100644
--- a/include/git2/sys/filter.h
+++ b/include/git2/sys/filter.h
@@ -55,7 +55,10 @@ GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
* your own chains of filters.
*/
GIT_EXTERN(int) git_filter_list_new(
- git_filter_list **out, git_repository *repo, git_filter_mode_t mode);
+ git_filter_list **out,
+ git_repository *repo,
+ git_filter_mode_t mode,
+ uint32_t options);
/**
* Add a filter to a filter list with the given payload.
@@ -115,10 +118,15 @@ GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
/**
- * Get the git_filter_mode_t to be applied
+ * Get the git_filter_mode_t to be used
*/
GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
+/**
+ * Get the combination git_filter_opt_t options to be applied
+ */
+GIT_EXTERN(uint32_t) git_filter_source_options(const git_filter_source *src);
+
/*
* struct git_filter
*
@@ -149,6 +157,7 @@ typedef int (*git_filter_init_fn)(git_filter *self);
* Specified as `filter.shutdown`, this is an optional callback invoked
* when the filter is unregistered or when libgit2 is shutting down. It
* will be called once at most and should release resources as needed.
+ * This may be called even if the `initialize` callback was not made.
*
* Typically this function will free the `git_filter` object itself.
*/
diff --git a/include/git2/sys/mempack.h b/include/git2/sys/mempack.h
new file mode 100644
index 000000000..d3bc87b4d
--- /dev/null
+++ b/include/git2/sys/mempack.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_odb_mempack_h__
+#define INCLUDE_sys_git_odb_mempack_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+/**
+ * @file git2/sys/mempack.h
+ * @brief Custom ODB backend that permits packing objects in-memory
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Instantiate a new mempack backend.
+ *
+ * The backend must be added to an existing ODB with the highest
+ * priority.
+ *
+ * git_mempack_new(&mempacker);
+ * git_repository_odb(&odb, repository);
+ * git_odb_add_backend(odb, mempacker, 999);
+ *
+ * Once the backend has been loaded, all writes to the ODB will
+ * instead be queued in memory, and can be finalized with
+ * `git_mempack_dump`.
+ *
+ * Subsequent reads will also be served from the in-memory store
+ * to ensure consistency, until the memory store is dumped.
+ *
+ * @param out Poiter where to store the ODB backend
+ * @return 0 on success; error code otherwise
+ */
+int git_mempack_new(git_odb_backend **out);
+
+/**
+ * Dump all the queued in-memory writes to a packfile.
+ *
+ * The contents of the packfile will be stored in the given buffer.
+ * It is the caller's responsability to ensure that the generated
+ * packfile is available to the repository (e.g. by writing it
+ * to disk, or doing something crazy like distributing it across
+ * several copies of the repository over a network).
+ *
+ * Once the generated packfile is available to the repository,
+ * call `git_mempack_reset` to cleanup the memory store.
+ *
+ * Calling `git_mempack_reset` before the packfile has been
+ * written to disk will result in an inconsistent repository
+ * (the objects in the memory store won't be accessible).
+ *
+ * @param pack Buffer where to store the raw packfile
+ * @param repo The active repository where the backend is loaded
+ * @param backend The mempack backend
+ * @return 0 on success; error code otherwise
+ */
+int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backend);
+
+/**
+ * Reset the memory packer by clearing all the queued objects.
+ *
+ * This assumes that `git_mempack_dump` has been called before to
+ * store all the queued objects into a single packfile.
+ *
+ * Alternatively, call `reset` without a previous dump to "undo"
+ * all the recently written objects, giving transaction-like
+ * semantics to the Git repository.
+ *
+ * @param backend The mempack backend
+ */
+void git_mempack_reset(git_odb_backend *backend);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h
index 8039a5b82..1fc3c3159 100644
--- a/include/git2/sys/odb_backend.h
+++ b/include/git2/sys/odb_backend.h
@@ -35,11 +35,8 @@ struct git_odb_backend {
int (* read)(
void **, size_t *, git_otype *, git_odb_backend *, const git_oid *);
- /* To find a unique object given a prefix
- * of its oid.
- * The oid given must be so that the
- * remaining (GIT_OID_HEXSZ - len)*4 bits
- * are 0s.
+ /* To find a unique object given a prefix of its oid. The oid given
+ * must be so that the remaining (GIT_OID_HEXSZ - len)*4 bits are 0s.
*/
int (* read_prefix)(
git_oid *, void **, size_t *, git_otype *,
@@ -64,6 +61,9 @@ struct git_odb_backend {
int (* exists)(
git_odb_backend *, const git_oid *);
+ int (* exists_prefix)(
+ git_oid *, git_odb_backend *, const git_oid *, size_t);
+
/**
* If the backend implements a refreshing mechanism, it should be exposed
* through this endpoint. Each call to `git_odb_refresh()` will invoke it.
@@ -81,7 +81,7 @@ struct git_odb_backend {
int (* writepack)(
git_odb_writepack **, git_odb_backend *, git_odb *odb,
- git_transfer_progress_callback progress_cb, void *progress_payload);
+ git_transfer_progress_cb progress_cb, void *progress_payload);
void (* free)(git_odb_backend *);
};
@@ -89,6 +89,18 @@ struct git_odb_backend {
#define GIT_ODB_BACKEND_VERSION 1
#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+/**
+ * Initializes a `git_odb_backend` with default values. Equivalent to
+ * creating an instance with GIT_ODB_BACKEND_INIT.
+ *
+ * @param opts the `git_odb_backend` struct to initialize.
+ * @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_odb_init_backend(
+ git_odb_backend *backend,
+ unsigned int version);
+
GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
GIT_END_DECL
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
index 9cf5073fb..3b216a287 100644
--- a/include/git2/sys/refdb_backend.h
+++ b/include/git2/sys/refdb_backend.h
@@ -93,17 +93,20 @@ struct git_refdb_backend {
* must provide this function.
*/
int (*write)(git_refdb_backend *backend,
- const git_reference *ref, int force);
+ const git_reference *ref, int force,
+ const git_signature *who, const char *message,
+ const git_oid *old, const char *old_target);
int (*rename)(
git_reference **out, git_refdb_backend *backend,
- const char *old_name, const char *new_name, int force);
+ const char *old_name, const char *new_name, int force,
+ const git_signature *who, const char *message);
/**
* Deletes the given reference from the refdb. A refdb implementation
* must provide this function.
*/
- int (*del)(git_refdb_backend *backend, const char *ref_name);
+ int (*del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
/**
* Suggests that the given refdb compress or optimize its references.
@@ -115,6 +118,17 @@ struct git_refdb_backend {
int (*compress)(git_refdb_backend *backend);
/**
+ * Query whether a particular reference has a log (may be empty)
+ */
+ int (*has_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
+ * Make sure a particular reference will have a reflog which
+ * will be appended to on writes.
+ */
+ int (*ensure_log)(git_refdb_backend *backend, const char *refname);
+
+ /**
* Frees any resources held by the refdb. A refdb implementation may
* provide this function; if it is not provided, nothing will be done.
*/
@@ -145,6 +159,18 @@ struct git_refdb_backend {
#define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
/**
+ * Initializes a `git_refdb_backend` with default values. Equivalent to
+ * creating an instance with GIT_REFDB_BACKEND_INIT.
+ *
+ * @param opts the `git_refdb_backend` struct to initialize
+ * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_refdb_init_backend(
+ git_refdb_backend *backend,
+ unsigned int version);
+
+/**
* Constructors for default filesystem-based refdb backend
*
* Under normal usage, this is called for you when the repository is
diff --git a/include/git2/transport.h b/include/git2/transport.h
index caabd0465..af7812b5d 100644
--- a/include/git2/transport.h
+++ b/include/git2/transport.h
@@ -41,6 +41,9 @@ typedef enum {
/* git_cred_default */
GIT_CREDTYPE_DEFAULT = (1u << 3),
+
+ /* git_cred_ssh_interactive */
+ GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
} git_credtype_t;
/* The base structure for all credential types */
@@ -60,8 +63,10 @@ typedef struct {
#ifdef GIT_SSH
typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));
+typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback));
#else
typedef int (*git_cred_sign_callback)(void *, ...);
+typedef int (*git_cred_ssh_interactive_callback)(void *, ...);
#endif
/**
@@ -76,6 +81,16 @@ typedef struct git_cred_ssh_key {
} git_cred_ssh_key;
/**
+ * Keyboard-interactive based ssh authentication
+ */
+typedef struct git_cred_ssh_interactive {
+ git_cred parent;
+ char *username;
+ git_cred_ssh_interactive_callback prompt_callback;
+ void *payload;
+} git_cred_ssh_interactive;
+
+/**
* A key with a custom signature function
*/
typedef struct git_cred_ssh_custom {
@@ -83,8 +98,8 @@ typedef struct git_cred_ssh_custom {
char *username;
char *publickey;
size_t publickey_len;
- void *sign_callback;
- void *sign_data;
+ git_cred_sign_callback sign_callback;
+ void *payload;
} git_cred_ssh_custom;
/** A key for NTLM/Kerberos "default" credentials */
@@ -131,6 +146,33 @@ GIT_EXTERN(int) git_cred_ssh_key_new(
const char *passphrase);
/**
+ * Create a new ssh keyboard-interactive based credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param username Username to use to authenticate.
+ * @param prompt_callback The callback method used for prompts.
+ * @param payload Additional data to pass to the callback.
+ * @return 0 for success or an error code for failure.
+ */
+GIT_EXTERN(int) git_cred_ssh_interactive_new(
+ git_cred **out,
+ const char *username,
+ git_cred_ssh_interactive_callback prompt_callback,
+ void *payload);
+
+/**
+ * Create a new ssh key credential object used for querying an ssh-agent.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_ssh_key_from_agent(
+ git_cred **out,
+ const char *username);
+
+/**
* Create an ssh key credential with a custom signing function.
*
* This lets you use your own function to sign the challenge.
@@ -144,8 +186,8 @@ GIT_EXTERN(int) git_cred_ssh_key_new(
* @param username username to use to authenticate
* @param publickey The bytes of the public key.
* @param publickey_len The length of the public key in bytes.
- * @param sign_fn The callback method to sign the data during the challenge.
- * @param sign_data The data to pass to the sign function.
+ * @param sign_callback The callback method to sign the data during the challenge.
+ * @param payload Additional data to pass to the callback.
* @return 0 for success or an error code for failure
*/
GIT_EXTERN(int) git_cred_ssh_custom_new(
@@ -153,8 +195,8 @@ GIT_EXTERN(int) git_cred_ssh_custom_new(
const char *username,
const char *publickey,
size_t publickey_len,
- git_cred_sign_callback sign_fn,
- void *sign_data);
+ git_cred_sign_callback sign_callback,
+ void *payload);
/**
* Create a "default" credential usable for Negotiate mechanisms like NTLM
@@ -173,7 +215,8 @@ GIT_EXTERN(int) git_cred_default_new(git_cred **out);
* remote url, or NULL if not included.
* - allowed_types: A bitmask stating which cred types are OK to return.
* - payload: The payload provided when specifying this callback.
- * - returns 0 for success or non-zero to indicate an error
+ * - returns 0 for success, < 0 to indicate an error, > 0 to indicate
+ * no credential was acquired
*/
typedef int (*git_cred_acquire_cb)(
git_cred **cred,
@@ -244,7 +287,7 @@ struct git_transport {
git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
- git_transfer_progress_callback progress_cb,
+ git_transfer_progress_cb progress_cb,
void *progress_payload);
/* Checks to see if the transport is connected */
@@ -268,6 +311,18 @@ struct git_transport {
#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
/**
+ * Initializes a `git_transport` with default values. Equivalent to
+ * creating an instance with GIT_TRANSPORT_INIT.
+ *
+ * @param opts the `git_transport` struct to initialize
+ * @param version Version of struct; pass `GIT_TRANSPORT_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_transport_init(
+ git_transport *opts,
+ unsigned int version);
+
+/**
* Function to use to create a transport from a URL. The transport database
* is scanned to find a transport that implements the scheme of the URI (i.e.
* git:// or http://) and a transport object is returned to the caller.
diff --git a/include/git2/tree.h b/include/git2/tree.h
index d94b446c2..56922d40b 100644
--- a/include/git2/tree.h
+++ b/include/git2/tree.h
@@ -121,11 +121,11 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
* 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
+ * @param id 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);
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byid(
+ const git_tree *tree, const git_oid *id);
/**
* Retrieve a tree entry contained in a tree or in any of its subtrees,
@@ -150,10 +150,11 @@ GIT_EXTERN(int) git_tree_entry_bypath(
* 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)
+ * @param dest pointer where to store the copy
+ * @param source tree entry to duplicate
+ * @return 0 or an error code
*/
-GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry);
+GIT_EXTERN(int) git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source);
/**
* Free a user-owned tree entry
@@ -332,11 +333,18 @@ GIT_EXTERN(int) git_treebuilder_insert(
GIT_EXTERN(int) git_treebuilder_remove(
git_treebuilder *bld, const char *filename);
+/**
+ * Callback for git_treebuilder_filter
+ *
+ * The return value is treated as a boolean, with zero indicating that the
+ * entry should be left alone and any non-zero value meaning that the
+ * entry should be removed from the treebuilder list (i.e. filtered out).
+ */
typedef int (*git_treebuilder_filter_cb)(
const git_tree_entry *entry, void *payload);
/**
- * Filter the entries in the tree
+ * Selectively remove entries in the tree
*
* The `filter` callback will be called for each entry in the tree with a
* pointer to the entry and the provided `payload`; if the callback returns
@@ -344,7 +352,7 @@ typedef int (*git_treebuilder_filter_cb)(
*
* @param bld Tree builder
* @param filter Callback to filter entries
- * @param payload Extra data to pass to filter
+ * @param payload Extra data to pass to filter callback
*/
GIT_EXTERN(void) git_treebuilder_filter(
git_treebuilder *bld,
diff --git a/include/git2/types.h b/include/git2/types.h
index 55505b110..6295ebbfa 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -131,7 +131,7 @@ typedef struct git_treebuilder git_treebuilder;
/** Memory representation of an index file. */
typedef struct git_index git_index;
-/** An interator for conflicts in the index. */
+/** An iterator for conflicts in the index. */
typedef struct git_index_conflict_iterator git_index_conflict_iterator;
/** Memory representation of a set of config files */
@@ -154,15 +154,15 @@ typedef struct git_packbuilder git_packbuilder;
/** Time in a signature */
typedef struct git_time {
- git_time_t time; /** time in seconds from epoch */
- int offset; /** timezone offset, in minutes */
+ git_time_t time; /**< time in seconds from epoch */
+ int offset; /**< timezone offset, in minutes */
} git_time;
/** An action signature (e.g. for committers, taggers, etc) */
typedef struct git_signature {
- char *name; /** full name of the author */
- char *email; /** email of the author */
- git_time when; /** time when the action happened */
+ char *name; /**< full name of the author */
+ char *email; /**< email of the author */
+ git_time when; /**< time when the action happened */
} git_signature;
/** In-memory representation of a reference. */
@@ -183,9 +183,9 @@ typedef struct git_status_list git_status_list;
/** Basic type of any Git reference. */
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_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_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
} git_ref_t;
@@ -193,6 +193,7 @@ typedef enum {
typedef enum {
GIT_BRANCH_LOCAL = 1,
GIT_BRANCH_REMOTE = 2,
+ GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE,
} git_branch_t;
/** Valid modes for index and tree entries. */
@@ -240,7 +241,7 @@ typedef struct git_transfer_progress {
* @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 int (*git_transfer_progress_cb)(const git_transfer_progress *stats, void *payload);
/**
* Opaque structure representing a submodule.
@@ -313,16 +314,35 @@ typedef enum {
* when we don't want any particular ignore rule to be specified.
*/
typedef enum {
- GIT_SUBMODULE_IGNORE_RESET = -1, /* reset to on-disk value */
+ GIT_SUBMODULE_IGNORE_RESET = -1, /**< reset to on-disk value */
- GIT_SUBMODULE_IGNORE_NONE = 1, /* any change or untracked == dirty */
- GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
- GIT_SUBMODULE_IGNORE_DIRTY = 3, /* only dirty if HEAD moved */
- GIT_SUBMODULE_IGNORE_ALL = 4, /* never dirty */
+ GIT_SUBMODULE_IGNORE_NONE = 1, /**< any change or untracked == dirty */
+ GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /**< dirty if tracked files change */
+ GIT_SUBMODULE_IGNORE_DIRTY = 3, /**< only dirty if HEAD moved */
+ GIT_SUBMODULE_IGNORE_ALL = 4, /**< never dirty */
GIT_SUBMODULE_IGNORE_DEFAULT = 0
} git_submodule_ignore_t;
+/**
+ * Options for submodule recurse.
+ *
+ * Represent the value of `submodule.$name.fetchRecurseSubmodules`
+ *
+ * * GIT_SUBMODULE_RECURSE_RESET - reset to the on-disk value
+ * * GIT_SUBMODULE_RECURSE_NO - do no recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_YES - recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_ONDEMAND - recurse into submodules only when
+ * commit not already in local clone
+ */
+typedef enum {
+ GIT_SUBMODULE_RECURSE_RESET = -1,
+
+ GIT_SUBMODULE_RECURSE_NO = 0,
+ GIT_SUBMODULE_RECURSE_YES = 1,
+ GIT_SUBMODULE_RECURSE_ONDEMAND = 2,
+} git_submodule_recurse_t;
+
/** @} */
GIT_END_DECL
diff --git a/include/git2/version.h b/include/git2/version.h
index c4c5e8eb1..5bda42735 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -7,9 +7,11 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.20.0"
+#define LIBGIT2_VERSION "0.21.0"
#define LIBGIT2_VER_MAJOR 0
-#define LIBGIT2_VER_MINOR 20
+#define LIBGIT2_VER_MINOR 21
#define LIBGIT2_VER_REVISION 0
+#define LIBGIT2_SOVERSION 21
+
#endif