summaryrefslogtreecommitdiff
path: root/include/git2
diff options
context:
space:
mode:
Diffstat (limited to 'include/git2')
-rw-r--r--include/git2/blame.h198
-rw-r--r--include/git2/blob.h32
-rw-r--r--include/git2/branch.h40
-rw-r--r--include/git2/buffer.h112
-rw-r--r--include/git2/checkout.h27
-rw-r--r--include/git2/clone.h62
-rw-r--r--include/git2/commit.h35
-rw-r--r--include/git2/common.h19
-rw-r--r--include/git2/config.h85
-rw-r--r--include/git2/cred_helpers.h2
-rw-r--r--include/git2/diff.h794
-rw-r--r--include/git2/errors.h19
-rw-r--r--include/git2/filter.h142
-rw-r--r--include/git2/index.h38
-rw-r--r--include/git2/indexer.h22
-rw-r--r--include/git2/merge.h76
-rw-r--r--include/git2/notes.h4
-rw-r--r--include/git2/object.h19
-rw-r--r--include/git2/odb.h74
-rw-r--r--include/git2/odb_backend.h56
-rw-r--r--include/git2/oid.h7
-rw-r--r--include/git2/pack.h48
-rw-r--r--include/git2/patch.h250
-rw-r--r--include/git2/pathspec.h260
-rw-r--r--include/git2/push.h31
-rw-r--r--include/git2/reflog.h36
-rw-r--r--include/git2/refs.h31
-rw-r--r--include/git2/remote.h175
-rw-r--r--include/git2/repository.h22
-rw-r--r--include/git2/revparse.h43
-rw-r--r--include/git2/revwalk.h8
-rw-r--r--include/git2/signature.h13
-rw-r--r--include/git2/stash.h2
-rw-r--r--include/git2/status.h32
-rw-r--r--include/git2/submodule.h110
-rw-r--r--include/git2/sys/config.h31
-rw-r--r--include/git2/sys/filter.h292
-rw-r--r--include/git2/sys/index.h2
-rw-r--r--include/git2/sys/odb_backend.h20
-rw-r--r--include/git2/sys/refdb_backend.h26
-rw-r--r--include/git2/sys/reflog.h21
-rw-r--r--include/git2/sys/refs.h4
-rw-r--r--include/git2/sys/repository.h20
-rw-r--r--include/git2/transport.h230
-rw-r--r--include/git2/tree.h13
-rw-r--r--include/git2/types.h94
-rw-r--r--include/git2/version.h4
47 files changed, 2833 insertions, 848 deletions
diff --git a/include/git2/blame.h b/include/git2/blame.h
new file mode 100644
index 000000000..73bcc5bc6
--- /dev/null
+++ b/include/git2/blame.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_git_blame_h__
+#define INCLUDE_git_blame_h__
+
+#include "common.h"
+#include "oid.h"
+
+/**
+ * @file git2/blame.h
+ * @brief Git blame routines
+ * @defgroup git_blame Git blame routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags for indicating option behavior for git_blame APIs.
+ */
+typedef enum {
+ /** Normal blame, the default */
+ GIT_BLAME_NORMAL = 0,
+ /** Track lines that have moved within a file (like `git blame -M`).
+ * NOT IMPLEMENTED. */
+ GIT_BLAME_TRACK_COPIES_SAME_FILE = (1<<0),
+ /** Track lines that have moved across files in the same commit (like `git blame -C`).
+ * NOT IMPLEMENTED. */
+ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES = (1<<1),
+ /** Track lines that have been copied from another file that exists in the
+ * same commit (like `git blame -CC`). Implies SAME_FILE.
+ * NOT IMPLEMENTED. */
+ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES = (1<<2),
+ /** Track lines that have been copied from another file that exists in *any*
+ * commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES.
+ * NOT IMPLEMENTED. */
+ GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3),
+} git_blame_flag_t;
+
+/**
+ * Blame options structure
+ *
+ * Use zeros to indicate default settings. It's easiest to use the
+ * `GIT_BLAME_OPTIONS_INIT` macro:
+ * git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+ *
+ * - `flags` is a combination of the `git_blame_flag_t` values above.
+ * - `min_match_characters` is the lower bound on the number of alphanumeric
+ * characters that must be detected as moving/copying within a file for it to
+ * associate those lines with the parent commit. The default value is 20.
+ * This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*`
+ * flags are specified.
+ * - `newest_commit` is the id of the newest commit to consider. The default
+ * is HEAD.
+ * - `oldest_commit` is the id of the oldest commit to consider. The default
+ * is the first commit encountered with a NULL parent.
+ * - `min_line` is the first line in the file to blame. The default is 1 (line
+ * numbers start with 1).
+ * - `max_line` is the last line in the file to blame. The default is the last
+ * line of the file.
+ */
+
+typedef struct git_blame_options {
+ unsigned int version;
+
+ uint32_t flags;
+ uint16_t min_match_characters;
+ git_oid newest_commit;
+ git_oid oldest_commit;
+ uint32_t min_line;
+ uint32_t max_line;
+} git_blame_options;
+
+#define GIT_BLAME_OPTIONS_VERSION 1
+#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
+
+/**
+ * Structure that represents a blame hunk.
+ *
+ * - `lines_in_hunk` is the number of lines in this hunk
+ * - `final_commit_id` is the OID of the commit where this line was last
+ * changed.
+ * - `final_start_line_number` is the 1-based line number where this hunk
+ * begins, in the final version of the file
+ * - `orig_commit_id` is the OID of the commit where this hunk was found. This
+ * will usually be the same as `final_commit_id`, except when
+ * `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified.
+ * - `orig_path` is the path to the file where this hunk originated, as of the
+ * commit specified by `orig_commit_id`.
+ * - `orig_start_line_number` is the 1-based line number where this hunk begins
+ * in the file named by `orig_path` in the commit specified by
+ * `orig_commit_id`.
+ * - `boundary` is 1 iff the hunk has been tracked to a boundary commit (the
+ * root, or the commit specified in git_blame_options.oldest_commit)
+ */
+typedef struct git_blame_hunk {
+ uint16_t lines_in_hunk;
+
+ git_oid final_commit_id;
+ uint16_t final_start_line_number;
+ git_signature *final_signature;
+
+ git_oid orig_commit_id;
+ const char *orig_path;
+ uint16_t orig_start_line_number;
+ git_signature *orig_signature;
+
+ char boundary;
+} git_blame_hunk;
+
+
+/* Opaque structure to hold blame results */
+typedef struct git_blame git_blame;
+
+/**
+ * Gets the number of hunks that exist in the blame structure.
+ */
+GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame);
+
+/**
+ * Gets the blame hunk at the given index.
+ *
+ * @param blame the blame structure to query
+ * @param index index of the hunk to retrieve
+ * @return the hunk at the given index, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex(
+ git_blame *blame,
+ uint32_t index);
+
+/**
+ * Gets the hunk that relates to the given line number in the newest commit.
+ *
+ * @param blame the blame structure to query
+ * @param lineno the (1-based) line number to find a hunk for
+ * @return the hunk that contains the given line, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byline(
+ git_blame *blame,
+ uint32_t lineno);
+
+/**
+ * Get the blame for a single file.
+ *
+ * @param out pointer that will receive the blame object
+ * @param repo repository whose history is to be walked
+ * @param path path to file to consider
+ * @param options options for the blame operation. If NULL, this is treated as
+ * though GIT_BLAME_OPTIONS_INIT were passed.
+ * @return 0 on success, or an error code. (use giterr_last for information
+ * about the error.)
+ */
+GIT_EXTERN(int) git_blame_file(
+ git_blame **out,
+ git_repository *repo,
+ const char *path,
+ git_blame_options *options);
+
+
+/**
+ * Get blame data for a file that has been modified in memory. The `reference`
+ * parameter is a pre-calculated blame for the in-odb history of the file. This
+ * means that once a file blame is completed (which can be expensive), updating
+ * the buffer blame is very fast.
+ *
+ * Lines that differ between the buffer and the committed version are marked as
+ * having a zero OID for their final_commit_id.
+ *
+ * @param out pointer that will receive the resulting blame data
+ * @param reference cached blame from the history of the file (usually the output
+ * from git_blame_file)
+ * @param buffer the (possibly) modified contents of the file
+ * @param buffer_len number of valid bytes in the buffer
+ * @return 0 on success, or an error code. (use giterr_last for information
+ * about the error)
+ */
+GIT_EXTERN(int) git_blame_buffer(
+ git_blame **out,
+ git_blame *reference,
+ const char *buffer,
+ uint32_t buffer_len);
+
+/**
+ * Free memory allocated by git_blame_file or git_blame_buffer.
+ *
+ * @param blame the blame structure to free
+ */
+GIT_EXTERN(void) git_blame_free(git_blame *blame);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/include/git2/blob.h b/include/git2/blob.h
index 8fca48966..dcab4fbe0 100644
--- a/include/git2/blob.h
+++ b/include/git2/blob.h
@@ -11,6 +11,7 @@
#include "types.h"
#include "oid.h"
#include "object.h"
+#include "buffer.h"
/**
* @file git2/blob.h
@@ -96,6 +97,37 @@ GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob);
/**
+ * Get a buffer with the filtered content of a blob.
+ *
+ * This applies filters as if the blob was being checked out to the
+ * working directory under the specified filename. This may apply
+ * CRLF filtering or other types of changes depending on the file
+ * attributes set for the blob and the content detected in it.
+ *
+ * The output is written into a `git_buf` which the caller must free
+ * when done (via `git_buf_free`).
+ *
+ * If no filters need to be applied, then the `out` buffer will just be
+ * populated with a pointer to the raw content of the blob. In that case,
+ * be careful to *not* free the blob until done with the buffer. To keep
+ * the data detached from the blob, call `git_buf_grow` on the buffer
+ * with a `want_size` of 0 and the buffer will be reallocated to be
+ * detached from the blob.
+ *
+ * @param out The git_buf to be filled in
+ * @param blob Pointer to the blob
+ * @param as_path Path used for file attribute lookups, etc.
+ * @param check_for_binary_data Should this test if blob content contains
+ * NUL bytes / looks like binary data before applying filters?
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_blob_filtered_content(
+ git_buf *out,
+ git_blob *blob,
+ const char *as_path,
+ int check_for_binary_data);
+
+/**
* Read a file from the working folder of a repository
* and write it to the Object Database as a loose blob
*
diff --git a/include/git2/branch.h b/include/git2/branch.h
index de414e9b0..44d6fd9c3 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -66,33 +66,41 @@ GIT_EXTERN(int) git_branch_create(
*/
GIT_EXTERN(int) git_branch_delete(git_reference *branch);
-typedef int (*git_branch_foreach_cb)(
- const char *branch_name,
- git_branch_t branch_type,
- void *payload);
+/** Iterator type for branches */
+typedef struct git_branch_iterator git_branch_iterator;
/**
- * Loop over all the branches and issue a callback for each one.
- *
- * If the callback returns a non-zero value, this will stop looping.
+ * Create an iterator which loops over the requested branches.
*
+ * @param out the iterator
* @param repo Repository where to find the branches.
- *
* @param list_flags Filtering flags for the branch
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
* or a combination of the two.
*
- * @param branch_cb Callback to invoke per found branch.
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_branch_iterator_new(
+ git_branch_iterator **out,
+ git_repository *repo,
+ git_branch_t list_flags);
+
+/**
+ * Retrieve the next branch from the iterator
*
- * @param payload Extra parameter to callback function.
+ * @param out the reference
+ * @param out_type the type of branch (local or remote-tracking)
+ * @param iter the branch iterator
+ * @return 0 on success, GIT_ITEROVER if there are no more branches or an error code.
+ */
+GIT_EXTERN(int) git_branch_next(git_reference **out, git_branch_t *out_type, git_branch_iterator *iter);
+
+/**
+ * Free a branch iterator
*
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @param iter the iterator to free
*/
-GIT_EXTERN(int) git_branch_foreach(
- git_repository *repo,
- unsigned int list_flags,
- git_branch_foreach_cb branch_cb,
- void *payload);
+GIT_EXTERN(void) git_branch_iterator_free(git_branch_iterator *iter);
/**
* Move/rename an existing local branch reference.
diff --git a/include/git2/buffer.h b/include/git2/buffer.h
new file mode 100644
index 000000000..36a61e6c9
--- /dev/null
+++ b/include/git2/buffer.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_buf_h__
+#define INCLUDE_git_buf_h__
+
+#include "common.h"
+
+/**
+ * @file git2/buffer.h
+ * @brief Buffer export structure
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * A data buffer for exporting data from libgit2
+ *
+ * Sometimes libgit2 wants to return an allocated data buffer to the
+ * caller and have the caller take responsibility for freeing that memory.
+ * This can be awkward if the caller does not have easy access to the same
+ * allocation functions that libgit2 is using. In those cases, libgit2
+ * will fill in a `git_buf` and the caller can use `git_buf_free()` to
+ * release it when they are done.
+ *
+ * A `git_buf` may also be used for the caller to pass in a reference to
+ * a block of memory they hold. In this case, libgit2 will not resize or
+ * free the memory, but will read from it as needed.
+ *
+ * A `git_buf` is a public structure with three fields:
+ *
+ * - `ptr` points to the start of the allocated memory. If it is NULL,
+ * then the `git_buf` is considered empty and libgit2 will feel free
+ * to overwrite it with new data.
+ *
+ * - `size` holds the size (in bytes) of the data that is actually used.
+ *
+ * - `asize` holds the known total amount of allocated memory if the `ptr`
+ * was allocated by libgit2. It may be larger than `size`. If `ptr`
+ * was not allocated by libgit2 and should not be resized and/or freed,
+ * then `asize` will be set to zero.
+ *
+ * Some APIs may occasionally do something slightly unusual with a buffer,
+ * such as setting `ptr` to a value that was passed in by the user. In
+ * those cases, the behavior will be clearly documented by the API.
+ */
+typedef struct {
+ char *ptr;
+ size_t asize, size;
+} git_buf;
+
+/**
+ * Static initializer for git_buf from static buffer
+ */
+#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) }
+
+/**
+ * Free the memory referred to by the git_buf.
+ *
+ * Note that this does not free the `git_buf` itself, just the memory
+ * pointed to by `buffer->ptr`. This will not free the memory if it looks
+ * like it was not allocated internally, but it will clear the buffer back
+ * to the empty state.
+ *
+ * @param buffer The buffer to deallocate
+ */
+GIT_EXTERN(void) git_buf_free(git_buf *buffer);
+
+/**
+ * Resize the buffer allocation to make more space.
+ *
+ * This will attempt to grow the buffer to accomodate the target size.
+ *
+ * If the buffer refers to memory that was not allocated by libgit2 (i.e.
+ * the `asize` field is zero), then `ptr` will be replaced with a newly
+ * allocated block of data. Be careful so that memory allocated by the
+ * caller is not lost. As a special variant, if you pass `target_size` as
+ * 0 and the memory is not allocated by libgit2, this will allocate a new
+ * buffer of size `size` and copy the external data into it.
+ *
+ * Currently, this will never shrink a buffer, only expand it.
+ *
+ * If the allocation fails, this will return an error and the buffer will be
+ * marked as invalid for future operations, invaliding the contents.
+ *
+ * @param buffer The buffer to be resized; may or may not be allocated yet
+ * @param target_size The desired available size
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size);
+
+/**
+ * Set buffer to a copy of some raw data.
+ *
+ * @param buffer The buffer to set
+ * @param data The data to copy into the buffer
+ * @param datalen The length of the data to copy into the buffer
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_set(
+ git_buf *buffer, const void *data, size_t datalen);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
index a086408c7..efafdc3e4 100644
--- a/include/git2/checkout.h
+++ b/include/git2/checkout.h
@@ -131,6 +131,13 @@ typedef enum {
/** Don't refresh index/config/etc before doing checkout */
GIT_CHECKOUT_NO_REFRESH = (1u << 9),
+ /** Allow checkout to skip unmerged files */
+ GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
+ /** For unmerged files, checkout stage 2 from index */
+ GIT_CHECKOUT_USE_OURS = (1u << 11),
+ /** For unmerged files, checkout stage 3 from index */
+ GIT_CHECKOUT_USE_THEIRS = (1u << 12),
+
/** Treat pathspec as simple list of exact match file paths */
GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
@@ -141,13 +148,6 @@ typedef enum {
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
*/
- /** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */
- GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
- /** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */
- GIT_CHECKOUT_USE_OURS = (1u << 11),
- /** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */
- GIT_CHECKOUT_USE_THEIRS = (1u << 12),
-
/** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
/** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
@@ -238,6 +238,9 @@ typedef struct git_checkout_opts {
git_tree *baseline; /** expected content of workdir, defaults to HEAD */
const char *target_directory; /** alternative checkout path to workdir */
+
+ 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;
#define GIT_CHECKOUT_OPTS_VERSION 1
@@ -249,13 +252,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_EORPHANEDHEAD when HEAD points to a non existing
+ * @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)
*/
GIT_EXTERN(int) git_checkout_head(
git_repository *repo,
- git_checkout_opts *opts);
+ const git_checkout_opts *opts);
/**
* Updates files in the working tree to match the content of the index.
@@ -269,7 +272,7 @@ GIT_EXTERN(int) git_checkout_head(
GIT_EXTERN(int) git_checkout_index(
git_repository *repo,
git_index *index,
- git_checkout_opts *opts);
+ const git_checkout_opts *opts);
/**
* Updates files in the index and working tree to match the content of the
@@ -277,7 +280,7 @@ GIT_EXTERN(int) git_checkout_index(
*
* @param repo repository to check out (must be non-bare)
* @param treeish a commit, tag or tree which content will be used to update
- * the working directory
+ * 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)
@@ -285,7 +288,7 @@ GIT_EXTERN(int) git_checkout_index(
GIT_EXTERN(int) git_checkout_tree(
git_repository *repo,
const git_object *treeish,
- git_checkout_opts *opts);
+ const git_checkout_opts *opts);
/** @} */
GIT_END_DECL
diff --git a/include/git2/clone.h b/include/git2/clone.h
index 5858b4e32..331cf92e7 100644
--- a/include/git2/clone.h
+++ b/include/git2/clone.h
@@ -35,30 +35,12 @@ GIT_BEGIN_DECL
* set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT.
* - `bare` should be set to zero to create a standard repo, non-zero for
* a bare repo
- * - `fetch_progress_cb` is optional callback for fetch progress. Be aware that
- * this is called inline with network and indexing operations, so performance
- * may be affected.
- * - `fetch_progress_payload` is payload for fetch_progress_cb
+ * - `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".
- * - `pushurl` is a URL to be used for pushing. NULL means use the fetch url.
- * - `fetch_spec` is the fetch specification to be used for fetching. NULL
- * results in the same behavior as GIT_REMOTE_DEFAULT_FETCH.
- * - `push_spec` is the fetch specification to be used for pushing. NULL means
- * use the same spec as for fetching.
- * - `cred_acquire_cb` is a callback to be used if credentials are required
- * during the initial fetch.
- * - `cred_acquire_payload` is the payload for the above callback.
- * - `transport_flags` is flags used to create transport if no transport is
- * provided.
- * - `transport` is a custom transport to be used for the initial fetch. NULL
- * means use the transport autodetected from the URL.
- * - `remote_callbacks` may be used to specify custom progress callbacks for
- * the origin remote before the fetch is initiated.
- * - `remote_autotag` may be used to specify the autotag setting before the
- * initial fetch. The default is GIT_REMOTE_DOWNLOAD_TAGS_ALL.
* - `checkout_branch` gives the name of the branch to checkout. NULL means
* use the remote's HEAD.
*/
@@ -67,29 +49,23 @@ typedef struct git_clone_options {
unsigned int version;
git_checkout_opts checkout_opts;
- int bare;
- git_transfer_progress_callback fetch_progress_cb;
- void *fetch_progress_payload;
+ git_remote_callbacks remote_callbacks;
+ int bare;
+ int ignore_cert_errors;
const char *remote_name;
- const char *pushurl;
- const char *fetch_spec;
- const char *push_spec;
- git_cred_acquire_cb cred_acquire_cb;
- void *cred_acquire_payload;
- git_transport_flags_t transport_flags;
- git_transport *transport;
- git_remote_callbacks *remote_callbacks;
- git_remote_autotag_option_t remote_autotag;
const char* checkout_branch;
} git_clone_options;
#define GIT_CLONE_OPTIONS_VERSION 1
-#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE_CREATE}}
+#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE_CREATE}, GIT_REMOTE_CALLBACKS_INIT}
/**
- * Clone a remote repository, and checkout the branch pointed to by the remote
- * HEAD.
+ * Clone a remote repository.
+ *
+ * This version handles the simple case. If you'd like to create the
+ * repository or remote with non-default settings, you can create and
+ * configure them and then use `git_clone_into()`.
*
* @param out pointer that will receive the resulting repository object
* @param url the remote repository to clone
@@ -105,6 +81,22 @@ GIT_EXTERN(int) git_clone(
const char *local_path,
const git_clone_options *options);
+/**
+ * Clone into a repository
+ *
+ * After creating the repository and remote and configuring them for
+ * paths and callbacks respectively, you can call this function to
+ * perform the clone operation and optionally checkout files.
+ *
+ * @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
+ */
+GIT_EXTERN(int) git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/commit.h b/include/git2/commit.h
index 544d21d87..a08cf1c6c 100644
--- a/include/git2/commit.h
+++ b/include/git2/commit.h
@@ -24,17 +24,24 @@ GIT_BEGIN_DECL
/**
* Lookup a commit object from a repository.
*
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
+ *
* @param commit pointer to the looked up commit
* @param repo the repo to use when locating the commit.
* @param id identity of the commit to locate. If the object is
* an annotated tag it will be peeled back to the commit.
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id);
+GIT_EXTERN(int) git_commit_lookup(
+ git_commit **commit, git_repository *repo, const git_oid *id);
/**
- * Lookup a commit object from a repository,
- * given a prefix of its identifier (short id).
+ * Lookup a commit object from a repository, given a prefix of its
+ * identifier (short id).
+ *
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
*
* @see git_object_lookup_prefix
*
@@ -45,7 +52,8 @@ GIT_EXTERN(int) git_commit_lookup(git_commit **commit, git_repository *repo, con
* @param len the length of the short identifier
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len);
+GIT_EXTERN(int) git_commit_lookup_prefix(
+ git_commit **commit, git_repository *repo, const git_oid *id, size_t len);
/**
* Close an open commit
@@ -92,12 +100,23 @@ GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit);
/**
* Get the full message of a commit.
*
+ * The returned message will be slightly prettified by removing any
+ * potential leading newlines.
+ *
* @param commit a previously loaded commit.
* @return the message of a commit
*/
GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
/**
+ * Get the full raw message of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the raw message of a commit
+ */
+GIT_EXTERN(const char *) git_commit_message_raw(const git_commit *commit);
+
+/**
* Get the commit time (i.e. committer time) of a commit.
*
* @param commit a previously loaded commit.
@@ -130,6 +149,14 @@ GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit)
GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
/**
+ * Get the full raw text of the commit header.
+ *
+ * @param commit a previously loaded commit
+ * @return the header text of the commit
+ */
+GIT_EXTERN(const char *) git_commit_raw_header(const git_commit *commit);
+
+/**
* Get the tree pointed to by a commit.
*
* @param tree_out pointer where to store the tree object
diff --git a/include/git2/common.h b/include/git2/common.h
index b52e13918..dca0c9c21 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -105,7 +105,8 @@ GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
*/
typedef enum {
GIT_CAP_THREADS = ( 1 << 0 ),
- GIT_CAP_HTTPS = ( 1 << 1 )
+ GIT_CAP_HTTPS = ( 1 << 1 ),
+ GIT_CAP_SSH = ( 1 << 2 ),
} git_cap_t;
/**
@@ -135,7 +136,9 @@ typedef enum {
GIT_OPT_SET_CACHE_OBJECT_LIMIT,
GIT_OPT_SET_CACHE_MAX_SIZE,
GIT_OPT_ENABLE_CACHING,
- GIT_OPT_GET_CACHED_MEMORY
+ GIT_OPT_GET_CACHED_MEMORY,
+ GIT_OPT_GET_TEMPLATE_PATH,
+ GIT_OPT_SET_TEMPLATE_PATH
} git_libgit2_opt_t;
/**
@@ -209,6 +212,18 @@ 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)
+ *
+ * > 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.
+ *
+ * * opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)
+ *
+ * > Set the default template path.
+ * >
+ * > - `path` directory of template.
+ *
* @param option Option key
* @param ... value to set the option
* @return 0 on success, <0 on failure
diff --git a/include/git2/config.h b/include/git2/config.h
index 827d43544..95da4bc03 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -61,6 +61,7 @@ typedef struct {
} git_config_entry;
typedef int (*git_config_foreach_cb)(const git_config_entry *, void *);
+typedef struct git_config_iterator git_config_iterator;
typedef enum {
GIT_CVAR_FALSE = 0,
@@ -327,7 +328,7 @@ GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char
GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
/**
- * Get each value of a multivar.
+ * Get each value of a multivar in a foreach callback
*
* The callback will be called on each variable found
*
@@ -338,7 +339,34 @@ GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, c
* @param callback the function to be called on each value of the variable
* @param payload opaque pointer to pass to the callback
*/
-GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
+GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
+
+/**
+ * Get each value of a multivar
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp regular expression to filter which variables we're
+ * interested in. Use NULL to indicate all
+ */
+GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp);
+
+/**
+ * Return the current entry and advance the iterator
+ *
+ * @param entry pointer to store the entry
+ * @param iter the iterator
+ * @return 0 or an error code. GIT_ITEROVER if the iteration has completed
+ */
+GIT_EXTERN(int) git_config_next(git_config_entry **entry, git_config_iterator *iter);
+
+/**
+ * Free a config iterator
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_config_iterator_free(git_config_iterator *iter);
/**
* Set the value of an integer config variable in the config file
@@ -407,6 +435,17 @@ GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const
GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
/**
+ * Deletes one or several entries from a multivar in the local config file.
+ *
+ * @param cfg where to look for the variables
+ * @param name the variable's name
+ * @param regexp a regular expression to indicate which values to delete
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_delete_multivar(git_config *cfg, const char *name, const char *regexp);
+
+/**
* Perform an operation on each config variable.
*
* The callback receives the normalized name and value of each variable
@@ -425,6 +464,29 @@ GIT_EXTERN(int) git_config_foreach(
void *payload);
/**
+ * Iterate over all the config variables
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to ge the variables from
+ */
+GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_config *cfg);
+
+/**
+ * Iterate over all the config variables whose name matches a pattern
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to ge the variables from
+ * @param regexp regular expression to match the names
+ */
+GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp);
+
+/**
* Perform an operation on each config variable matching a regular expression.
*
* This behaviors like `git_config_foreach` with an additional filter of a
@@ -535,6 +597,25 @@ GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value);
GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
+/**
+ * Perform an operation on each config variable in given config backend
+ * matching a regular expression.
+ *
+ * This behaviors like `git_config_foreach_match` except instead of all config
+ * entries it just enumerates through the given backend entry.
+ *
+ * @param backend where to get the variables from
+ * @param regexp regular expression to match against config names (can be NULL)
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ */
+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_END_DECL
#endif
diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h
index 5d93cf4dd..1d8809211 100644
--- a/include/git2/cred_helpers.h
+++ b/include/git2/cred_helpers.h
@@ -7,7 +7,7 @@
#ifndef INCLUDE_git_cred_helpers_h__
#define INCLUDE_git_cred_helpers_h__
-#include "git2/transport.h"
+#include "transport.h"
/**
* @file git2/cred_helpers.h
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 43029c49c..61d288380 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -20,34 +20,38 @@
* Overview
* --------
*
- * Calculating diffs is generally done in two phases: building a diff list
- * then traversing the diff list. This makes is easier to share logic
- * across the various types of diffs (tree vs tree, workdir vs index, etc.),
- * and also allows you to insert optional diff list post-processing phases,
- * such as rename detected, in between the steps. When you are done with a
- * diff list object, it must be freed.
+ * Calculating diffs is generally done in two phases: building a list of
+ * diffs then traversing it. This makes is easier to share logic across
+ * the various types of diffs (tree vs tree, workdir vs index, etc.), and
+ * also allows you to insert optional diff post-processing phases,
+ * such as rename detection, in between the steps. When you are done with
+ * a diff object, it must be freed.
*
* Terminology
* -----------
*
* To understand the diff APIs, you should know the following terms:
*
- * - A `diff` or `diff list` represents the cumulative list of differences
- * between two snapshots of a repository (possibly filtered by a set of
- * file name patterns). This is the `git_diff_list` object.
+ * - A `diff` represents the cumulative list of differences between two
+ * snapshots of a repository (possibly filtered by a set of file name
+ * patterns). This is the `git_diff` object.
+ *
* - A `delta` is a file pair with an old and new revision. The old version
* may be absent if the file was just created and the new version may be
* absent if the file was deleted. A diff is mostly just a list of deltas.
+ *
* - A `binary` file / delta is a file (or pair) for which no text diffs
- * should be generated. A diff list can contain delta entries that are
+ * should be generated. A diff can contain delta entries that are
* binary, but no diff content will be output for those files. There is
* a base heuristic for binary detection and you can further tune the
* behavior with git attributes or diff flags and option settings.
+ *
* - A `hunk` is a span of modified lines in a delta along with some stable
* surrounding context. You can configure the amount of context and other
* properties of how hunks are generated. Each hunk also comes with a
* header that described where it starts and ends in both the old and new
* versions in the delta.
+ *
* - A `line` is a range of characters inside a hunk. It could be a context
* line (i.e. in both old and new versions), an added line (i.e. only in
* the new version), or a removed line (i.e. only in the old version).
@@ -68,100 +72,125 @@ GIT_BEGIN_DECL
typedef enum {
/** Normal diff, the default */
GIT_DIFF_NORMAL = 0,
- /** Reverse the sides of the diff */
- GIT_DIFF_REVERSE = (1 << 0),
- /** Treat all files as text, disabling binary attributes & detection */
- GIT_DIFF_FORCE_TEXT = (1 << 1),
- /** Ignore all whitespace */
- GIT_DIFF_IGNORE_WHITESPACE = (1 << 2),
- /** Ignore changes in amount of whitespace */
- GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3),
- /** Ignore whitespace at end of line */
- GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4),
- /** Exclude submodules from the diff completely */
- GIT_DIFF_IGNORE_SUBMODULES = (1 << 5),
- /** Use the "patience diff" algorithm (currently unimplemented) */
- GIT_DIFF_PATIENCE = (1 << 6),
- /** Include ignored files in the diff list */
- GIT_DIFF_INCLUDE_IGNORED = (1 << 7),
- /** Include untracked files in the diff list */
- GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8),
- /** Include unmodified files in the diff list */
- GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9),
- /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
- * directory will be marked with only a single entry in the diff list
- * (a la what core Git does in `git status`); this flag adds *all*
- * files under untracked directories as UNTRACKED entries, too.
+ /*
+ * Options controlling which files will be in the diff
*/
- GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10),
- /** If the pathspec is set in the diff options, this flags means to
- * apply it as an exact match instead of as an fnmatch pattern.
- */
- GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11),
+ /** Reverse the sides of the diff */
+ GIT_DIFF_REVERSE = (1u << 0),
- /** Use case insensitive filename comparisons */
- GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12),
+ /** Include ignored files in the diff */
+ GIT_DIFF_INCLUDE_IGNORED = (1u << 1),
- /** When generating patch text, include the content of untracked
- * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
- * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that
- * flag if you want the content of every single UNTRACKED file.
+ /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
+ * will be marked with only a single entry in the diff; this flag
+ * adds all files under the directory as IGNORED entries, too.
*/
- GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13),
+ GIT_DIFF_RECURSE_IGNORED_DIRS = (1u << 2),
- /** Disable updating of the `binary` flag in delta records. This is
- * useful when iterating over a diff if you don't need hunk and data
- * callbacks and want to avoid having to load file completely.
+ /** Include untracked files in the diff */
+ GIT_DIFF_INCLUDE_UNTRACKED = (1u << 3),
+
+ /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
+ * directory will be marked with only a single entry in the diff
+ * (a la what core Git does in `git status`); this flag adds *all*
+ * files under untracked directories as UNTRACKED entries, too.
*/
- GIT_DIFF_SKIP_BINARY_CHECK = (1 << 14),
+ GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1u << 4),
+
+ /** Include unmodified files in the diff */
+ GIT_DIFF_INCLUDE_UNMODIFIED = (1u << 5),
/** Normally, a type change between files will be converted into a
* DELETED record for the old and an ADDED record for the new; this
* options enabled the generation of TYPECHANGE delta records.
*/
- GIT_DIFF_INCLUDE_TYPECHANGE = (1 << 15),
+ GIT_DIFF_INCLUDE_TYPECHANGE = (1u << 6),
/** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still
* generally show as a DELETED blob. This flag tries to correctly
* label blob->tree transitions as TYPECHANGE records with new_file's
* mode set to tree. Note: the tree SHA will not be available.
*/
- GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16),
+ GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1u << 7),
/** Ignore file mode changes */
- GIT_DIFF_IGNORE_FILEMODE = (1 << 17),
+ GIT_DIFF_IGNORE_FILEMODE = (1u << 8),
- /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
- * will be marked with only a single entry in the diff list; this flag
- * adds all files under the directory as IGNORED entries, too.
+ /** Treat all submodules as unmodified */
+ GIT_DIFF_IGNORE_SUBMODULES = (1u << 9),
+
+ /** Use case insensitive filename comparisons */
+ GIT_DIFF_IGNORE_CASE = (1u << 10),
+
+ /** If the pathspec is set in the diff options, this flags means to
+ * apply it as an exact match instead of as an fnmatch pattern.
*/
- GIT_DIFF_RECURSE_IGNORED_DIRS = (1 << 18),
-
- /** Core Git scans inside untracked directories, labeling them IGNORED
- * if they are empty or only contain ignored files; a directory is
- * consider UNTRACKED only if it has an actual untracked file in it.
- * This scan is extra work for a case you often don't care about. This
- * flag makes libgit2 immediately label an untracked directory as
- * UNTRACKED without looking inside it (which differs from core Git).
- * Of course, ignore rules are still checked for the directory itself.
+ GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1u << 12),
+
+ /** Disable updating of the `binary` flag in delta records. This is
+ * useful when iterating over a diff if you don't need hunk and data
+ * callbacks and want to avoid having to load file completely.
+ */
+ GIT_DIFF_SKIP_BINARY_CHECK = (1u << 13),
+
+ /** When diff finds an untracked directory, to match the behavior of
+ * core Git, it scans the contents for IGNORED and UNTRACKED files.
+ * If *all* contents are IGNORED, then the directory is IGNORED; if
+ * any contents are not IGNORED, then the directory is UNTRACKED.
+ * This is extra work that may not matter in many cases. This flag
+ * turns off that scan and immediately labels an untracked directory
+ * as UNTRACKED (changing the behavior to not match core Git).
+ */
+ GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
+
+ /*
+ * Options controlling how output will be generated
*/
- GIT_DIFF_FAST_UNTRACKED_DIRS = (1 << 19),
+ /** Treat all files as text, disabling binary attributes & detection */
+ GIT_DIFF_FORCE_TEXT = (1u << 20),
/** Treat all files as binary, disabling text diffs */
- GIT_DIFF_FORCE_BINARY = (1 << 20),
+ GIT_DIFF_FORCE_BINARY = (1u << 21),
+
+ /** Ignore all whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE = (1u << 22),
+ /** Ignore changes in amount of whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1u << 23),
+ /** Ignore whitespace at end of line */
+ GIT_DIFF_IGNORE_WHITESPACE_EOL = (1u << 24),
+
+ /** When generating patch text, include the content of untracked
+ * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
+ * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that
+ * flag if you want the content of every single UNTRACKED file.
+ */
+ GIT_DIFF_SHOW_UNTRACKED_CONTENT = (1u << 25),
+
+ /** When generating output, include the names of unmodified files if
+ * they are included in the git_diff. Normally these are skipped in
+ * the formats that list files (e.g. name-only, name-status, raw).
+ * Even with this, these will not be included in patch format.
+ */
+ GIT_DIFF_SHOW_UNMODIFIED = (1u << 26),
+
+ /** Use the "patience diff" algorithm */
+ GIT_DIFF_PATIENCE = (1u << 28),
+ /** Take extra time to find minimal diff */
+ GIT_DIFF_MINIMAL = (1 << 29),
+
} git_diff_option_t;
/**
- * The diff list object that contains all individual file deltas.
+ * The diff object that contains all individual file deltas.
*
* This is an opaque structure which will be allocated by one of the diff
* generator functions below (such as `git_diff_tree_to_tree`). You are
* responsible for releasing the object memory when done, using the
- * `git_diff_list_free()` function.
+ * `git_diff_free()` function.
*/
-typedef struct git_diff_list git_diff_list;
+typedef struct git_diff git_diff;
/**
* Flags for the delta object and the file objects on each side.
@@ -172,16 +201,16 @@ typedef struct git_diff_list git_diff_list;
* considered reserved for internal or future use.
*/
typedef enum {
- GIT_DIFF_FLAG_BINARY = (1 << 0), /** file(s) treated as binary data */
- GIT_DIFF_FLAG_NOT_BINARY = (1 << 1), /** file(s) treated as text data */
- GIT_DIFF_FLAG_VALID_OID = (1 << 2), /** `oid` value is known correct */
+ GIT_DIFF_FLAG_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_t;
/**
* What type of change is described by a git_diff_delta?
*
* `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
- * `git_diff_find_similar()` on the diff list object.
+ * `git_diff_find_similar()` on the diff object.
*
* `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
* in the option flags (otherwise type changes will be split into ADDED /
@@ -200,11 +229,11 @@ typedef enum {
} git_delta_t;
/**
- * Description of one side of a diff entry.
+ * Description of one side of a delta.
*
- * Although this is called a "file", it may actually represent a file, a
- * symbolic link, a submodule commit id, or even a tree (although that only
- * if you are tracking type changes or ignored/untracked directories).
+ * Although this is called a "file", it could represent a file, a symbolic
+ * link, a submodule commit id, or even a tree (although that only if you
+ * are tracking type changes or ignored/untracked directories).
*
* The `oid` is the `git_oid` of the item. If the entry represents an
* absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta),
@@ -231,9 +260,8 @@ typedef struct {
/**
* Description of changes to one entry.
*
- * When iterating over a diff list object, this will be passed to most
- * callback functions and you can use the contents to understand exactly
- * what has changed.
+ * When iterating over a diff, this will be passed to most callbacks and
+ * you can use the contents to understand exactly what has changed.
*
* The `old_file` represents the "from" side of the diff and the `new_file`
* represents to "to" side of the diff. What those means depend on the
@@ -266,28 +294,29 @@ typedef struct {
* the score (a la `printf("M%03d", 100 - delta->similarity)`).
*/
typedef struct {
+ git_delta_t status;
+ uint32_t flags; /**< git_diff_flag_t values */
+ uint16_t similarity; /**< for RENAMED and COPIED, value 0-100 */
+ uint16_t nfiles; /**< number of files in this delta */
git_diff_file old_file;
git_diff_file new_file;
- git_delta_t status;
- uint32_t similarity; /**< for RENAMED and COPIED, value 0-100 */
- uint32_t flags;
} git_diff_delta;
/**
* Diff notification callback function.
*
* The callback will be called for each file, just before the `git_delta_t`
- * gets inserted into the diff list.
+ * gets inserted into the diff.
*
* When the callback:
* - returns < 0, the diff process will be aborted.
- * - returns > 0, the delta will not be inserted into the diff list, but the
+ * - returns > 0, the delta will not be inserted into the diff, but the
* diff process continues.
- * - returns 0, the delta is inserted into the diff list, and the diff process
+ * - returns 0, the delta is inserted into the diff, and the diff process
* continues.
*/
typedef int (*git_diff_notify_cb)(
- const git_diff_list *diff_so_far,
+ const git_diff *diff_so_far,
const git_diff_delta *delta_to_add,
const char *matched_pathspec,
void *payload);
@@ -314,28 +343,44 @@ typedef int (*git_diff_notify_cb)(
* - `notify_cb` is an optional callback function, notifying the consumer of
* which files are being examined as the diff is generated
* - `notify_payload` is the payload data to pass to the `notify_cb` function
+ * - `ignore_submodules` overrides the submodule ignore setting for all
+ * submodules in the diff.
*/
typedef struct {
unsigned int version; /**< version for the struct */
uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */
- uint16_t context_lines; /**< defaults to 3 */
- uint16_t interhunk_lines; /**< defaults to 0 */
- const char *old_prefix; /**< defaults to "a" */
- const char *new_prefix; /**< defaults to "b" */
- git_strarray pathspec; /**< defaults to include all paths */
- git_off_t max_size; /**< defaults to 512MB */
+
+ /* options controlling which files are in the diff */
+
+ git_submodule_ignore_t ignore_submodules; /**< submodule ignore rule */
+ git_strarray pathspec; /**< defaults to include all paths */
git_diff_notify_cb notify_cb;
- void *notify_payload;
+ void *notify_payload;
+
+ /* options controlling how to diff text is generated */
+
+ 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 */
+ git_off_t max_size; /**< defaults to 512MB */
+ const char *old_prefix; /**< defaults to "a" */
+ const char *new_prefix; /**< defaults to "b" */
} git_diff_options;
+/* The current version of the diff options structure */
#define GIT_DIFF_OPTIONS_VERSION 1
-#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_NORMAL, 3}
+
+/* Stack initializer for diff options. Alternatively use
+ * `git_diff_options_init` programmatic initialization.
+ */
+#define GIT_DIFF_OPTIONS_INIT \
+ {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_DEFAULT, {NULL,0}, NULL, NULL, 3}
/**
* When iterating over a diff, callback that will be made per file.
*
* @param delta A pointer to the delta data for the file
- * @param progress Goes from 0 to 1 over the diff list
+ * @param progress Goes from 0 to 1 over the diff
* @param payload User-specified pointer from foreach function
*/
typedef int (*git_diff_file_cb)(
@@ -346,34 +391,35 @@ typedef int (*git_diff_file_cb)(
/**
* Structure describing a hunk of a diff.
*/
-typedef struct {
- int old_start; /** Starting line number in old_file */
- int old_lines; /** Number of lines in old_file */
- int new_start; /** Starting line number in new_file */
- int new_lines; /** Number of lines in new_file */
-} git_diff_range;
+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 */
+};
/**
* When iterating over a diff, callback that will be made per hunk.
*/
typedef int (*git_diff_hunk_cb)(
const git_diff_delta *delta,
- const git_diff_range *range,
- const char *header,
- size_t header_len,
+ const git_diff_hunk *hunk,
void *payload);
/**
* Line origin constants.
*
* These values describe where a line came from and will be passed to
- * the git_diff_data_cb when iterating over a diff. There are some
+ * the git_diff_line_cb when iterating over a diff. There are some
* special origin constants at the end that are used for the text
* output callbacks to demarcate lines that are actually part of
* the file or hunk headers.
*/
typedef enum {
- /* These values will be sent to `git_diff_data_cb` along with the line */
+ /* These values will be sent to `git_diff_line_cb` along with the line */
GIT_DIFF_LINE_CONTEXT = ' ',
GIT_DIFF_LINE_ADDITION = '+',
GIT_DIFF_LINE_DELETION = '-',
@@ -382,16 +428,29 @@ typedef enum {
GIT_DIFF_LINE_ADD_EOFNL = '>', /**< Old has no LF at end, new does */
GIT_DIFF_LINE_DEL_EOFNL = '<', /**< Old has LF at end, new does not */
- /* The following values will only be sent to a `git_diff_data_cb` when
- * the content of a diff is being formatted (eg. through
- * git_diff_print_patch() or git_diff_print_compact(), for instance).
+ /* The following values will only be sent to a `git_diff_line_cb` when
+ * the content of a diff is being formatted through `git_diff_print`.
*/
GIT_DIFF_LINE_FILE_HDR = 'F',
GIT_DIFF_LINE_HUNK_HDR = 'H',
- GIT_DIFF_LINE_BINARY = 'B'
+ GIT_DIFF_LINE_BINARY = 'B' /**< For "Binary files x and y differ" */
} git_diff_line_t;
/**
+ * Structure describing a line (or data span) of a diff.
+ */
+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 */
+};
+
+/**
* When iterating over a diff, callback that will be made per text diff
* line. In this context, the provided range will be NULL.
*
@@ -399,46 +458,36 @@ typedef enum {
* of text. This uses some extra GIT_DIFF_LINE_... constants for output
* of lines of file and hunk headers.
*/
-typedef int (*git_diff_data_cb)(
+typedef int (*git_diff_line_cb)(
const git_diff_delta *delta, /** delta that contains this data */
- const git_diff_range *range, /** range of lines containing this data */
- char line_origin, /** git_diff_list_t value from above */
- const char *content, /** diff data - not NUL terminated */
- size_t content_len, /** number of bytes of diff data */
+ const git_diff_hunk *hunk, /** hunk containing this data */
+ const git_diff_line *line, /** line data */
void *payload); /** user reference data */
/**
- * The diff patch is used to store all the text diffs for a delta.
- *
- * You can easily loop over the content of patches and get information about
- * them.
- */
-typedef struct git_diff_patch git_diff_patch;
-
-/**
* Flags to control the behavior of diff rename/copy detection.
*/
typedef enum {
/** look for renames? (`--find-renames`) */
- GIT_DIFF_FIND_RENAMES = (1 << 0),
+ GIT_DIFF_FIND_RENAMES = (1u << 0),
/** consider old side of modified for renames? (`--break-rewrites=N`) */
- GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1 << 1),
+ GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1u << 1),
/** look for copies? (a la `--find-copies`) */
- GIT_DIFF_FIND_COPIES = (1 << 2),
+ GIT_DIFF_FIND_COPIES = (1u << 2),
/** consider unmodified as copy sources? (`--find-copies-harder`) */
- GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3),
+ GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1u << 3),
/** mark large rewrites for split (`--break-rewrites=/M`) */
- GIT_DIFF_FIND_REWRITES = (1 << 4),
+ GIT_DIFF_FIND_REWRITES = (1u << 4),
/** actually split large rewrites into delete/add pairs */
- GIT_DIFF_BREAK_REWRITES = (1 << 5),
+ GIT_DIFF_BREAK_REWRITES = (1u << 5),
/** mark rewrites for split and break into delete/add pairs */
GIT_DIFF_FIND_AND_BREAK_REWRITES =
(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES),
/** find renames/copies for untracked items in working directory */
- GIT_DIFF_FIND_FOR_UNTRACKED = (1 << 6),
+ GIT_DIFF_FIND_FOR_UNTRACKED = (1u << 6),
/** turn on all finding features */
GIT_DIFF_FIND_ALL = (0x0ff),
@@ -446,11 +495,14 @@ typedef enum {
/** measure similarity ignoring leading whitespace (default) */
GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
/** measure similarity ignoring all whitespace */
- GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 12),
+ GIT_DIFF_FIND_IGNORE_WHITESPACE = (1u << 12),
/** measure similarity including all data */
- GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13),
+ GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1u << 13),
/** measure similarity only by comparing SHAs (fast and cheap) */
- GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14),
+ GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1u << 14),
+
+ /** do not break rewrites unless they contribute to a rename */
+ GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1u << 15),
} git_diff_find_t;
/**
@@ -515,22 +567,22 @@ typedef struct {
#define GIT_DIFF_FIND_OPTIONS_VERSION 1
#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
-/** @name Diff List Generator Functions
+/** @name Diff Generator Functions
*
* These are the functions you would use to create (or destroy) a
- * git_diff_list from various objects in a repository.
+ * git_diff from various objects in a repository.
*/
/**@{*/
/**
- * Deallocate a diff list.
+ * Deallocate a diff.
*
- * @param diff The previously created diff list; cannot be used after free.
+ * @param diff The previously created diff; cannot be used after free.
*/
-GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff);
+GIT_EXTERN(void) git_diff_free(git_diff *diff);
/**
- * Create a diff list with the difference between two tree objects.
+ * Create a diff with the difference between two tree objects.
*
* This is equivalent to `git diff <old-tree> <new-tree>`
*
@@ -539,21 +591,21 @@ GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff);
* pass NULL to indicate an empty tree, although it is an error to pass
* NULL for both the `old_tree` and `new_tree`.
*
- * @param diff Output pointer to a git_diff_list pointer to be allocated.
+ * @param diff Output pointer to a git_diff pointer to be allocated.
* @param repo The repository containing the trees.
* @param old_tree A git_tree object to diff from, or NULL for empty tree.
* @param new_tree A git_tree object to diff to, or NULL for empty tree.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_tree(
- git_diff_list **diff,
+ git_diff **diff,
git_repository *repo,
git_tree *old_tree,
git_tree *new_tree,
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between a tree and repository index.
+ * Create a diff between a tree and repository index.
*
* This is equivalent to `git diff --cached <treeish>` or if you pass
* the HEAD tree, then like `git diff --cached`.
@@ -561,21 +613,25 @@ GIT_EXTERN(int) git_diff_tree_to_tree(
* The tree you pass will be used for the "old_file" side of the delta, and
* the index will be used for the "new_file" side of the delta.
*
- * @param diff Output pointer to a git_diff_list pointer to be allocated.
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used. In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
* @param repo The repository containing the tree and index.
* @param old_tree A git_tree object to diff from, or NULL for empty tree.
* @param index The index to diff with; repo index used if NULL.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_index(
- git_diff_list **diff,
+ git_diff **diff,
git_repository *repo,
git_tree *old_tree,
git_index *index,
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between the repository index and the workdir directory.
+ * Create a diff between the repository index and the workdir directory.
*
* This matches the `git diff` command. See the note below on
* `git_diff_tree_to_workdir` for a discussion of the difference between
@@ -585,19 +641,23 @@ GIT_EXTERN(int) git_diff_tree_to_index(
* The index will be used for the "old_file" side of the delta, and the
* working directory will be used for the "new_file" side of the delta.
*
- * @param diff Output pointer to a git_diff_list pointer to be allocated.
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used. In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
* @param repo The repository.
* @param index The index to diff from; repo index used if NULL.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_index_to_workdir(
- git_diff_list **diff,
+ git_diff **diff,
git_repository *repo,
git_index *index,
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between a tree and the working directory.
+ * Create a diff between a tree and the working directory.
*
* The tree you provide will be used for the "old_file" side of the delta,
* and the working directory will be used for the "new_file" side.
@@ -611,31 +671,51 @@ GIT_EXTERN(int) git_diff_index_to_workdir(
* files in the index. It may come as a surprise, but there is no direct
* equivalent in core git.
*
- * To emulate `git diff <treeish>`, call both `git_diff_tree_to_index` and
- * `git_diff_index_to_workdir`, then call `git_diff_merge` on the results.
- * That will yield a `git_diff_list` that matches the git output.
+ * 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.
*
- * @param diff A pointer to a git_diff_list pointer that will be allocated.
+ * @param diff A pointer to a git_diff pointer that will be allocated.
* @param repo The repository containing the tree.
* @param old_tree A git_tree object to diff from, or NULL for empty tree.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_workdir(
- git_diff_list **diff,
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Create a diff between a tree and the working directory using index data
+ * to account for staged deletes, tracked files, etc.
+ *
+ * This emulates `git diff <tree>` by diffing the tree to the index and
+ * the index to the working directory and blending the results into a
+ * single diff that includes staged deleted, etc.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir_with_index(
+ git_diff **diff,
git_repository *repo,
git_tree *old_tree,
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Merge one diff list into another.
+ * Merge one diff into another.
*
* This merges items from the "from" list into the "onto" list. The
- * resulting diff list will have all items that appear in either list.
+ * resulting diff will have all items that appear in either list.
* If an item appears in both lists, then it will be "merged" to appear
* as if the old version was from the "onto" list and the new version
* is from the "from" list (with the exception that if the item has a
@@ -645,320 +725,176 @@ GIT_EXTERN(int) git_diff_tree_to_workdir(
* @param from Diff to merge.
*/
GIT_EXTERN(int) git_diff_merge(
- git_diff_list *onto,
- const git_diff_list *from);
+ git_diff *onto,
+ const git_diff *from);
/**
- * Transform a diff list marking file renames, copies, etc.
+ * Transform a diff marking file renames, copies, etc.
*
- * This modifies a diff list in place, replacing old entries that look
+ * This modifies a diff in place, replacing old entries that look
* like renames or copies with new entries reflecting those changes.
* This also will, if requested, break modified files into add/remove
* pairs if the amount of change is above a threshold.
*
- * @param diff Diff list to run detection algorithms on
+ * @param diff diff to run detection algorithms on
* @param options Control how detection should be run, NULL for defaults
* @return 0 on success, -1 on failure
*/
GIT_EXTERN(int) git_diff_find_similar(
- git_diff_list *diff,
- git_diff_find_options *options);
-
-/**@}*/
-
-
-/** @name Diff List Processor Functions
- *
- * These are the functions you apply to a diff list to process it
- * or read it in some way.
- */
-/**@{*/
+ git_diff *diff,
+ const git_diff_find_options *options);
/**
- * Loop over all deltas in a diff list issuing callbacks.
+ * Initialize diff options structure
*
- * This will iterate through all of the files described in a diff. You
- * should provide a file callback to learn about each file.
+ * 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.
*
- * The "hunk" and "line" callbacks are optional, and the text diff of the
- * files will only be calculated if they are not NULL. Of course, these
- * callbacks will not be invoked for binary files on the diff list or for
- * files whose only changed is a file mode change.
- *
- * Returning a non-zero value from any of the callbacks will terminate
- * the iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff_list generated by one of the above functions.
- * @param file_cb Callback function to make per file in the diff.
- * @param hunk_cb Optional callback to make per hunk of text diff. This
- * callback is called to describe a range of lines in the
- * diff. It will not be issued for binary files.
- * @param line_cb Optional callback to make per line of diff text. This
- * same callback will be made for context lines, added, and
- * removed lines, and even for a deleted trailing newline.
- * @param payload Reference pointer that will be passed to your callbacks.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @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_foreach(
- git_diff_list *diff,
- git_diff_file_cb file_cb,
- git_diff_hunk_cb hunk_cb,
- git_diff_data_cb line_cb,
- void *payload);
+GIT_EXTERN(int) git_diff_options_init(
+ git_diff_options *options,
+ unsigned int version);
-/**
- * Iterate over a diff generating text output like "git diff --name-status".
- *
- * Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff_list generated by one of the above functions.
- * @param print_cb Callback to make per line of diff text.
- * @param payload Reference pointer that will be passed to your callback.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
- */
-GIT_EXTERN(int) git_diff_print_compact(
- git_diff_list *diff,
- git_diff_data_cb print_cb,
- void *payload);
+/**@}*/
-/**
- * Iterate over a diff generating text output like "git diff --raw".
- *
- * Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff_list generated by one of the above functions.
- * @param print_cb Callback to make per line of diff text.
- * @param payload Reference pointer that will be passed to your callback.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
- */
-GIT_EXTERN(int) git_diff_print_raw(
- git_diff_list *diff,
- git_diff_data_cb print_cb,
- void *payload);
-/**
- * Look up the single character abbreviation for a delta status code.
- *
- * When you call `git_diff_print_compact` it prints single letter codes into
- * the output such as 'A' for added, 'D' for deleted, 'M' for modified, etc.
- * It is sometimes convenient to convert a git_delta_t value into these
- * letters for your own purposes. This function does just that. By the
- * way, unmodified will return a space (i.e. ' ').
+/** @name Diff Processor Functions
*
- * @param status The git_delta_t value to look up
- * @return The single character label for that code
- */
-GIT_EXTERN(char) git_diff_status_char(git_delta_t status);
-
-/**
- * Iterate over a diff generating text output like "git diff".
- *
- * This is a super easy way to generate a patch from a diff.
- *
- * Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff_list generated by one of the above functions.
- * @param payload Reference pointer that will be passed to your callbacks.
- * @param print_cb Callback function to output lines of the diff. This
- * same function will be called for file headers, hunk
- * headers, and diff lines. Fortunately, you can probably
- * use various GIT_DIFF_LINE constants to determine what
- * text you are given.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * These are the functions you apply to a diff to process it
+ * or read it in some way.
*/
-GIT_EXTERN(int) git_diff_print_patch(
- git_diff_list *diff,
- git_diff_data_cb print_cb,
- void *payload);
+/**@{*/
/**
- * Query how many diff records are there in a diff list.
+ * Query how many diff records are there in a diff.
*
- * @param diff A git_diff_list generated by one of the above functions
+ * @param diff A git_diff generated by one of the above functions
* @return Count of number of deltas in the list
*/
-GIT_EXTERN(size_t) git_diff_num_deltas(git_diff_list *diff);
+GIT_EXTERN(size_t) git_diff_num_deltas(const git_diff *diff);
/**
- * Query how many diff deltas are there in a diff list filtered by type.
+ * Query how many diff deltas are there in a diff filtered by type.
*
* This works just like `git_diff_entrycount()` with an extra parameter
* that is a `git_delta_t` and returns just the count of how many deltas
* match that particular type.
*
- * @param diff A git_diff_list generated by one of the above functions
+ * @param diff A git_diff generated by one of the above functions
* @param type A git_delta_t value to filter the count
* @return Count of number of deltas matching delta_t type
*/
GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
- git_diff_list *diff,
- git_delta_t type);
+ const git_diff *diff, git_delta_t type);
/**
- * Return the diff delta and patch for an entry in the diff list.
- *
- * The `git_diff_patch` is a newly created object contains the text diffs
- * for the delta. You have to call `git_diff_patch_free()` when you are
- * done with it. You can use the patch object to loop over all the hunks
- * and lines in the diff of the one delta.
+ * Return the diff delta for an entry in the diff list.
*
- * For an unchanged file or a binary file, no `git_diff_patch` will be
- * created, the output will be set to NULL, and the `binary` flag will be
- * set true in the `git_diff_delta` structure.
- *
- * The `git_diff_delta` pointer points to internal data and you do not have
+ * The `git_delta` pointer points to internal data and you do not have
* to release it when you are done with it. It will go away when the
- * `git_diff_list` and `git_diff_patch` go away.
+ * `git_diff` (or any associated `git_patch`) goes away.
*
- * It is okay to pass NULL for either of the output parameters; if you pass
- * NULL for the `git_diff_patch`, then the text diff will not be calculated.
+ * Note that the flags on the delta related to whether it has binary
+ * content or not may not be set if there are no attributes set for the
+ * file and there has been no reason to load the file data at this point.
+ * For now, if you need those flags to be up to date, your only option is
+ * to either use `git_diff_foreach` or create a `git_patch`.
*
- * @param patch_out Output parameter for the delta patch object
- * @param delta_out Output parameter for the delta object
* @param diff Diff list object
* @param idx Index into diff list
- * @return 0 on success, other value < 0 on error
+ * @return Pointer to git_diff_delta (or NULL if `idx` out of range)
*/
-GIT_EXTERN(int) git_diff_get_patch(
- git_diff_patch **patch_out,
- const git_diff_delta **delta_out,
- git_diff_list *diff,
- size_t idx);
+GIT_EXTERN(const git_diff_delta *) git_diff_get_delta(
+ const git_diff *diff, size_t idx);
/**
- * Free a git_diff_patch object.
- */
-GIT_EXTERN(void) git_diff_patch_free(
- git_diff_patch *patch);
-
-/**
- * Get the delta associated with a patch
- */
-GIT_EXTERN(const git_diff_delta *) git_diff_patch_delta(
- git_diff_patch *patch);
-
-/**
- * Get the number of hunks in a patch
+ * Check if deltas are sorted case sensitively or insensitively.
+ *
+ * @param diff diff to check
+ * @return 0 if case sensitive, 1 if case is ignored
*/
-GIT_EXTERN(size_t) git_diff_patch_num_hunks(
- git_diff_patch *patch);
+GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
/**
- * Get line counts of each type in a patch.
+ * Loop over all deltas in a diff issuing callbacks.
*
- * This helps imitate a diff --numstat type of output. For that purpose,
- * you only need the `total_additions` and `total_deletions` values, but we
- * include the `total_context` line count in case you want the total number
- * of lines of diff output that will be generated.
+ * This will iterate through all of the files described in a diff. You
+ * should provide a file callback to learn about each file.
*
- * All outputs are optional. Pass NULL if you don't need a particular count.
+ * The "hunk" and "line" callbacks are optional, and the text diff of the
+ * files will only be calculated if they are not NULL. Of course, these
+ * callbacks will not be invoked for binary files on the diff or for
+ * files whose only changed is a file mode change.
*
- * @param total_context Count of context lines in output, can be NULL.
- * @param total_additions Count of addition lines in output, can be NULL.
- * @param total_deletions Count of deletion lines in output, can be NULL.
- * @param patch The git_diff_patch object
- * @return 0 on success, <0 on error
- */
-GIT_EXTERN(int) git_diff_patch_line_stats(
- size_t *total_context,
- size_t *total_additions,
- size_t *total_deletions,
- const git_diff_patch *patch);
-
-/**
- * Get the information about a hunk in a patch
- *
- * Given a patch and a hunk index into the patch, this returns detailed
- * information about that hunk. Any of the output pointers can be passed
- * as NULL if you don't care about that particular piece of information.
- *
- * @param range Output pointer to git_diff_range of hunk
- * @param header Output pointer to header string for hunk. Unlike the
- * content pointer for each line, this will be NUL-terminated
- * @param header_len Output value of characters in header string
- * @param lines_in_hunk Output count of total lines in this hunk
- * @param patch Input pointer to patch object
- * @param hunk_idx Input index of hunk to get information about
- * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error
+ * Returning a non-zero value from any of the callbacks will terminate
+ * the iteration and cause this return `GIT_EUSER`.
+ *
+ * @param diff A git_diff generated by one of the above functions.
+ * @param file_cb Callback function to make per file in the diff.
+ * @param hunk_cb Optional callback to make per hunk of text diff. This
+ * callback is called to describe a range of lines in the
+ * diff. It will not be issued for binary files.
+ * @param line_cb Optional callback to make per line of diff text. This
+ * same callback will be made for context lines, added, and
+ * removed lines, and even for a deleted trailing newline.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
-GIT_EXTERN(int) git_diff_patch_get_hunk(
- const git_diff_range **range,
- const char **header,
- size_t *header_len,
- size_t *lines_in_hunk,
- git_diff_patch *patch,
- size_t hunk_idx);
+GIT_EXTERN(int) git_diff_foreach(
+ git_diff *diff,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_line_cb line_cb,
+ void *payload);
/**
- * Get the number of lines in a hunk.
+ * Look up the single character abbreviation for a delta status code.
+ *
+ * When you run `git diff --name-status` it uses single letter codes in
+ * the output such as 'A' for added, 'D' for deleted, 'M' for modified,
+ * etc. This function converts a git_delta_t value into these letters for
+ * your own purposes. GIT_DELTA_UNTRACKED will return a space (i.e. ' ').
*
- * @param patch The git_diff_patch object
- * @param hunk_idx Index of the hunk
- * @return Number of lines in hunk or -1 if invalid hunk index
+ * @param status The git_delta_t value to look up
+ * @return The single character label for that code
*/
-GIT_EXTERN(int) git_diff_patch_num_lines_in_hunk(
- git_diff_patch *patch,
- size_t hunk_idx);
+GIT_EXTERN(char) git_diff_status_char(git_delta_t status);
/**
- * Get data about a line in a hunk of a patch.
- *
- * Given a patch, a hunk index, and a line index in the hunk, this
- * will return a lot of details about that line. If you pass a hunk
- * index larger than the number of hunks or a line index larger than
- * the number of lines in the hunk, this will return -1.
- *
- * @param line_origin A GIT_DIFF_LINE constant from above
- * @param content Pointer to content of diff line, not NUL-terminated
- * @param content_len Number of characters in content
- * @param old_lineno Line number in old file or -1 if line is added
- * @param new_lineno Line number in new file or -1 if line is deleted
- * @param patch The patch to look in
- * @param hunk_idx The index of the hunk
- * @param line_of_hunk The index of the line in the hunk
- * @return 0 on success, <0 on failure
+ * Possible output formats for diff data
*/
-GIT_EXTERN(int) git_diff_patch_get_line_in_hunk(
- char *line_origin,
- const char **content,
- size_t *content_len,
- int *old_lineno,
- int *new_lineno,
- git_diff_patch *patch,
- size_t hunk_idx,
- size_t line_of_hunk);
+typedef enum {
+ GIT_DIFF_FORMAT_PATCH = 1u, /**< full git diff */
+ GIT_DIFF_FORMAT_PATCH_HEADER = 2u, /**< just the file headers of patch */
+ GIT_DIFF_FORMAT_RAW = 3u, /**< like git diff --raw */
+ GIT_DIFF_FORMAT_NAME_ONLY = 4u, /**< like git diff --name-only */
+ GIT_DIFF_FORMAT_NAME_STATUS = 5u, /**< like git diff --name-status */
+} git_diff_format_t;
/**
- * Serialize the patch to text via callback.
+ * Iterate over a diff generating formatted text output.
*
- * Returning a non-zero value from the callback will terminate the iteration
- * and cause this return `GIT_EUSER`.
+ * Returning a non-zero value from the callbacks will terminate the
+ * iteration and cause this return `GIT_EUSER`.
*
- * @param patch A git_diff_patch representing changes to one file
- * @param print_cb Callback function to output lines of the patch. Will be
- * called for file headers, hunk headers, and diff lines.
- * @param payload Reference pointer that will be passed to your callbacks.
+ * @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
*/
-GIT_EXTERN(int) git_diff_patch_print(
- git_diff_patch *patch,
- git_diff_data_cb print_cb,
+GIT_EXTERN(int) git_diff_print(
+ git_diff *diff,
+ git_diff_format_t format,
+ git_diff_line_cb print_cb,
void *payload);
-/**
- * Get the content of a patch as a single diff text.
- *
- * @param string Allocated string; caller must free.
- * @param patch A git_diff_patch representing changes to one file
- * @return 0 on success, <0 on failure.
- */
-GIT_EXTERN(int) git_diff_patch_to_str(
- char **string,
- git_diff_patch *patch);
-
/**@}*/
@@ -1001,34 +937,10 @@ GIT_EXTERN(int) git_diff_blobs(
const git_diff_options *options,
git_diff_file_cb file_cb,
git_diff_hunk_cb hunk_cb,
- git_diff_data_cb line_cb,
+ git_diff_line_cb line_cb,
void *payload);
/**
- * Directly generate a patch from the difference between two blobs.
- *
- * This is just like `git_diff_blobs()` except it generates a patch object
- * for the difference instead of directly making callbacks. You can use the
- * standard `git_diff_patch` accessor functions to read the patch data, and
- * you must call `git_diff_patch_free()` on the patch when done.
- *
- * @param out The generated patch; NULL on error
- * @param old_blob Blob for old side of diff, or NULL for empty blob
- * @param old_as_path Treat old blob as if it had this filename; can be NULL
- * @param new_blob Blob for new side of diff, or NULL for empty blob
- * @param new_as_path Treat new blob as if it had this filename; can be NULL
- * @param opts Options for diff, or NULL for default options
- * @return 0 on success or error code < 0
- */
-GIT_EXTERN(int) git_diff_patch_from_blobs(
- git_diff_patch **out,
- const git_blob *old_blob,
- const char *old_as_path,
- const git_blob *new_blob,
- const char *new_as_path,
- const git_diff_options *opts);
-
-/**
* Directly run a diff between a blob and a buffer.
*
* As with `git_diff_blobs`, comparing a blob and buffer lacks some context,
@@ -1048,7 +960,7 @@ GIT_EXTERN(int) git_diff_patch_from_blobs(
* @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 data_cb Callback for each line 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
*/
@@ -1061,35 +973,9 @@ GIT_EXTERN(int) git_diff_blob_to_buffer(
const git_diff_options *options,
git_diff_file_cb file_cb,
git_diff_hunk_cb hunk_cb,
- git_diff_data_cb data_cb,
+ git_diff_line_cb line_cb,
void *payload);
-/**
- * Directly generate a patch from the difference between a blob and a buffer.
- *
- * This is just like `git_diff_blob_to_buffer()` except it generates a patch
- * object for the difference instead of directly making callbacks. You can
- * use the standard `git_diff_patch` accessor functions to read the patch
- * data, and you must call `git_diff_patch_free()` on the patch when done.
- *
- * @param out The generated patch; NULL on error
- * @param old_blob Blob for old side of diff, or NULL for empty blob
- * @param old_as_path Treat old blob as if it had this filename; can be NULL
- * @param buffer Raw data for new side of diff, or NULL for empty
- * @param buffer_len Length of raw data for new side of diff
- * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
- * @param opts Options for diff, or NULL for default options
- * @return 0 on success or error code < 0
- */
-GIT_EXTERN(int) git_diff_patch_from_blob_and_buffer(
- git_diff_patch **out,
- const git_blob *old_blob,
- const char *old_as_path,
- const char *buffer,
- size_t buffer_len,
- const char *buffer_as_path,
- const git_diff_options *opts);
-
GIT_END_DECL
diff --git a/include/git2/errors.h b/include/git2/errors.h
index 2032a436a..be7a31d8e 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -8,6 +8,7 @@
#define INCLUDE_git_errors_h__
#include "common.h"
+#include "buffer.h"
/**
* @file git2/errors.h
@@ -27,11 +28,12 @@ typedef enum {
GIT_EBUFS = -6,
GIT_EUSER = -7,
GIT_EBAREREPO = -8,
- GIT_EORPHANEDHEAD = -9,
+ GIT_EUNBORNBRANCH = -9,
GIT_EUNMERGED = -10,
GIT_ENONFASTFORWARD = -11,
GIT_EINVALIDSPEC = -12,
GIT_EMERGECONFLICT = -13,
+ GIT_ELOCKED = -14,
GIT_PASSTHROUGH = -30,
GIT_ITEROVER = -31,
@@ -44,6 +46,7 @@ typedef struct {
/** Error classes */
typedef enum {
+ GITERR_NONE = 0,
GITERR_NOMEMORY,
GITERR_OS,
GITERR_INVALID,
@@ -66,6 +69,8 @@ typedef enum {
GITERR_CHECKOUT,
GITERR_FETCHHEAD,
GITERR_MERGE,
+ GITERR_SSH,
+ GITERR_FILTER,
} git_error_t;
/**
@@ -82,6 +87,18 @@ GIT_EXTERN(const git_error *) giterr_last(void);
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
+ * cleared as if `giterr_clear` had been called.
+ *
+ * If there was no existing error in the library, -1 will be returned
+ * and the contents of `cpy` will be left unmodified.
+ */
+GIT_EXTERN(int) giterr_detach(git_error *cpy);
+
+/**
* Set the error message string for this thread.
*
* This function is public so that custom ODB backends and the like can
diff --git a/include/git2/filter.h b/include/git2/filter.h
new file mode 100644
index 000000000..f96b6766b
--- /dev/null
+++ b/include/git2/filter.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_filter_h__
+#define INCLUDE_git_filter_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/filter.h
+ * @brief Git filter APIs
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Filters are applied in one of two directions: smudging - which is
+ * exporting a file from the Git object database to the working directory,
+ * and cleaning - which is importing a file from the working directory to
+ * the Git object database. These values control which direction of
+ * change is being applied.
+ */
+typedef enum {
+ GIT_FILTER_TO_WORKTREE = 0,
+ GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE,
+ GIT_FILTER_TO_ODB = 1,
+ GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB,
+} git_filter_mode_t;
+
+/**
+ * A filter that can transform file data
+ *
+ * This represents a filter that can be used to transform or even replace
+ * file data. Libgit2 includes one built in filter and it is possible to
+ * write your own (see git2/sys/filter.h for information on that).
+ *
+ * The two builtin filters are:
+ *
+ * * "crlf" which uses the complex rules with the "text", "eol", and
+ * "crlf" file attributes to decide how to convert between LF and CRLF
+ * line endings
+ * * "ident" which replaces "$Id$" in a blob with "$Id: <blob OID>$" upon
+ * checkout and replaced "$Id: <anything>$" with "$Id$" on checkin.
+ */
+typedef struct git_filter git_filter;
+
+/**
+ * List of filters to be applied
+ *
+ * This represents a list of filters to be applied to a file / blob. You
+ * can build the list with one call, apply it with another, and dispose it
+ * with a third. In typical usage, there are not many occasions where a
+ * git_filter_list is needed directly since the library will generally
+ * handle conversions for you, but it can be convenient to be able to
+ * build and apply the list sometimes.
+ */
+typedef struct git_filter_list git_filter_list;
+
+/**
+ * Load the filter list for a given path.
+ *
+ * This will return 0 (success) but set the output git_filter_list to NULL
+ * if no filters are requested for the given file.
+ *
+ * @param filters Output newly created git_filter_list (or NULL)
+ * @param repo Repository object that contains `path`
+ * @param blob The blob to which the filter will be applied (if known)
+ * @param path Relative path of the file to be filtered
+ * @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @return 0 on success (which could still return NULL if no filters are
+ * needed for the requested file), <0 on error
+ */
+GIT_EXTERN(int) git_filter_list_load(
+ git_filter_list **filters,
+ git_repository *repo,
+ git_blob *blob, /* can be NULL */
+ const char *path,
+ git_filter_mode_t mode);
+
+/**
+ * Apply filter list to a data buffer.
+ *
+ * See `git2/buffer.h` for background on `git_buf` objects.
+ *
+ * If the `in` buffer holds data allocated by libgit2 (i.e. `in->asize` is
+ * not zero), then it will be overwritten when applying the filters. If
+ * not, then it will be left untouched.
+ *
+ * If there are no filters to apply (or `filters` is NULL), then the `out`
+ * buffer will reference the `in` buffer data (with `asize` set to zero)
+ * instead of allocating data. This keeps allocations to a minimum, but
+ * it means you have to be careful about freeing the `in` data since `out`
+ * may be pointing to it!
+ *
+ * @param out Buffer to store the result of the filtering
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param in Buffer containing the data to filter
+ * @return 0 on success, an error code otherwise
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_data(
+ git_buf *out,
+ git_filter_list *filters,
+ git_buf *in);
+
+/**
+ * Apply filter list to the contents of a file on disk
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_file(
+ git_buf *out,
+ git_filter_list *filters,
+ git_repository *repo,
+ const char *path);
+
+/**
+ * Apply filter list to the contents of a blob
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_blob(
+ git_buf *out,
+ git_filter_list *filters,
+ git_blob *blob);
+
+/**
+ * Free a git_filter_list
+ *
+ * @param filters A git_filter_list created by `git_filter_list_load`
+ */
+GIT_EXTERN(void) git_filter_list_free(git_filter_list *filters);
+
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/include/git2/index.h b/include/git2/index.h
index 51694aded..a60db370a 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -120,9 +120,9 @@ typedef struct git_index_entry {
/** Capabilities of system that affect index actions. */
typedef enum {
- GIT_INDEXCAP_IGNORE_CASE = 1,
- GIT_INDEXCAP_NO_FILEMODE = 2,
- GIT_INDEXCAP_NO_SYMLINKS = 4,
+ GIT_INDEXCAP_IGNORE_CASE = 1u,
+ GIT_INDEXCAP_NO_FILEMODE = 2u,
+ GIT_INDEXCAP_NO_SYMLINKS = 4u,
GIT_INDEXCAP_FROM_OWNER = ~0u
} git_indexcap_t;
@@ -138,6 +138,14 @@ typedef enum {
GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2),
} git_index_add_option_t;
+/**
+ * Match any index stage.
+ *
+ * Some index APIs take a stage to match; pass this value to match
+ * any entry matching the path regardless of stage.
+ */
+#define GIT_INDEX_STAGE_ANY -1
+
/** @name Index File Functions
*
* These functions work on the index file itself.
@@ -214,13 +222,23 @@ GIT_EXTERN(unsigned int) git_index_caps(const git_index *index);
GIT_EXTERN(int) git_index_set_caps(git_index *index, unsigned int caps);
/**
- * Update the contents of an existing index object in memory
- * by reading from the hard disk.
+ * Update the contents of an existing index object in memory by reading
+ * from the hard disk.
+ *
+ * If `force` is true, this performs a "hard" read that discards in-memory
+ * changes and always reloads the on-disk index data. If there is no
+ * on-disk version, the index will be cleared.
+ *
+ * If `force` is false, this does a "soft" read that reloads the index
+ * data from disk only if it has changed since the last time it was
+ * loaded. Purely in-memory index data will be untouched. Be aware: if
+ * there are changes on disk, unwritten in-memory changes are discarded.
*
* @param index an existing index object
+ * @param force if true, always reload, vs. only read if file has changed
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_index_read(git_index *index);
+GIT_EXTERN(int) git_index_read(git_index *index, int force);
/**
* Write an existing index object from memory back to disk
@@ -232,6 +250,14 @@ GIT_EXTERN(int) git_index_read(git_index *index);
GIT_EXTERN(int) git_index_write(git_index *index);
/**
+ * Get the full path to the index file on disk.
+ *
+ * @param index an existing index object
+ * @return path to index file or NULL for in-memory index
+ */
+GIT_EXTERN(const char *) git_index_path(git_index *index);
+
+/**
* Read a tree into the index file with stats
*
* The current index contents will be replaced by the specified tree.
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index 4db072c9b..e4c03ad06 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -13,19 +13,25 @@
GIT_BEGIN_DECL
-typedef struct git_indexer_stream git_indexer_stream;
+typedef struct git_indexer git_indexer;
/**
- * Create a new streaming indexer instance
+ * Create a new indexer instance
*
* @param out where to store the indexer instance
* @param path to the directory where the packfile should be stored
+ * @param mode permissions to use creating packfile or 0 for defaults
+ * @param odb object database from which to read base objects when
+ * fixing thin packs. Pass NULL if no thin pack is expected (an error
+ * will be returned if there are bases missing)
* @param progress_cb function to call with progress information
* @param progress_cb_payload payload for the progress callback
*/
-GIT_EXTERN(int) git_indexer_stream_new(
- git_indexer_stream **out,
+GIT_EXTERN(int) git_indexer_new(
+ git_indexer **out,
const char *path,
+ unsigned int mode,
+ git_odb *odb,
git_transfer_progress_callback progress_cb,
void *progress_cb_payload);
@@ -37,7 +43,7 @@ GIT_EXTERN(int) git_indexer_stream_new(
* @param size the size of the data in bytes
* @param stats stat storage
*/
-GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_transfer_progress *stats);
+GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats);
/**
* Finalize the pack and index
@@ -46,7 +52,7 @@ GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data
*
* @param idx the indexer
*/
-GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress *stats);
+GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_transfer_progress *stats);
/**
* Get the packfile's hash
@@ -56,14 +62,14 @@ GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_transfe
*
* @param idx the indexer instance
*/
-GIT_EXTERN(const git_oid *) git_indexer_stream_hash(const git_indexer_stream *idx);
+GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx);
/**
* Free the indexer and its resources
*
* @param idx the indexer to free
*/
-GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx);
+GIT_EXTERN(void) git_indexer_free(git_indexer *idx);
GIT_END_DECL
diff --git a/include/git2/merge.h b/include/git2/merge.h
index cef6f775b..3354fbeab 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -7,11 +7,11 @@
#ifndef INCLUDE_git_merge_h__
#define INCLUDE_git_merge_h__
-#include "git2/common.h"
-#include "git2/types.h"
-#include "git2/oid.h"
-#include "git2/checkout.h"
-#include "git2/index.h"
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "checkout.h"
+#include "index.h"
/**
* @file git2/merge.h
@@ -66,6 +66,29 @@ typedef struct {
/**
+ * Option flags for `git_merge`.
+ *
+ * GIT_MERGE_NO_FASTFORWARD - Do not fast-forward.
+ */
+typedef enum {
+ GIT_MERGE_NO_FASTFORWARD = 1,
+ GIT_MERGE_FASTFORWARD_ONLY = 2,
+} git_merge_flags_t;
+
+typedef struct {
+ unsigned int version;
+
+ git_merge_flags_t merge_flags;
+ git_merge_tree_opts merge_tree_opts;
+
+ git_checkout_opts checkout_opts;
+} git_merge_opts;
+
+#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}
+
+
+/**
* Find a merge base between two commits
*
* @param out the OID of a merge base between 'one' and 'two'
@@ -85,15 +108,15 @@ GIT_EXTERN(int) git_merge_base(
*
* @param out the OID of a merge base considering all the commits
* @param repo the repository where the commits exist
- * @param input_array oids of the commits
* @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
* @return Zero on success; GIT_ENOTFOUND or -1 on failure.
*/
GIT_EXTERN(int) git_merge_base_many(
git_oid *out,
git_repository *repo,
- const git_oid input_array[],
- size_t length);
+ size_t length,
+ const git_oid input_array[]);
/**
* Creates a `git_merge_head` from the given reference
@@ -168,6 +191,43 @@ GIT_EXTERN(int) git_merge_trees(
const git_tree *their_tree,
const git_merge_tree_opts *opts);
+/**
+ * Merges the given commits into HEAD, producing a new commit.
+ *
+ * @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
+ */
+GIT_EXTERN(int) git_merge(
+ git_merge_result **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);
+
+/**
+ * Gets the fast-forward OID if the merge was a fastforward.
+ *
+ * @param out the OID of the fast-forward
+ * @param merge_result the results of the merge
+ */
+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_END_DECL
#endif
diff --git a/include/git2/notes.h b/include/git2/notes.h
index 7382904ad..76361633b 100644
--- a/include/git2/notes.h
+++ b/include/git2/notes.h
@@ -99,7 +99,7 @@ GIT_EXTERN(int) git_note_read(
/**
* Get the note message
*
- * @param note
+ * @param note the note
* @return the note message
*/
GIT_EXTERN(const char *) git_note_message(const git_note *note);
@@ -108,7 +108,7 @@ GIT_EXTERN(const char *) git_note_message(const git_note *note);
/**
* Get the note object OID
*
- * @param note
+ * @param note the note
* @return the note object OID
*/
GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note);
diff --git a/include/git2/object.h b/include/git2/object.h
index b91b04dba..c40631fa6 100644
--- a/include/git2/object.h
+++ b/include/git2/object.h
@@ -36,7 +36,7 @@ GIT_BEGIN_DECL
* @param repo the repository to look up the object
* @param id the unique identifier for the object
* @param type the type of the object
- * @return a reference to the object
+ * @return 0 or an error code
*/
GIT_EXTERN(int) git_object_lookup(
git_object **object,
@@ -78,6 +78,23 @@ GIT_EXTERN(int) git_object_lookup_prefix(
size_t len,
git_otype type);
+
+/**
+ * Lookup an object that represents a tree entry.
+ *
+ * @param out buffer that receives a pointer to the object (which must be freed
+ * by the caller)
+ * @param treeish root object that can be peeled to a tree
+ * @param path relative path from the root object to the desired object
+ * @param type type of object desired
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_object_lookup_bypath(
+ git_object **out,
+ const git_object *treeish,
+ const char *path,
+ git_otype type);
+
/**
* Get the id (SHA1) of a repository object
*
diff --git a/include/git2/odb.h b/include/git2/odb.h
index b64436c4d..ad56384f0 100644
--- a/include/git2/odb.h
+++ b/include/git2/odb.h
@@ -120,7 +120,7 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i
* @param db database to search for the object in.
* @param short_id a prefix of the id of the object to read.
* @param len the length of the prefix
- * @return
+ * @return
* - 0 if the object was read;
* - GIT_ENOTFOUND if the object is not in the database.
* - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)
@@ -219,18 +219,12 @@ GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size
* The type and final length of the object must be specified
* when opening the stream.
*
- * The returned stream will be of type `GIT_STREAM_WRONLY` and
- * will have the following methods:
- *
- * - stream->write: write `n` bytes into the stream
- * - stream->finalize_write: close the stream and store the object in
- * the odb
- * - stream->free: free the stream
- *
- * The streaming write won't be effective until `stream->finalize_write`
- * is called and returns without an error
+ * The returned stream will be of type `GIT_STREAM_WRONLY`, and it
+ * won't be effective until `git_odb_stream_finalize_write` is called
+ * and returns without an error
*
- * The stream must always be free'd or will leak memory.
+ * The stream must always be freed when done with `git_odb_stream_free` or
+ * will leak memory.
*
* @see git_odb_stream
*
@@ -243,6 +237,48 @@ GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size
GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type);
/**
+ * Write to an odb stream
+ *
+ * This method will fail if the total number of received bytes exceeds the
+ * size declared with `git_odb_open_wstream()`
+ *
+ * @param stream the stream
+ * @param buffer the data to write
+ * @param len the buffer's length
+ * @return 0 if the write succeeded; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len);
+
+/**
+ * Finish writing to an odb stream
+ *
+ * The object will take its final name and will be available to the
+ * odb.
+ *
+ * This method will fail if the total number of received bytes
+ * differs from the size declared with `git_odb_open_wstream()`
+ *
+ * @param out pointer to store the resulting object's id
+ * @param stream the stream
+ * @return 0 on success; an error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream);
+
+/**
+ * Read from an odb stream
+ *
+ * Most backends don't implement streaming reads
+ */
+GIT_EXTERN(int) git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len);
+
+/**
+ * Free an odb stream
+ *
+ * @param stream the stream to free
+ */
+GIT_EXTERN(void) git_odb_stream_free(git_odb_stream *stream);
+
+/**
* Open a stream to read an object from the ODB
*
* Note that most backends do *not* support streaming reads
@@ -322,6 +358,20 @@ GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_oty
GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_otype type);
/**
+ * Create a copy of an odb_object
+ *
+ * The returned copy must be manually freed with `git_odb_object_free`.
+ * Note that because of an implementation detail, the returned copy will be
+ * the same pointer as `source`: the object is internally refcounted, so the
+ * copy still needs to be freed twice.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_object_dup(git_odb_object **dest, git_odb_object *source);
+
+/**
* Close an ODB object
*
* This method must always be called once a `git_odb_object` is no
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index af1e3e5b9..4d772cab9 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -7,8 +7,8 @@
#ifndef INCLUDE_git_odb_backend_h__
#define INCLUDE_git_odb_backend_h__
-#include "git2/common.h"
-#include "git2/types.h"
+#include "common.h"
+#include "types.h"
/**
* @file git2/backend.h
@@ -40,10 +40,18 @@ GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_
* @param objects_dir the Git repository's objects directory
* @param compression_level zlib compression level to use
* @param do_fsync whether to do an fsync() after writing (currently ignored)
+ * @param dir_mode permissions to use creating a directory or 0 for defaults
+ * @param file_mode permissions to use creating a file or 0 for defaults
*
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync);
+GIT_EXTERN(int) git_odb_backend_loose(
+ git_odb_backend **out,
+ const char *objects_dir,
+ int compression_level,
+ int do_fsync,
+ unsigned int dir_mode,
+ unsigned int file_mode);
/**
* Create a backend out of a single packfile
@@ -65,14 +73,50 @@ typedef enum {
GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
} git_odb_stream_t;
-/** A stream to read/write from a backend */
+/**
+ * A stream to read/write from a backend.
+ *
+ * This represents a stream of data being written to or read from a
+ * backend. When writing, the frontend functions take care of
+ * calculating the object's id and all `finalize_write` needs to do is
+ * store the object with the id it is passed.
+ */
struct git_odb_stream {
git_odb_backend *backend;
unsigned int mode;
+ void *hash_ctx;
+
+ size_t declared_size;
+ size_t received_bytes;
+ /**
+ * Write at most `len` bytes into `buffer` and advance the stream.
+ */
int (*read)(git_odb_stream *stream, char *buffer, size_t len);
+
+ /**
+ * Write `len` bytes from `buffer` into the stream.
+ */
int (*write)(git_odb_stream *stream, const char *buffer, size_t len);
- int (*finalize_write)(git_oid *oid_p, git_odb_stream *stream);
+
+ /**
+ * Store the contents of the stream as an object with the id
+ * specified in `oid`.
+ *
+ * This method might not be invoked if:
+ * - an error occurs earlier with the `write` callback,
+ * - the object referred to by `oid` already exists in any backend, or
+ * - the final number of received bytes differs from the size declared
+ * with `git_odb_open_wstream()`
+ */
+ int (*finalize_write)(git_odb_stream *stream, const git_oid *oid);
+
+ /**
+ * Free the stream's memory.
+ *
+ * This method might be called without a call to `finalize_write` if
+ * an error occurs or if the object is already present in the ODB.
+ */
void (*free)(git_odb_stream *stream);
};
@@ -80,7 +124,7 @@ struct git_odb_stream {
struct git_odb_writepack {
git_odb_backend *backend;
- int (*add)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
+ int (*append)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
int (*commit)(git_odb_writepack *writepack, git_transfer_progress *stats);
void (*free)(git_odb_writepack *writepack);
};
diff --git a/include/git2/oid.h b/include/git2/oid.h
index 662338d93..384b656d7 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -188,8 +188,7 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
*
* @param id oid structure.
* @param str input hex string of an object id.
- * @return GIT_ENOTOID if str is not a valid hex string,
- * 0 in case of a match, GIT_ERROR otherwise.
+ * @return 0 in case of a match, -1 otherwise.
*/
GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
@@ -241,13 +240,13 @@ GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
* or freed.
*
* For performance reasons, there is a hard-limit of how many
- * OIDs can be added to a single set (around ~22000, assuming
+ * OIDs can be added to a single set (around ~32000, assuming
* a mostly randomized distribution), which should be enough
* for any kind of program, and keeps the algorithm fast and
* memory-efficient.
*
* Attempting to add more than those OIDs will result in a
- * GIT_ENOMEM error
+ * GITERR_INVALID error
*
* @param os a `git_oid_shorten` instance
* @param text_id an OID in text form
diff --git a/include/git2/pack.h b/include/git2/pack.h
index cc1f48add..88a2716bb 100644
--- a/include/git2/pack.h
+++ b/include/git2/pack.h
@@ -38,7 +38,7 @@
* `git_packbuilder_set_threads` can be used to adjust the number of
* threads used for the process.
*
- * See tests-clar/pack/packbuilder.c for an example.
+ * See tests/pack/packbuilder.c for an example.
*
* @ingroup Git
* @{
@@ -46,6 +46,14 @@
GIT_BEGIN_DECL
/**
+ * Stages that are reported by the packbuilder progress callback.
+ */
+typedef enum {
+ GIT_PACKBUILDER_ADDING_OBJECTS = 0,
+ GIT_PACKBUILDER_DELTAFICATION = 1,
+} git_packbuilder_stage_t;
+
+/**
* Initialize a new packbuilder
*
* @param out The new packbuilder object
@@ -111,6 +119,7 @@ GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid
*
* @param pb The packbuilder
* @param path to the directory where the packfile and index should be stored
+ * @param mode permissions to use creating a packfile or 0 for defaults
* @param progress_cb function to call with progress information from the indexer (optional)
* @param progress_cb_payload payload for the progress callback (optional)
*
@@ -119,9 +128,20 @@ GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid
GIT_EXTERN(int) git_packbuilder_write(
git_packbuilder *pb,
const char *path,
+ unsigned int mode,
git_transfer_progress_callback progress_cb,
void *progress_cb_payload);
+/**
+* Get the packfile's hash
+*
+* A packfile's name is derived from the sorted hashing of all object
+* names. This is only correct after the packfile has been written.
+*
+* @param pb The packbuilder object
+*/
+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
@@ -137,7 +157,7 @@ GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_for
* Get the total number of objects the packbuilder will write out
*
* @param pb the packbuilder
- * @return
+ * @return the number of objects in the packfile
*/
GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
@@ -145,10 +165,32 @@ GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
* Get the number of objects the packbuilder has already written out
*
* @param pb the packbuilder
- * @return
+ * @return the number of objects which have already been written
*/
GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb);
+/** Packbuilder progress notification function */
+typedef int (*git_packbuilder_progress)(
+ int stage,
+ unsigned int current,
+ unsigned int total,
+ void *payload);
+
+/**
+ * Set the callbacks for a packbuilder
+ *
+ * @param pb The packbuilder object
+ * @param progress_cb Function to call with progress information during
+ * pack building. Be aware that this is called inline with pack building
+ * operations, so performance may be affected.
+ * @param progress_cb_payload Payload for progress callback.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_set_callbacks(
+ git_packbuilder *pb,
+ git_packbuilder_progress progress_cb,
+ void *progress_cb_payload);
+
/**
* Free the packbuilder and all associated data
*
diff --git a/include/git2/patch.h b/include/git2/patch.h
new file mode 100644
index 000000000..6a6ad92d7
--- /dev/null
+++ b/include/git2/patch.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_patch_h__
+#define INCLUDE_git_patch_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "diff.h"
+
+/**
+ * @file git2/patch.h
+ * @brief Patch handling routines.
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The diff patch is used to store all the text diffs for a delta.
+ *
+ * You can easily loop over the content of patches and get information about
+ * them.
+ */
+typedef struct git_patch git_patch;
+
+/**
+ * Return the diff delta and patch for an entry in the diff list.
+ *
+ * The `git_patch` is a newly created object contains the text diffs
+ * for the delta. You have to call `git_patch_free()` when you are
+ * done with it. You can use the patch object to loop over all the hunks
+ * and lines in the diff of the one delta.
+ *
+ * For an unchanged file or a binary file, no `git_patch` will be
+ * created, the output will be set to NULL, and the `binary` flag will be
+ * set true in the `git_diff_delta` structure.
+ *
+ * The `git_diff_delta` pointer points to internal data and you do not have
+ * to release it when you are done with it. It will go away when the
+ * `git_diff` and `git_patch` go away.
+ *
+ * It is okay to pass NULL for either of the output parameters; if you pass
+ * NULL for the `git_patch`, then the text diff will not be calculated.
+ *
+ * @param out Output parameter for the delta patch object
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return 0 on success, other value < 0 on error
+ */
+GIT_EXTERN(int) git_patch_from_diff(
+ git_patch **out, git_diff *diff, size_t idx);
+
+/**
+ * Directly generate a patch from the difference between two blobs.
+ *
+ * This is just like `git_diff_blobs()` except it generates a patch object
+ * for the difference instead of directly making callbacks. You can use the
+ * standard `git_patch` accessor functions to read the patch data, and
+ * you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param new_as_path Treat new blob as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blobs(
+ git_patch **out,
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const git_blob *new_blob,
+ const char *new_as_path,
+ const git_diff_options *opts);
+
+/**
+ * Directly generate a patch from the difference between a blob and a buffer.
+ *
+ * This is just like `git_diff_blob_to_buffer()` except it generates a patch
+ * object for the difference instead of directly making callbacks. You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param buffer Raw data for new side of diff, or NULL for empty
+ * @param buffer_len Length of raw data for new side of diff
+ * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blob_and_buffer(
+ git_patch **out,
+ const git_blob *old_blob,
+ const char *old_as_path,
+ const char *buffer,
+ size_t buffer_len,
+ const char *buffer_as_path,
+ const git_diff_options *opts);
+
+/**
+ * Free a git_patch object.
+ */
+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);
+
+/**
+ * Get the number of hunks in a patch
+ */
+GIT_EXTERN(size_t) git_patch_num_hunks(git_patch *patch);
+
+/**
+ * Get line counts of each type in a patch.
+ *
+ * This helps imitate a diff --numstat type of output. For that purpose,
+ * you only need the `total_additions` and `total_deletions` values, but we
+ * include the `total_context` line count in case you want the total number
+ * of lines of diff output that will be generated.
+ *
+ * All outputs are optional. Pass NULL if you don't need a particular count.
+ *
+ * @param total_context Count of context lines in output, can be NULL.
+ * @param total_additions Count of addition lines in output, can be NULL.
+ * @param total_deletions Count of deletion lines in output, can be NULL.
+ * @param patch The git_patch object
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_patch_line_stats(
+ size_t *total_context,
+ size_t *total_additions,
+ size_t *total_deletions,
+ const git_patch *patch);
+
+/**
+ * Get the information about a hunk in a patch
+ *
+ * Given a patch and a hunk index into the patch, this returns detailed
+ * information about that hunk. Any of the output pointers can be passed
+ * as NULL if you don't care about that particular piece of information.
+ *
+ * @param out Output pointer to git_diff_hunk of hunk
+ * @param lines_in_hunk Output count of total lines in this hunk
+ * @param patch Input pointer to patch object
+ * @param hunk_idx Input index of hunk to get information about
+ * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error
+ */
+GIT_EXTERN(int) git_patch_get_hunk(
+ const git_diff_hunk **out,
+ size_t *lines_in_hunk,
+ git_patch *patch,
+ size_t hunk_idx);
+
+/**
+ * Get the number of lines in a hunk.
+ *
+ * @param patch The git_patch object
+ * @param hunk_idx Index of the hunk
+ * @return Number of lines in hunk or -1 if invalid hunk index
+ */
+GIT_EXTERN(int) git_patch_num_lines_in_hunk(
+ git_patch *patch,
+ size_t hunk_idx);
+
+/**
+ * Get data about a line in a hunk of a patch.
+ *
+ * Given a patch, a hunk index, and a line index in the hunk, this
+ * will return a lot of details about that line. If you pass a hunk
+ * index larger than the number of hunks or a line index larger than
+ * the number of lines in the hunk, this will return -1.
+ *
+ * @param out The git_diff_line data for this line
+ * @param patch The patch to look in
+ * @param hunk_idx The index of the hunk
+ * @param line_of_hunk The index of the line in the hunk
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_patch_get_line_in_hunk(
+ const git_diff_line **out,
+ git_patch *patch,
+ size_t hunk_idx,
+ size_t line_of_hunk);
+
+/**
+ * Look up size of patch diff data in bytes
+ *
+ * This returns the raw size of the patch data. This only includes the
+ * actual data from the lines of the diff, not the file or hunk headers.
+ *
+ * If you pass `include_context` as true (non-zero), this will be the size
+ * of all of the diff output; if you pass it as false (zero), this will
+ * only include the actual changed lines (as if `context_lines` was 0).
+ *
+ * @param patch A git_patch representing changes to one file
+ * @param include_context Include context lines in size if non-zero
+ * @param include_hunk_headers Include hunk header lines if non-zero
+ * @param include_file_headers Include file header lines if non-zero
+ * @return The number of bytes of data
+ */
+GIT_EXTERN(size_t) git_patch_size(
+ git_patch *patch,
+ int include_context,
+ int include_hunk_headers,
+ int include_file_headers);
+
+/**
+ * Serialize the patch to text via callback.
+ *
+ * Returning a non-zero value from the callback will terminate the iteration
+ * and cause this return `GIT_EUSER`.
+ *
+ * @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
+ */
+GIT_EXTERN(int) git_patch_print(
+ git_patch *patch,
+ git_diff_line_cb print_cb,
+ void *payload);
+
+/**
+ * Get the content of a patch as a single diff text.
+ *
+ * @param string Allocated string; caller must free.
+ * @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_patch *patch);
+
+
+GIT_END_DECL
+
+/**@}*/
+
+#endif
diff --git a/include/git2/pathspec.h b/include/git2/pathspec.h
new file mode 100644
index 000000000..2fb0bb716
--- /dev/null
+++ b/include/git2/pathspec.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_pathspec_h__
+#define INCLUDE_git_pathspec_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "diff.h"
+
+/**
+ * Compiled pathspec
+ */
+typedef struct git_pathspec git_pathspec;
+
+/**
+ * List of filenames matching a pathspec
+ */
+typedef struct git_pathspec_match_list git_pathspec_match_list;
+
+/**
+ * Options controlling how pathspec match should be executed
+ *
+ * - GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
+ * match will use native case sensitivity of platform filesystem
+ * - GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
+ * match will use native case sensitivity of platform filesystem
+ * - GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
+ * string comparison for matching
+ * - GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
+ * code GIT_ENOTFOUND if no matches are found; otherwise no matches is
+ * still success (return 0) but `git_pathspec_match_list_entrycount`
+ * will indicate 0 matches.
+ * - GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
+ * should track which patterns matched which files so that at the end of
+ * the match we can identify patterns that did not match any files.
+ * - GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
+ * does not need to keep the actual matching filenames. Use this to
+ * just test if there were any matches at all or in combination with
+ * GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
+ */
+typedef enum {
+ GIT_PATHSPEC_DEFAULT = 0,
+ GIT_PATHSPEC_IGNORE_CASE = (1u << 0),
+ GIT_PATHSPEC_USE_CASE = (1u << 1),
+ GIT_PATHSPEC_NO_GLOB = (1u << 2),
+ GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
+ GIT_PATHSPEC_FIND_FAILURES = (1u << 4),
+ GIT_PATHSPEC_FAILURES_ONLY = (1u << 5),
+} git_pathspec_flag_t;
+
+/**
+ * Compile a pathspec
+ *
+ * @param out Output of the compiled pathspec
+ * @param pathspec A git_strarray of the paths to match
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_pathspec_new(
+ git_pathspec **out, const git_strarray *pathspec);
+
+/**
+ * Free a pathspec
+ *
+ * @param ps The compiled pathspec
+ */
+GIT_EXTERN(void) git_pathspec_free(git_pathspec *ps);
+
+/**
+ * Try to match a path against a pathspec
+ *
+ * Unlike most of the other pathspec matching functions, this will not
+ * fall back on the native case-sensitivity for your platform. You must
+ * explicitly pass flags to control case sensitivity or else this will
+ * fall back on being case sensitive.
+ *
+ * @param ps The compiled pathspec
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param path The pathname to attempt to match
+ * @return 1 is path matches spec, 0 if it does not
+ */
+GIT_EXTERN(int) git_pathspec_matches_path(
+ const git_pathspec *ps, uint32_t flags, const char *path);
+
+/**
+ * Match a pathspec against the working directory of a repository.
+ *
+ * This matches the pathspec against the current files in the working
+ * directory of the repository. It is an error to invoke this on a bare
+ * repo. This handles git ignores (i.e. ignored files will not be
+ * considered to match the `pathspec` unless the file is tracked in the
+ * index).
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param repo The repository in which to match; bare repo is an error
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag was given
+ */
+GIT_EXTERN(int) git_pathspec_match_workdir(
+ git_pathspec_match_list **out,
+ git_repository *repo,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against entries in an index.
+ *
+ * This matches the pathspec against the files in the repository index.
+ *
+ * NOTE: At the moment, the case sensitivity of this match is controlled
+ * by the current case-sensitivity of the index object itself and the
+ * USE_CASE and IGNORE_CASE flags will have no effect. This behavior will
+ * be corrected in a future release.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param index The index to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_index(
+ git_pathspec_match_list **out,
+ git_index *index,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a tree.
+ *
+ * This matches the pathspec against the files in the given tree.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param tree The root-level tree to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_tree(
+ git_pathspec_match_list **out,
+ git_tree *tree,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a diff list.
+ *
+ * This matches the pathspec against the files in the given diff list.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`. That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag). You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param diff A generated diff list
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ * the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_diff(
+ git_pathspec_match_list **out,
+ git_diff *diff,
+ uint32_t flags,
+ git_pathspec *ps);
+
+/**
+ * Free memory associates with a git_pathspec_match_list
+ *
+ * @param m The git_pathspec_match_list to be freed
+ */
+GIT_EXTERN(void) git_pathspec_match_list_free(git_pathspec_match_list *m);
+
+/**
+ * Get the number of items in a match list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in match list
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_entrycount(
+ const git_pathspec_match_list *m);
+
+/**
+ * Get a matching filename by position.
+ *
+ * This routine cannot be used if the match list was generated by
+ * `git_pathspec_match_diff`. If so, it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get a matching diff delta by position.
+ *
+ * This routine can only be used if the match list was generated by
+ * `git_pathspec_match_diff`. Otherwise it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const git_diff_delta *) git_pathspec_match_list_diff_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get the number of pathspec items that did not match.
+ *
+ * This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when
+ * generating the git_pathspec_match_list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in original pathspec that had no matches
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
+ const git_pathspec_match_list *m);
+
+/**
+ * Get an original pathspec string that had no matches.
+ *
+ * This will be return NULL for positions out of range.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the failed items
+ * @return The pathspec pattern that didn't match anything
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
+ const git_pathspec_match_list *m, size_t pos);
+
+#endif
diff --git a/include/git2/push.h b/include/git2/push.h
index f92308144..77ef74039 100644
--- a/include/git2/push.h
+++ b/include/git2/push.h
@@ -8,6 +8,7 @@
#define INCLUDE_git_push_h__
#include "common.h"
+#include "pack.h"
/**
* @file git2/push.h
@@ -38,6 +39,13 @@ typedef struct {
#define GIT_PUSH_OPTIONS_VERSION 1
#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION }
+/** Push network progress notification function */
+typedef int (*git_push_transfer_progress)(
+ unsigned int current,
+ unsigned int total,
+ size_t bytes,
+ void* payload);
+
/**
* Create a new push object
*
@@ -61,6 +69,27 @@ GIT_EXTERN(int) git_push_set_options(
const git_push_options *opts);
/**
+ * Set the callbacks for a push
+ *
+ * @param push The push object
+ * @param pack_progress_cb Function to call with progress information during
+ * pack building. Be aware that this is called inline with pack building
+ * operations, so performance may be affected.
+ * @param pack_progress_cb_payload Payload for the pack progress callback.
+ * @param transfer_progress_cb Function to call with progress information during
+ * the upload portion of a push. Be aware that this is called inline with
+ * pack building operations, so performance may be affected.
+ * @param transfer_progress_cb_payload Payload for the network progress callback.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_set_callbacks(
+ git_push *push,
+ git_packbuilder_progress pack_progress_cb,
+ void *pack_progress_cb_payload,
+ git_push_transfer_progress transfer_progress_cb,
+ void *transfer_progress_cb_payload);
+
+/**
* Add a refspec to be pushed
*
* @param push The push object
@@ -98,7 +127,7 @@ GIT_EXTERN(int) git_push_finish(git_push *push);
*
* @param push The push object
*
- * @return true if equal, false otherwise
+ * @return true if remote side successfully unpacked, false otherwise
*/
GIT_EXTERN(int) git_push_unpack_ok(git_push *push);
diff --git a/include/git2/reflog.h b/include/git2/reflog.h
index 4944530af..2d1b6eeaa 100644
--- a/include/git2/reflog.h
+++ b/include/git2/reflog.h
@@ -31,10 +31,11 @@ GIT_BEGIN_DECL
* git_reflog_free().
*
* @param out pointer to reflog
- * @param ref reference to read the reflog for
+ * @param repo the repostiory
+ * @param name reference to look up
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reflog_read(git_reflog **out, const git_reference *ref);
+GIT_EXTERN(int) git_reflog_read(git_reflog **out, git_repository *repo, const char *name);
/**
* Write an existing in-memory reflog object back to disk
@@ -59,26 +60,45 @@ 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);
/**
- * Rename the reflog for the given reference
+ * 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
*
* The new name will be checked for validity.
* See `git_reference_create_symbolic()` for rules about valid names.
*
- * @param ref the reference
- * @param name the new name of the reference
+ * @param repo the repository
+ * @param old_name the old name of the reference
+ * @param new_name the new name of the reference
* @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name);
+GIT_EXTERN(int) git_reflog_rename(git_repository *repo, const char *old_name, const char *name);
/**
* Delete the reflog for the given reference
*
- * @param ref the reference
+ * @param repo the repository
+ * @param name the reflog to delete
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reflog_delete(git_reference *ref);
+GIT_EXTERN(int) git_reflog_delete(git_repository *repo, const char *name);
/**
* Get the number of log entries in a reflog
diff --git a/include/git2/refs.h b/include/git2/refs.h
index 795f7ab27..4041947f6 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -32,7 +32,7 @@ GIT_BEGIN_DECL
* @param out pointer to the looked-up reference
* @param repo the repository to look up the reference
* @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
- * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
*/
GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name);
@@ -49,7 +49,7 @@ GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo,
* @param out Pointer to oid to be filled in
* @param repo The repository in which to look up the reference
* @param name The long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
- * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
*/
GIT_EXTERN(int) git_reference_name_to_id(
git_oid *out, git_repository *repo, const char *name);
@@ -94,7 +94,7 @@ GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, co
* @param name The name of the reference
* @param target The target of the reference
* @param force Overwrite existing references
- * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
+ * @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);
@@ -126,7 +126,7 @@ GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repositor
* @param name The name of the reference
* @param id The object id pointed to by the reference.
* @param force Overwrite existing references
- * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
+ * @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);
@@ -225,7 +225,7 @@ GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
* @param out Pointer to the newly created reference
* @param ref The reference
* @param target The new target for the reference
- * @return 0 on success, EINVALIDSPEC or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_reference_symbolic_set_target(
git_reference **out,
@@ -268,7 +268,7 @@ 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
- * @return 0 on success, EINVALIDSPEC, EEXISTS or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
*
*/
GIT_EXTERN(int) git_reference_rename(
@@ -442,9 +442,18 @@ GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
*/
GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
+/**
+ * Check if a reference is a tag
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/tags
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_tag(git_reference *ref);
typedef enum {
- GIT_REF_FORMAT_NORMAL = 0,
+ GIT_REF_FORMAT_NORMAL = 0u,
/**
* Control whether one-level refnames are accepted
@@ -452,7 +461,7 @@ typedef enum {
* components). Those are expected to be written only using
* uppercase letters and underscore (FETCH_HEAD, ...)
*/
- GIT_REF_FORMAT_ALLOW_ONELEVEL = (1 << 0),
+ GIT_REF_FORMAT_ALLOW_ONELEVEL = (1u << 0),
/**
* Interpret the provided name as a reference pattern for a
@@ -461,14 +470,14 @@ typedef enum {
* in place of a one full pathname component
* (e.g., foo/<star>/bar but not foo/bar<star>).
*/
- GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1),
+ GIT_REF_FORMAT_REFSPEC_PATTERN = (1u << 1),
/**
* Interpret the name as part of a refspec in shorthand form
* so the `ONELEVEL` naming rules aren't enforced and 'master'
* becomes a valid name.
*/
- GIT_REF_FORMAT_REFSPEC_SHORTHAND = (1 << 2),
+ GIT_REF_FORMAT_REFSPEC_SHORTHAND = (1u << 2),
} git_reference_normalize_t;
/**
@@ -488,7 +497,7 @@ typedef enum {
* @param name Reference name to be checked.
* @param flags Flags to constrain name validation rules - see the
* GIT_REF_FORMAT constants above.
- * @return 0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC
+ * @return 0 on success, GIT_EBUFS if buffer is too small, GIT_EINVALIDSPEC
* or an error code.
*/
GIT_EXTERN(int) git_reference_normalize_name(
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 45d15d0a3..7410909dc 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -25,13 +25,6 @@
GIT_BEGIN_DECL
typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload);
-/*
- * TODO: This functions still need to be implemented:
- * - _listcb/_foreach
- * - _add
- * - _rename
- * - _del (needs support from config)
- */
/**
* Add a remote with the default fetch refspec to the repository's configuration. This
@@ -50,6 +43,25 @@ GIT_EXTERN(int) git_remote_create(
const char *url);
/**
+ * Add a remote with the provided fetch refspec (or default if NULL) to the repository's
+ * configuration. This
+ * calls git_remote_save before returning.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @param fetch the remote fetch value
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create_with_fetchspec(
+ git_remote **out,
+ git_repository *repo,
+ const char *name,
+ const char *url,
+ const char *fetch);
+
+/**
* Create a remote in memory
*
* Create a remote with the given refspec in memory. You can use
@@ -61,7 +73,7 @@ GIT_EXTERN(int) git_remote_create(
*
* @param out pointer to the new remote object
* @param repo the associated repository
- * @param fetch the fetch refspec to use for this remote. May be NULL for defaults.
+ * @param fetch the fetch refspec to use for this remote.
* @param url the remote repository's URL
* @return 0 or an error code
*/
@@ -96,6 +108,14 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
/**
+ * Get the remote's repository
+ *
+ * @param remote the remote
+ * @return a pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_remote_owner(const git_remote *remote);
+
+/**
* Get the remote's name
*
* @param remote the remote
@@ -144,8 +164,11 @@ GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
/**
* Add a fetch refspec to the remote
*
+ * Convenience function for adding a single fetch refspec to the
+ * current list in the remote.
+ *
* @param remote the remote
- * @apram refspec the new fetch refspec
+ * @param refspec the new fetch refspec
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
@@ -162,8 +185,21 @@ GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote);
/**
+ * Set the remote's list of fetch refspecs
+ *
+ * The contents of the string array are copied.
+ *
+ * @param remote the remote to modify
+ * @param array the new list of fetch resfpecs
+ */
+GIT_EXTERN(int) git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array);
+
+/**
* Add a push refspec to the remote
*
+ * Convenience function for adding a single push refspec to the
+ * current list in the remote.
+ *
* @param remote the remote
* @param refspec the new push refspec
* @return 0 or an error value
@@ -182,6 +218,16 @@ GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *remote);
/**
+ * Set the remote's list of push refspecs
+ *
+ * The contents of the string array are copied.
+ *
+ * @param remote the remote to modify
+ * @param array the new list of push resfpecs
+ */
+GIT_EXTERN(int) git_remote_set_push_refspecs(git_remote *remote, git_strarray *array);
+
+/**
* Clear the refspecs
*
* Remove all configured fetch and push refspecs from the remote.
@@ -208,15 +254,6 @@ GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote);
GIT_EXTERN(const git_refspec *)git_remote_get_refspec(git_remote *remote, size_t n);
/**
- * Remove a refspec from the remote
- *
- * @param remote the remote to query
- * @param n the refspec to remove
- * @return 0 or GIT_ENOTFOUND
- */
-GIT_EXTERN(int) git_remote_remove_refspec(git_remote *remote, size_t n);
-
-/**
* Open a connection to a remote
*
* The transport is selected based on the URL. The direction argument
@@ -236,36 +273,30 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
* The remote (or more exactly its transport) must be connected. The
* memory belongs to the remote.
*
- * If you a return a non-zero value from the callback, this will stop
- * looping over the refs.
+ * The array will stay valid as long as the remote object exists and
+ * its transport isn't changed, but a copy is recommended for usage of
+ * the data.
*
+ * @param out pointer to the array
+ * @param size the number of remote heads
* @param remote the remote
- * @param list_cb function to call with each ref discovered at the remote
- * @param payload additional data to pass to the callback
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @return 0 on success, or an error code
*/
-GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload);
+GIT_EXTERN(int) git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote);
/**
- * Download the packfile
+ * Download and index the packfile
*
- * Negotiate what objects should be downloaded and download the
- * packfile with those objects. The packfile is downloaded with a
- * temporary filename, as it's final name is not known yet. If there
- * was no packfile needed (all the objects were available locally),
- * filename will be NULL and the function will return success.
+ * Connect to the remote if it hasn't been done yet, negotiate with
+ * the remote git which objects are missing, download and index the
+ * packfile.
+ *
+ * The .idx file will be created and both it and the packfile with be
+ * renamed to their final name.
*
- * @param remote the remote to download from
- * @param progress_cb function to call with progress information. Be aware that
- * this is called inline with network and indexing operations, so performance
- * may be affected.
- * @param payload payload for the progress callback
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_download(
- git_remote *remote,
- git_transfer_progress_callback progress_cb,
- void *payload);
+GIT_EXTERN(int) git_remote_download(git_remote *remote);
/**
* Check whether the remote is connected
@@ -317,6 +348,17 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
/**
+ * Download new data and update tips
+ *
+ * Convenience function to connect to a remote, download the data,
+ * disconnect and update the remote-tracking branches.
+ *
+ * @param remote the remote to fetch from
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_fetch(git_remote *remote);
+
+/**
* Return whether a string is a valid remote URL
*
* @param url the url to check
@@ -352,21 +394,6 @@ GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check);
/**
- * Set a credentials acquisition callback for this remote. If the remote is
- * not available for anonymous access, then you must set this callback in order
- * to provide credentials to the transport at the time of authentication
- * failure so that retry can be performed.
- *
- * @param remote the remote to configure
- * @param cred_acquire_cb The credentials acquisition callback to use (defaults
- * to NULL)
- */
-GIT_EXTERN(void) git_remote_set_cred_acquire_cb(
- git_remote *remote,
- git_cred_acquire_cb cred_acquire_cb,
- void *payload);
-
-/**
* Sets a custom transport for the remote. The caller can use this function
* to bypass the automatic discovery of a transport by URL scheme (i.e.
* http://, https://, git://) and supply their own transport to be used
@@ -395,13 +422,47 @@ typedef enum git_remote_completion_type {
/**
* The callback settings structure
*
- * Set the calbacks to be called by the remote.
+ * Set the callbacks to be called by the remote when informing the user
+ * about the progress of the network operations.
*/
struct git_remote_callbacks {
unsigned int version;
- void (*progress)(const char *str, int len, void *data);
+ /**
+ * Textual progress from the remote. Text send over the
+ * progress side-band will be passed to this function (this is
+ * the 'counting objects' output.
+ */
+ int (*progress)(const char *str, int len, void *data);
+
+ /**
+ * Completion is called when different parts of the download
+ * process are done (currently unused).
+ */
int (*completion)(git_remote_completion_type type, void *data);
+
+ /**
+ * This will be called if the remote host requires
+ * authentication in order to connect to it.
+ */
+ int (*credentials)(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data);
+
+ /**
+ * 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);
+
+ /**
+ * Each time a reference is updated locally, this function
+ * will be called with information about it.
+ */
int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
+
+ /**
+ * This will be passed to each of the callbacks in this struct
+ * as the last parameter.
+ */
void *payload;
};
@@ -418,7 +479,7 @@ struct git_remote_callbacks {
* @param callbacks a pointer to the user's callback settings
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
+GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks);
/**
* Get the statistics structure that is filled in by the fetch operation.
diff --git a/include/git2/repository.h b/include/git2/repository.h
index 2164cfac1..b4d561992 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -94,10 +94,14 @@ GIT_EXTERN(int) git_repository_discover(
* changes from the `stat` system call). (E.g. Searching in a user's home
* directory "/home/user/source/" will not return "/.git/" as the found
* repo if "/" is a different filesystem than "/home".)
+ * * GIT_REPOSITORY_OPEN_BARE - Open repository as a bare repo regardless
+ * of core.bare config, and defer loading config file for faster setup.
+ * Unlike `git_repository_open_bare`, this can follow gitlinks.
*/
typedef enum {
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
+ GIT_REPOSITORY_OPEN_BARE = (1 << 2),
} git_repository_open_flag_t;
/**
@@ -178,7 +182,7 @@ GIT_EXTERN(int) git_repository_init(
* when initializing a new repo. Details of individual values are:
*
* * BARE - Create a bare repository with no working directory.
- * * NO_REINIT - Return an EEXISTS error if the repo_path appears to
+ * * NO_REINIT - Return an GIT_EEXISTS error if the repo_path appears to
* already be an git repository.
* * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo
* path for non-bare repos (if it is not already there), but
@@ -293,7 +297,7 @@ GIT_EXTERN(int) git_repository_init_ext(
* @param out pointer to the reference which will be retrieved
* @param repo a repository object
*
- * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
+ * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
* branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise
*/
GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
@@ -311,16 +315,16 @@ GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
/**
- * Check if the current branch is an orphan
+ * Check if the current branch is unborn
*
- * An orphan branch is one named from HEAD but which doesn't exist in
+ * An unborn branch is one named from HEAD but which doesn't exist in
* the refs namespace, because it doesn't have any commit to point to.
*
* @param repo Repo to test
- * @return 1 if the current branch is an orphan, 0 if it's not; error
+ * @return 1 if the current branch is unborn, 0 if it's not; error
* code if there was an error
*/
-GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
+GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);
/**
* Check if a repository is empty
@@ -471,7 +475,7 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
* @param out Buffer to write data into or NULL to just read required size
* @param len Length of `out` buffer in bytes
* @param repo Repository to read prepared message from
- * @return GIT_ENOUTFOUND if no message exists, other value < 0 for other
+ * @return GIT_ENOTFOUND if no message exists, other value < 0 for other
* errors, or total bytes in message (may be > `len`) on success
*/
GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
@@ -601,13 +605,13 @@ GIT_EXTERN(int) git_repository_set_head_detached(
* If the HEAD is already detached and points to a Tag, the HEAD is
* updated into making it point to the peeled Commit, and 0 is returned.
*
- * If the HEAD is already detached and points to a non commitish, the HEAD is
+ * If the HEAD is already detached and points to a non commitish, the HEAD is
* unaltered, and -1 is returned.
*
* Otherwise, the HEAD will be detached and point to the peeled Commit.
*
* @param repo Repository pointer
- * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
+ * @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(
diff --git a/include/git2/revparse.h b/include/git2/revparse.h
index 786a9da57..d170e1621 100644
--- a/include/git2/revparse.h
+++ b/include/git2/revparse.h
@@ -10,7 +10,6 @@
#include "common.h"
#include "types.h"
-
/**
* @file git2/revparse.h
* @brief Git revision parsing routines
@@ -21,27 +20,37 @@
GIT_BEGIN_DECL
/**
- * Find a single object, as specified by a revision string. See `man gitrevisions`,
- * or http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * Find a single object, as specified by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
* information on the syntax accepted.
*
+ * The returned object should be released with `git_object_free` when no
+ * longer needed.
+ *
* @param out pointer to output object
* @param repo the repository to search in
* @param spec the textual specification for an object
* @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code
*/
-GIT_EXTERN(int) git_revparse_single(git_object **out, git_repository *repo, const char *spec);
+GIT_EXTERN(int) git_revparse_single(
+ git_object **out, git_repository *repo, const char *spec);
/**
- * Find a single object, as specified by a revision string.
- * See `man gitrevisions`,
- * or http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * Find a single object and intermediate reference by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
* information on the syntax accepted.
*
* In some cases (`@{<-n>}` or `<branchname>@{upstream}`), the expression may
* point to an intermediate reference. When such expressions are being passed
* in, `reference_out` will be valued as well.
*
+ * The returned object should be released with `git_object_free` and the
+ * returned reference with `git_reference_free` when no longer needed.
+ *
* @param object_out pointer to output object
* @param reference_out pointer to output reference or NULL
* @param repo the repository to search in
@@ -76,25 +85,27 @@ typedef struct {
git_object *from;
/** The right element of the revspec; must be freed by the user */
git_object *to;
- /** The intent of the revspec */
+ /** The intent of the revspec (i.e. `git_revparse_mode_t` flags) */
unsigned int flags;
} git_revspec;
/**
- * Parse a revision string for `from`, `to`, and intent. See `man gitrevisions` or
- * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for information
- * on the syntax accepted.
+ * Parse a revision string for `from`, `to`, and intent.
+ *
+ * See `man gitrevisions` or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
*
- * @param revspec Pointer to an user-allocated git_revspec struct where the result
- * of the rev-parse will be stored
+ * @param revspec Pointer to an user-allocated git_revspec struct where
+ * the result of the rev-parse will be stored
* @param repo the repository to search in
* @param spec the rev-parse spec to parse
* @return 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code
*/
GIT_EXTERN(int) git_revparse(
- git_revspec *revspec,
- git_repository *repo,
- const char *spec);
+ git_revspec *revspec,
+ git_repository *repo,
+ const char *spec);
/** @} */
diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h
index 8bfe0b502..c59b79938 100644
--- a/include/git2/revwalk.h
+++ b/include/git2/revwalk.h
@@ -232,6 +232,14 @@ GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode);
GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range);
/**
+ * Simplify the history by first-parent
+ *
+ * No parents other than the first for each commit will be enqueued.
+ */
+GIT_EXTERN(void) git_revwalk_simplify_first_parent(git_revwalk *walk);
+
+
+/**
* Free a revision walker previously allocated.
*
* @param walk traversal handle to close. If NULL nothing occurs.
diff --git a/include/git2/signature.h b/include/git2/signature.h
index 00d19de66..2fa46d032 100644
--- a/include/git2/signature.h
+++ b/include/git2/signature.h
@@ -48,6 +48,19 @@ GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const c
*/
GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email);
+/**
+ * Create a new action signature with default user and now timestamp.
+ *
+ * This looks up the user.name and user.email from the configuration and
+ * uses the current time as the timestamp, and creates a new signature
+ * based on that information. It will return GIT_ENOTFOUND if either the
+ * user.name or user.email are not set.
+ *
+ * @param out new signature
+ * @param repo repository pointer
+ * @return 0 on success, GIT_ENOTFOUND if config is missing, or error code
+ */
+GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo);
/**
* Create a copy of an existing signature. All internal strings are also
diff --git a/include/git2/stash.h b/include/git2/stash.h
index 68d1b5413..b48d33f5d 100644
--- a/include/git2/stash.h
+++ b/include/git2/stash.h
@@ -57,7 +57,7 @@ typedef enum {
GIT_EXTERN(int) git_stash_save(
git_oid *out,
git_repository *repo,
- git_signature *stasher,
+ const git_signature *stasher,
const char *message,
unsigned int flags);
diff --git a/include/git2/status.h b/include/git2/status.h
index 63aea2f3b..4ec3432df 100644
--- a/include/git2/status.h
+++ b/include/git2/status.h
@@ -60,25 +60,24 @@ typedef int (*git_status_cb)(
const char *path, unsigned int status_flags, void *payload);
/**
- * For extended status, select the files on which to report status.
+ * Select the files on which to report status.
+ *
+ * With `git_status_foreach_ext`, this will control which changes get
+ * callbacks. With `git_status_list_new`, these will control which
+ * changes are included in the list.
*
* - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This roughly
- * matches `git status --porcelain` where each file gets a callback
- * indicating its status in the index and in the working directory.
+ * matches `git status --porcelain` regarding which files are
+ * included and in what order.
* - GIT_STATUS_SHOW_INDEX_ONLY only gives status based on HEAD to index
* comparison, not looking at working directory changes.
* - GIT_STATUS_SHOW_WORKDIR_ONLY only gives status based on index to
* working directory comparison, not comparing the index to the HEAD.
- * - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR runs index-only then workdir-only,
- * issuing (up to) two callbacks per file (first index, then workdir).
- * This is slightly more efficient than separate calls and can make it
- * easier to emulate plain `git status` text output.
*/
typedef enum {
GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0,
GIT_STATUS_SHOW_INDEX_ONLY = 1,
GIT_STATUS_SHOW_WORKDIR_ONLY = 2,
- GIT_STATUS_SHOW_INDEX_THEN_WORKDIR = 3,
} git_status_show_t;
/**
@@ -108,7 +107,7 @@ typedef enum {
* - GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX indicates that rename detection
* should be processed between the head and the index and enables
* the GIT_STATUS_INDEX_RENAMED as a possible status flag.
- * - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates tha rename
+ * - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates that rename
* detection should be run between the index and the working directory
* and enabled GIT_STATUS_WT_RENAMED as a possible status flag.
* - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case
@@ -117,6 +116,11 @@ typedef enum {
* - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case
* sensitivity for the file system and forces the output to be in
* case-insensitive order
+ * - GIT_STATUS_OPT_RENAMES_FROM_REWRITES indicates that rename detection
+ * should include rewritten files
+ * - 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).
*
* Calling `git_status_foreach()` is like calling the extended version
* with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
@@ -135,6 +139,8 @@ typedef enum {
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8),
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9),
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_t;
#define GIT_STATUS_OPT_DEFAULTS \
@@ -235,12 +241,12 @@ GIT_EXTERN(int) git_status_foreach_ext(
* This is not quite the same as calling `git_status_foreach_ext()` with
* the pathspec set to the specified path.
*
- * @param status_flags The status value for the file
+ * @param status_flags Output combination of git_status_t values for file
* @param repo A repository object
- * @param path The file to retrieve status for, rooted at the repo's workdir
+ * @param path The file to retrieve status for relative to the repo workdir
* @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,
- * index, and work tree, GIT_EINVALIDPATH if `path` points at a folder,
- * GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error.
+ * index, and work tree, GIT_EAMBIGUOUS if `path` matches multiple files
+ * or if it refers to a folder, and -1 on other errors.
*/
GIT_EXTERN(int) git_status_file(
unsigned int *status_flags,
diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index 91b5300ae..186f263f5 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -14,51 +14,18 @@
/**
* @file git2/submodule.h
* @brief Git submodule management utilities
- * @defgroup git_submodule Git submodule management routines
- * @ingroup Git
- * @{
- */
-GIT_BEGIN_DECL
-
-/**
- * Opaque structure representing a submodule.
*
* Submodule support in libgit2 builds a list of known submodules and keeps
* it in the repository. The list is built from the .gitmodules file, the
* .git/config file, the index, and the HEAD tree. Items in the working
* directory that look like submodules (i.e. a git repo) but are not
* mentioned in those places won't be tracked.
- */
-typedef struct git_submodule git_submodule;
-
-/**
- * Values that could be specified for the update rule of a submodule.
*
- * Use the DEFAULT value if you have altered the update value via
- * `git_submodule_set_update()` and wish to reset to the original default.
- */
-typedef enum {
- GIT_SUBMODULE_UPDATE_DEFAULT = -1,
- GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
- GIT_SUBMODULE_UPDATE_REBASE = 1,
- GIT_SUBMODULE_UPDATE_MERGE = 2,
- GIT_SUBMODULE_UPDATE_NONE = 3
-} git_submodule_update_t;
-
-/**
- * Values that could be specified for how closely to examine the
- * working directory when getting submodule status.
- *
- * Use the DEFUALT value if you have altered the ignore value via
- * `git_submodule_set_ignore()` and wish to reset to the original value.
+ * @defgroup git_submodule Git submodule management routines
+ * @ingroup Git
+ * @{
*/
-typedef enum {
- GIT_SUBMODULE_IGNORE_DEFAULT = -1, /* reset to default */
- GIT_SUBMODULE_IGNORE_NONE = 0, /* any change or untracked == dirty */
- GIT_SUBMODULE_IGNORE_UNTRACKED = 1, /* dirty if tracked files change */
- GIT_SUBMODULE_IGNORE_DIRTY = 2, /* only dirty if HEAD moved */
- GIT_SUBMODULE_IGNORE_ALL = 3 /* never dirty */
-} git_submodule_ignore_t;
+GIT_BEGIN_DECL
/**
* Return codes for submodule status.
@@ -119,19 +86,9 @@ typedef enum {
GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13),
} git_submodule_status_t;
-#define GIT_SUBMODULE_STATUS__IN_FLAGS \
- (GIT_SUBMODULE_STATUS_IN_HEAD | \
- GIT_SUBMODULE_STATUS_IN_INDEX | \
- GIT_SUBMODULE_STATUS_IN_CONFIG | \
- GIT_SUBMODULE_STATUS_IN_WD)
-
-#define GIT_SUBMODULE_STATUS__INDEX_FLAGS \
- (GIT_SUBMODULE_STATUS_INDEX_ADDED | \
- GIT_SUBMODULE_STATUS_INDEX_DELETED | \
- GIT_SUBMODULE_STATUS_INDEX_MODIFIED)
-
-#define GIT_SUBMODULE_STATUS__WD_FLAGS \
- ~(GIT_SUBMODULE_STATUS__IN_FLAGS | GIT_SUBMODULE_STATUS__INDEX_FLAGS)
+#define GIT_SUBMODULE_STATUS__IN_FLAGS 0x000Fu
+#define GIT_SUBMODULE_STATUS__INDEX_FLAGS 0x0070u
+#define GIT_SUBMODULE_STATUS__WD_FLAGS 0x3F80u
#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \
(((S) & ~GIT_SUBMODULE_STATUS__IN_FLAGS) == 0)
@@ -359,9 +316,10 @@ GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule);
GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
/**
- * Get the ignore rule for the submodule.
+ * Get the ignore rule that will be used for the submodule.
*
- * There are four ignore values:
+ * These values control the behavior of `git_submodule_status()` for this
+ * submodule. There are four ignore values:
*
* - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents
* of the submodule from a clean checkout to be dirty, including the
@@ -375,6 +333,13 @@ GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
* - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo.
* The working directory will be consider clean so long as there is a
* checked out version present.
+ *
+ * plus the special **GIT_SUBMODULE_IGNORE_RESET** which can be used with
+ * `git_submodule_set_ignore()` to revert to the on-disk setting.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_ignore_t valyue what will be used for
+ * this submodule.
*/
GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
git_submodule *submodule);
@@ -382,15 +347,17 @@ GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
/**
* Set the ignore rule for the submodule.
*
- * This sets the ignore rule in memory for the submodule. This will be used
- * for any following actions (such as `git_submodule_status()`) while the
- * submodule is in memory. You should call `git_submodule_save()` if you
- * want to persist the new ignore role.
+ * This sets the in-memory ignore rule for the submodule which will
+ * control the behavior of `git_submodule_status()`.
*
- * Calling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling
- * `git_submodule_reload()` will revert the rule to the value that was in the
- * original config.
+ * To make changes persistent, call `git_submodule_save()` to write the
+ * value to disk (in the ".gitmodules" and ".git/config" files).
*
+ * Call with `GIT_SUBMODULE_IGNORE_RESET` or call `git_submodule_reload()`
+ * to revert the in-memory rule to the value that is on disk.
+ *
+ * @param submodule The submodule to update
+ * @param ignore The new value for the ignore rule
* @return old value for ignore
*/
GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
@@ -398,7 +365,16 @@ GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
git_submodule_ignore_t ignore);
/**
- * Get the update rule for the submodule.
+ * Get the update rule that will be used for the submodule.
+ *
+ * This value controls the behavior of the `git submodule update` command.
+ * There are four useful values documented with `git_submodule_update_t`
+ * plus the `GIT_SUBMODULE_UPDATE_RESET` which can be used to revert to
+ * the on-disk setting.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_update_t value that will be used
+ * for this submodule.
*/
GIT_EXTERN(git_submodule_update_t) git_submodule_update(
git_submodule *submodule);
@@ -406,13 +382,17 @@ GIT_EXTERN(git_submodule_update_t) git_submodule_update(
/**
* Set the update rule for the submodule.
*
- * This sets the update rule in memory for the submodule. You should call
- * `git_submodule_save()` if you want to persist the new update rule.
+ * The initial value comes from the ".git/config" setting of
+ * `submodule.$name.update` for this submodule (which is initialized from
+ * the ".gitmodules" file). Using this function sets the update rule in
+ * memory for the submodule. Call `git_submodule_save()` to write out the
+ * new update rule.
*
- * Calling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling
- * `git_submodule_reload()` will revert the rule to the value that was in the
- * original config.
+ * Calling this again with GIT_SUBMODULE_UPDATE_RESET or calling
+ * `git_submodule_reload()` will revert the rule to the on disk value.
*
+ * @param submodule The submodule to update
+ * @param update The new value to use
* @return old value for update
*/
GIT_EXTERN(git_submodule_update_t) git_submodule_set_update(
diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h
index 11e59cf03..419ad7ea7 100644
--- a/include/git2/sys/config.h
+++ b/include/git2/sys/config.h
@@ -21,6 +21,33 @@
GIT_BEGIN_DECL
/**
+ * Every iterator must have this struct as its first element, so the
+ * API can talk to it. You'd define your iterator as
+ *
+ * struct my_iterator {
+ * git_config_iterator parent;
+ * ...
+ * }
+ *
+ * and assign `iter->parent.backend` to your `git_config_backend`.
+ */
+struct git_config_iterator {
+ git_config_backend *backend;
+ unsigned int flags;
+
+ /**
+ * Return the current entry and advance the iterator. The
+ * memory belongs to the library.
+ */
+ int (*next)(git_config_entry **entry, git_config_iterator *iter);
+
+ /**
+ * Free the iterator
+ */
+ void (*free)(git_config_iterator *iter);
+};
+
+/**
* Generic backend that implements the interface to
* access a configuration file
*/
@@ -31,11 +58,11 @@ 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_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload);
int (*set)(struct git_config_backend *, const char *key, const char *value);
int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
int (*del)(struct git_config_backend *, const char *key);
- int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload);
+ int (*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 *);
void (*free)(struct git_config_backend *);
};
diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h
new file mode 100644
index 000000000..94ad3aed4
--- /dev/null
+++ b/include/git2/sys/filter.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_filter_h__
+#define INCLUDE_sys_git_filter_h__
+
+#include "git2/filter.h"
+
+/**
+ * @file git2/sys/filter.h
+ * @brief Git filter backend and plugin routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Look up a filter by name
+ *
+ * @param name The name of the filter
+ * @return Pointer to the filter object or NULL if not found
+ */
+GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
+
+#define GIT_FILTER_CRLF "crlf"
+#define GIT_FILTER_IDENT "ident"
+
+/**
+ * This is priority that the internal CRLF filter will be registered with
+ */
+#define GIT_FILTER_CRLF_PRIORITY 0
+
+/**
+ * This is priority that the internal ident filter will be registered with
+ */
+#define GIT_FILTER_IDENT_PRIORITY 100
+
+/**
+ * This is priority to use with a custom filter to imitate a core Git
+ * filter driver, so that it will be run last on checkout and first on
+ * checkin. You do not have to use this, but it helps compatibility.
+ */
+#define GIT_FILTER_DRIVER_PRIORITY 200
+
+/**
+ * Create a new empty filter list
+ *
+ * Normally you won't use this because `git_filter_list_load` will create
+ * the filter list for you, but you can use this in combination with the
+ * `git_filter_lookup` and `git_filter_list_push` functions to assemble
+ * your own chains of filters.
+ */
+GIT_EXTERN(int) git_filter_list_new(
+ git_filter_list **out, git_repository *repo, git_filter_mode_t mode);
+
+/**
+ * Add a filter to a filter list with the given payload.
+ *
+ * Normally you won't have to do this because the filter list is created
+ * by calling the "check" function on registered filters when the filter
+ * attributes are set, but this does allow more direct manipulation of
+ * filter lists when desired.
+ *
+ * Note that normally the "check" function can set up a payload for the
+ * filter. Using this function, you can either pass in a payload if you
+ * know the expected payload format, or you can pass NULL. Some filters
+ * may fail with a NULL payload. Good luck!
+ */
+GIT_EXTERN(int) git_filter_list_push(
+ git_filter_list *fl, git_filter *filter, void *payload);
+
+/**
+ * Look up how many filters are in the list
+ *
+ * We will attempt to apply all of these filters to any data passed in,
+ * but note that the filter apply action still has the option of skipping
+ * data that is passed in (for example, the CRLF filter will skip data
+ * that appears to be binary).
+ *
+ * @param fl A filter list
+ * @return The number of filters in the list
+ */
+GIT_EXTERN(size_t) git_filter_list_length(const git_filter_list *fl);
+
+/**
+ * A filter source represents a file/blob to be processed
+ */
+typedef struct git_filter_source git_filter_source;
+
+/**
+ * Get the repository that the source data is coming from.
+ */
+GIT_EXTERN(git_repository *) git_filter_source_repo(const git_filter_source *src);
+
+/**
+ * Get the path that the source data is coming from.
+ */
+GIT_EXTERN(const char *) git_filter_source_path(const git_filter_source *src);
+
+/**
+ * Get the file mode of the source file
+ * If the mode is unknown, this will return 0
+ */
+GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
+
+/**
+ * Get the OID of the source
+ * If the OID is unknown (often the case with GIT_FILTER_CLEAN) then
+ * this will return NULL.
+ */
+GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
+
+/**
+ * Get the git_filter_mode_t to be applied
+ */
+GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
+
+/*
+ * struct git_filter
+ *
+ * The filter lifecycle:
+ * - initialize - first use of filter
+ * - shutdown - filter removed/unregistered from system
+ * - check - considering filter for file
+ * - apply - apply filter to file contents
+ * - cleanup - done with file
+ */
+
+/**
+ * Initialize callback on filter
+ *
+ * Specified as `filter.initialize`, this is an optional callback invoked
+ * before a filter is first used. It will be called once at most.
+ *
+ * If non-NULL, the filter's `initialize` callback will be invoked right
+ * before the first use of the filter, so you can defer expensive
+ * initialization operations (in case libgit2 is being used in a way that
+ * doesn't need the filter).
+ */
+typedef int (*git_filter_init_fn)(git_filter *self);
+
+/**
+ * Shutdown callback on filter
+ *
+ * Specified as `filter.shutdown`, this is an optional callback invoked
+ * when the filter is unregistered or when libgit2 is shutting down. It
+ * will be called once at most and should release resources as needed.
+ *
+ * Typically this function will free the `git_filter` object itself.
+ */
+typedef void (*git_filter_shutdown_fn)(git_filter *self);
+
+/**
+ * Callback to decide if a given source needs this filter
+ *
+ * Specified as `filter.check`, this is an optional callback that checks
+ * if filtering is needed for a given source.
+ *
+ * It should return 0 if the filter should be applied (i.e. success),
+ * GIT_PASSTHROUGH if the filter should not be applied, or an error code
+ * to fail out of the filter processing pipeline and return to the caller.
+ *
+ * The `attr_values` will be set to the values of any attributes given in
+ * the filter definition. See `git_filter` below for more detail.
+ *
+ * The `payload` will be a pointer to a reference payload for the filter.
+ * This will start as NULL, but `check` can assign to this pointer for
+ * later use by the `apply` callback. Note that the value should be heap
+ * allocated (not stack), so that it doesn't go away before the `apply`
+ * callback can use it. If a filter allocates and assigns a value to the
+ * `payload`, it will need a `cleanup` callback to free the payload.
+ */
+typedef int (*git_filter_check_fn)(
+ git_filter *self,
+ void **payload, /* points to NULL ptr on entry, may be set */
+ const git_filter_source *src,
+ const char **attr_values);
+
+/**
+ * Callback to actually perform the data filtering
+ *
+ * Specified as `filter.apply`, this is the callback that actually filters
+ * data. If it successfully writes the output, it should return 0. Like
+ * `check`, it can return GIT_PASSTHROUGH to indicate that the filter
+ * doesn't want to run. Other error codes will stop filter processing and
+ * return to the caller.
+ *
+ * The `payload` value will refer to any payload that was set by the
+ * `check` callback. It may be read from or written to as needed.
+ */
+typedef int (*git_filter_apply_fn)(
+ git_filter *self,
+ void **payload, /* may be read and/or set */
+ git_buf *to,
+ const git_buf *from,
+ const git_filter_source *src);
+
+/**
+ * Callback to clean up after filtering has been applied
+ *
+ * Specified as `filter.cleanup`, this is an optional callback invoked
+ * after the filter has been applied. If the `check` or `apply` callbacks
+ * allocated a `payload` to keep per-source filter state, use this
+ * callback to free that payload and release resources as required.
+ */
+typedef void (*git_filter_cleanup_fn)(
+ git_filter *self,
+ void *payload);
+
+/**
+ * Filter structure used to register custom filters.
+ *
+ * To associate extra data with a filter, allocate extra data and put the
+ * `git_filter` struct at the start of your data buffer, then cast the
+ * `self` pointer to your larger structure when your callback is invoked.
+ *
+ * `version` should be set to GIT_FILTER_VERSION
+ *
+ * `attributes` is a whitespace-separated list of attribute names to check
+ * for this filter (e.g. "eol crlf text"). If the attribute name is bare,
+ * it will be simply loaded and passed to the `check` callback. If it has
+ * a value (i.e. "name=value"), the attribute must match that value for
+ * the filter to be applied.
+ *
+ * The `initialize`, `shutdown`, `check`, `apply`, and `cleanup` callbacks
+ * are all documented above with the respective function pointer typedefs.
+ */
+struct git_filter {
+ unsigned int version;
+
+ const char *attributes;
+
+ git_filter_init_fn initialize;
+ git_filter_shutdown_fn shutdown;
+ git_filter_check_fn check;
+ git_filter_apply_fn apply;
+ git_filter_cleanup_fn cleanup;
+};
+
+#define GIT_FILTER_VERSION 1
+
+/**
+ * Register a filter under a given name with a given priority.
+ *
+ * As mentioned elsewhere, the initialize callback will not be invoked
+ * immediately. It is deferred until the filter is used in some way.
+ *
+ * A filter's attribute checks and `check` and `apply` callbacks will be
+ * issued in order of `priority` on smudge (to workdir), and in reverse
+ * order of `priority` on clean (to odb).
+ *
+ * Two filters are preregistered with libgit2:
+ * - GIT_FILTER_CRLF with priority 0
+ * - GIT_FILTER_IDENT with priority 100
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name A name by which the filter can be referenced. Attempting
+ * to register with an in-use name will return GIT_EEXISTS.
+ * @param filter The filter definition. This pointer will be stored as is
+ * by libgit2 so it must be a durable allocation (either static
+ * or on the heap).
+ * @param priority The priority for filter application
+ * @return 0 on successful registry, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_register(
+ const char *name, git_filter *filter, int priority);
+
+/**
+ * Remove the filter with the given name
+ *
+ * Attempting to remove the builtin libgit2 filters is not permitted and
+ * will return an error.
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name The name under which the filter was registered
+ * @return 0 on success, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_unregister(const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/index.h b/include/git2/sys/index.h
index a32e07036..1a06a4df1 100644
--- a/include/git2/sys/index.h
+++ b/include/git2/sys/index.h
@@ -72,7 +72,6 @@ GIT_EXTERN(int) git_index_name_add(git_index *index,
* Remove all filename conflict entries.
*
* @param index an existing index object
- * @return 0 or an error code
*/
GIT_EXTERN(void) git_index_name_clear(git_index *index);
@@ -168,7 +167,6 @@ GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n);
* Remove all resolve undo entries from the index
*
* @param index an existing index object
- * @return 0 or an error code
*/
GIT_EXTERN(void) git_index_reuc_clear(git_index *index);
diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h
index 3cd2734c0..8039a5b82 100644
--- a/include/git2/sys/odb_backend.h
+++ b/include/git2/sys/odb_backend.h
@@ -48,12 +48,12 @@ struct git_odb_backend {
int (* read_header)(
size_t *, git_otype *, git_odb_backend *, const git_oid *);
- /* The writer may assume that the object
- * has already been hashed and is passed
- * in the first parameter.
+ /**
+ * Write an object into the backend. The id of the object has
+ * already been calculated and is passed in.
*/
int (* write)(
- git_oid *, git_odb_backend *, const void *, size_t, git_otype);
+ git_odb_backend *, const git_oid *, const void *, size_t, git_otype);
int (* writestream)(
git_odb_stream **, git_odb_backend *, size_t, git_otype);
@@ -64,13 +64,23 @@ struct git_odb_backend {
int (* exists)(
git_odb_backend *, const git_oid *);
+ /**
+ * If the backend implements a refreshing mechanism, it should be exposed
+ * through this endpoint. Each call to `git_odb_refresh()` will invoke it.
+ *
+ * However, the backend implementation should try to stay up-to-date as much
+ * as possible by itself as libgit2 will not automatically invoke
+ * `git_odb_refresh()`. For instance, a potential strategy for the backend
+ * implementation to achieve this could be to internally invoke this
+ * endpoint on failed lookups (ie. `exists()`, `read()`, `read_header()`).
+ */
int (* refresh)(git_odb_backend *);
int (* foreach)(
git_odb_backend *, git_odb_foreach_cb cb, void *payload);
int (* writepack)(
- git_odb_writepack **, git_odb_backend *,
+ git_odb_writepack **, git_odb_backend *, git_odb *odb,
git_transfer_progress_callback progress_cb, void *progress_payload);
void (* free)(git_odb_backend *);
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
index 9b457b074..9cf5073fb 100644
--- a/include/git2/sys/refdb_backend.h
+++ b/include/git2/sys/refdb_backend.h
@@ -103,7 +103,7 @@ struct git_refdb_backend {
* Deletes the given reference from the refdb. A refdb implementation
* must provide this function.
*/
- int (*delete)(git_refdb_backend *backend, const char *ref_name);
+ int (*del)(git_refdb_backend *backend, const char *ref_name);
/**
* Suggests that the given refdb compress or optimize its references.
@@ -119,10 +119,30 @@ struct git_refdb_backend {
* provide this function; if it is not provided, nothing will be done.
*/
void (*free)(git_refdb_backend *backend);
+
+ /**
+ * Read the reflog for the given reference name.
+ */
+ int (*reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
+
+ /**
+ * Write a reflog to disk.
+ */
+ int (*reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
+
+ /**
+ * Rename a reflog
+ */
+ int (*reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
+
+ /**
+ * Remove a reflog.
+ */
+ int (*reflog_delete)(git_refdb_backend *backend, const char *name);
};
-#define GIT_ODB_BACKEND_VERSION 1
-#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+#define GIT_REFDB_BACKEND_VERSION 1
+#define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
/**
* Constructors for default filesystem-based refdb backend
diff --git a/include/git2/sys/reflog.h b/include/git2/sys/reflog.h
new file mode 100644
index 000000000..c9d0041b9
--- /dev/null
+++ b/include/git2/sys/reflog.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_reflog_h__
+#define INCLUDE_sys_git_reflog_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+GIT_BEGIN_DECL
+
+GIT_EXTERN(git_reflog_entry *) git_reflog_entry__alloc(void);
+GIT_EXTERN(void) git_reflog_entry__free(git_reflog_entry *entry);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/sys/refs.h b/include/git2/sys/refs.h
index 85963258c..dd95ca12c 100644
--- a/include/git2/sys/refs.h
+++ b/include/git2/sys/refs.h
@@ -16,7 +16,7 @@
*
* @param name the reference name
* @param oid the object id for a direct reference
- * @param symbolic the target for a symbolic reference
+ * @param peel the first non-tag object's OID, or NULL
* @return the created git_reference or NULL on error
*/
GIT_EXTERN(git_reference *) git_reference__alloc(
@@ -28,7 +28,7 @@ GIT_EXTERN(git_reference *) git_reference__alloc(
* Create a new symbolic reference.
*
* @param name the reference name
- * @param symbolic the target for a symbolic reference
+ * @param target the target for a symbolic reference
* @return the created git_reference or NULL on error
*/
GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h
index ba3d65ae5..36f8b5836 100644
--- a/include/git2/sys/repository.h
+++ b/include/git2/sys/repository.h
@@ -27,7 +27,6 @@ GIT_BEGIN_DECL
*/
GIT_EXTERN(int) git_repository_new(git_repository **out);
-
/**
* Reset all the internal state in a repository.
*
@@ -42,6 +41,25 @@ GIT_EXTERN(int) git_repository_new(git_repository **out);
GIT_EXTERN(void) git_repository__cleanup(git_repository *repo);
/**
+ * Update the filesystem config settings for an open repository
+ *
+ * When a repository is initialized, config values are set based on the
+ * properties of the filesystem that the repository is on, such as
+ * "core.ignorecase", "core.filemode", "core.symlinks", etc. If the
+ * repository is moved to a new filesystem, these properties may no
+ * longer be correct and API calls may not behave as expected. This
+ * call reruns the phase of repository initialization that sets those
+ * properties to compensate for the current filesystem of the repo.
+ *
+ * @param repo A repository object
+ * @param recurse_submodules Should submodules be updated recursively
+ * @returrn 0 on success, < 0 on error
+ */
+GIT_EXTERN(int) git_repository_reinit_filesystem(
+ git_repository *repo,
+ int recurse_submodules);
+
+/**
* Set the configuration file for this repository
*
* This configuration file will be used for all configuration
diff --git a/include/git2/transport.h b/include/git2/transport.h
index 81bb3abe1..caabd0465 100644
--- a/include/git2/transport.h
+++ b/include/git2/transport.h
@@ -28,22 +28,31 @@ GIT_BEGIN_DECL
*** Begin interface for credentials acquisition ***
*/
+/** Authentication type requested */
typedef enum {
/* git_cred_userpass_plaintext */
- GIT_CREDTYPE_USERPASS_PLAINTEXT = 1,
- GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = 2,
- GIT_CREDTYPE_SSH_PUBLICKEY = 3,
+ GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
+
+ /* git_cred_ssh_key */
+ GIT_CREDTYPE_SSH_KEY = (1u << 1),
+
+ /* git_cred_ssh_custom */
+ GIT_CREDTYPE_SSH_CUSTOM = (1u << 2),
+
+ /* git_cred_default */
+ GIT_CREDTYPE_DEFAULT = (1u << 3),
} git_credtype_t;
/* The base structure for all credential types */
-typedef struct git_cred {
+typedef struct git_cred git_cred;
+
+struct git_cred {
git_credtype_t credtype;
- void (*free)(
- struct git_cred *cred);
-} git_cred;
+ void (*free)(git_cred *cred);
+};
-/* A plaintext username and password */
-typedef struct git_cred_userpass_plaintext {
+/** A plaintext username and password */
+typedef struct {
git_cred parent;
char *username;
char *password;
@@ -51,27 +60,46 @@ typedef struct git_cred_userpass_plaintext {
#ifdef GIT_SSH
typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));
+#else
+typedef int (*git_cred_sign_callback)(void *, ...);
+#endif
-/* A ssh key file and passphrase */
-typedef struct git_cred_ssh_keyfile_passphrase {
+/**
+ * A ssh key from disk
+ */
+typedef struct git_cred_ssh_key {
git_cred parent;
+ char *username;
char *publickey;
char *privatekey;
char *passphrase;
-} git_cred_ssh_keyfile_passphrase;
+} git_cred_ssh_key;
-/* A ssh public key and authentication callback */
-typedef struct git_cred_ssh_publickey {
+/**
+ * A key with a custom signature function
+ */
+typedef struct git_cred_ssh_custom {
git_cred parent;
+ char *username;
char *publickey;
- size_t publickey_len;
+ size_t publickey_len;
void *sign_callback;
void *sign_data;
-} git_cred_ssh_publickey;
-#endif
+} git_cred_ssh_custom;
+
+/** A key for NTLM/Kerberos "default" credentials */
+typedef struct git_cred git_cred_default;
+
+/**
+ * Check whether a credential object contains username information.
+ *
+ * @param cred object to check
+ * @return 1 if the credential object has non-NULL username, 0 otherwise
+ */
+GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
/**
- * Creates a new plain-text username and password credential object.
+ * Create a new plain-text username and password credential object.
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
@@ -84,52 +112,68 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
const char *username,
const char *password);
-#ifdef GIT_SSH
/**
- * Creates a new ssh key file and passphrase credential object.
+ * Create a new passphrase-protected ssh key credential object.
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
+ * @param username username to use to authenticate
* @param publickey The path to the public key of the credential.
* @param privatekey The path to the private key of the credential.
* @param passphrase The passphrase of the credential.
* @return 0 for success or an error code for failure
*/
-GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new(
+GIT_EXTERN(int) git_cred_ssh_key_new(
git_cred **out,
+ const char *username,
const char *publickey,
const char *privatekey,
- const char *passphrase);
+ const char *passphrase);
/**
- * Creates a new ssh public key credential object.
+ * Create an ssh key credential with a custom signing function.
+ *
+ * This lets you use your own function to sign the challenge.
+ *
+ * This function and its credential type is provided for completeness
+ * and wraps `libssh2_userauth_publickey()`, which is undocumented.
+ *
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
+ * @param username username to use to authenticate
* @param publickey The bytes of the public key.
* @param publickey_len The length of the public key in bytes.
- * @param sign_callback The callback method for authenticating.
- * @param sign_data The abstract data sent to the sign_callback method.
+ * @param sign_fn The callback method to sign the data during the challenge.
+ * @param sign_data The data to pass to the sign function.
* @return 0 for success or an error code for failure
*/
-GIT_EXTERN(int) git_cred_ssh_publickey_new(
+GIT_EXTERN(int) git_cred_ssh_custom_new(
git_cred **out,
+ const char *username,
const char *publickey,
- size_t publickey_len,
- git_cred_sign_callback,
- void *sign_data);
-#endif
+ size_t publickey_len,
+ git_cred_sign_callback sign_fn,
+ void *sign_data);
+
+/**
+ * Create a "default" credential usable for Negotiate mechanisms like NTLM
+ * or Kerberos authentication.
+ *
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_default_new(git_cred **out);
/**
* Signature of a function which acquires a credential object.
*
- * @param cred The newly created credential object.
- * @param url The resource for which we are demanding a credential.
- * @param username_from_url The username that was embedded in a "user@host"
+ * - cred: The newly created credential object.
+ * - url: The resource for which we are demanding a credential.
+ * - username_from_url: The username that was embedded in a "user@host"
* remote url, or NULL if not included.
- * @param allowed_types A bitmask stating which cred types are OK to return.
- * @param payload The payload provided when specifying this callback.
- * @return 0 for success or an error code for failure
+ * - 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
*/
typedef int (*git_cred_acquire_cb)(
git_cred **cred,
@@ -150,39 +194,45 @@ typedef enum {
GIT_TRANSPORTFLAGS_NO_CHECK_CERT = 1
} git_transport_flags_t;
-typedef void (*git_transport_message_cb)(const char *str, int len, void *data);
+typedef int (*git_transport_message_cb)(const char *str, int len, void *data);
+
+typedef struct git_transport git_transport;
-typedef struct git_transport {
+struct git_transport {
unsigned int version;
/* Set progress and error callbacks */
- int (*set_callbacks)(struct git_transport *transport,
+ int (*set_callbacks)(
+ git_transport *transport,
git_transport_message_cb progress_cb,
git_transport_message_cb error_cb,
void *payload);
/* Connect the transport to the remote repository, using the given
* direction. */
- int (*connect)(struct git_transport *transport,
+ int (*connect)(
+ git_transport *transport,
const char *url,
git_cred_acquire_cb cred_acquire_cb,
void *cred_acquire_payload,
int direction,
int flags);
- /* This function may be called after a successful call to connect(). The
- * provided callback is invoked for each ref discovered on the remote
- * end. */
- int (*ls)(struct git_transport *transport,
- git_headlist_cb list_cb,
- void *payload);
+ /* This function may be called after a successful call to
+ * connect(). The array returned is owned by the transport and
+ * is guranteed until the next call of a transport function. */
+ int (*ls)(
+ const git_remote_head ***out,
+ size_t *size,
+ git_transport *transport);
/* Executes the push whose context is in the git_push object. */
- int (*push)(struct git_transport *transport, git_push *push);
+ int (*push)(git_transport *transport, git_push *push);
/* This function may be called after a successful call to connect(), when
* the direction is FETCH. The function performs a negotiation to calculate
* the wants list for the fetch. */
- int (*negotiate_fetch)(struct git_transport *transport,
+ int (*negotiate_fetch)(
+ git_transport *transport,
git_repository *repo,
const git_remote_head * const *refs,
size_t count);
@@ -190,28 +240,29 @@ typedef struct git_transport {
/* This function may be called after a successful call to negotiate_fetch(),
* when the direction is FETCH. This function retrieves the pack file for
* the fetch from the remote end. */
- int (*download_pack)(struct git_transport *transport,
+ int (*download_pack)(
+ git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
void *progress_payload);
/* Checks to see if the transport is connected */
- int (*is_connected)(struct git_transport *transport);
+ int (*is_connected)(git_transport *transport);
/* Reads the flags value previously passed into connect() */
- int (*read_flags)(struct git_transport *transport, int *flags);
+ int (*read_flags)(git_transport *transport, int *flags);
/* Cancels any outstanding transport operation */
- void (*cancel)(struct git_transport *transport);
+ void (*cancel)(git_transport *transport);
/* This function is the reverse of connect() -- it terminates the
* connection to the remote end. */
- int (*close)(struct git_transport *transport);
+ int (*close)(git_transport *transport);
/* Frees/destructs the git_transport object. */
- void (*free)(struct git_transport *transport);
-} git_transport;
+ void (*free)(git_transport *transport);
+};
#define GIT_TRANSPORT_VERSION 1
#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
@@ -231,6 +282,40 @@ GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const
/* Signature of a function which creates a transport */
typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
+/**
+ * Add a custom transport definition, to be used in addition to the built-in
+ * set of transports that come with libgit2.
+ *
+ * The caller is responsible for synchronizing calls to git_transport_register
+ * and git_transport_unregister with other calls to the library that
+ * instantiate transports.
+ *
+ * @param prefix The scheme (ending in "://") to match, i.e. "git://"
+ * @param priority The priority of this transport relative to others with
+ * the same prefix. Built-in transports have a priority of 1.
+ * @param cb The callback used to create an instance of the transport
+ * @param param A fixed parameter to pass to cb at creation time
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_register(
+ const char *prefix,
+ unsigned priority,
+ git_transport_cb cb,
+ void *param);
+
+/**
+ *
+ * Unregister a custom transport definition which was previously registered
+ * with git_transport_register.
+ *
+ * @param prefix From the previous call to git_transport_register
+ * @param priority From the previous call to git_transport_register
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_unregister(
+ const char *prefix,
+ unsigned priority);
+
/* Transports which come with libgit2 (match git_transport_cb). The expected
* value for "param" is listed in-line below. */
@@ -299,35 +384,36 @@ typedef enum {
GIT_SERVICE_RECEIVEPACK = 4,
} git_smart_service_t;
-struct git_smart_subtransport;
+typedef struct git_smart_subtransport git_smart_subtransport;
+typedef struct git_smart_subtransport_stream git_smart_subtransport_stream;
/* A stream used by the smart transport to read and write data
* from a subtransport */
-typedef struct git_smart_subtransport_stream {
+struct git_smart_subtransport_stream {
/* The owning subtransport */
- struct git_smart_subtransport *subtransport;
+ git_smart_subtransport *subtransport;
int (*read)(
- struct git_smart_subtransport_stream *stream,
- char *buffer,
- size_t buf_size,
- size_t *bytes_read);
+ git_smart_subtransport_stream *stream,
+ char *buffer,
+ size_t buf_size,
+ size_t *bytes_read);
int (*write)(
- struct git_smart_subtransport_stream *stream,
- const char *buffer,
- size_t len);
+ git_smart_subtransport_stream *stream,
+ const char *buffer,
+ size_t len);
void (*free)(
- struct git_smart_subtransport_stream *stream);
-} git_smart_subtransport_stream;
+ git_smart_subtransport_stream *stream);
+};
/* An implementation of a subtransport which carries data for the
* smart transport */
-typedef struct git_smart_subtransport {
+struct git_smart_subtransport {
int (* action)(
git_smart_subtransport_stream **out,
- struct git_smart_subtransport *transport,
+ git_smart_subtransport *transport,
const char *url,
git_smart_service_t action);
@@ -337,10 +423,10 @@ typedef struct git_smart_subtransport {
*
* 1. UPLOADPACK_LS -> UPLOADPACK
* 2. RECEIVEPACK_LS -> RECEIVEPACK */
- int (* close)(struct git_smart_subtransport *transport);
+ int (*close)(git_smart_subtransport *transport);
- void (* free)(struct git_smart_subtransport *transport);
-} git_smart_subtransport;
+ void (*free)(git_smart_subtransport *transport);
+};
/* A function which creates a new subtransport for the smart transport */
typedef int (*git_smart_subtransport_cb)(
diff --git a/include/git2/tree.h b/include/git2/tree.h
index 65d8cc16e..d94b446c2 100644
--- a/include/git2/tree.h
+++ b/include/git2/tree.h
@@ -199,6 +199,17 @@ GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
/**
+ * Get the raw UNIX file attributes of a tree entry
+ *
+ * This function does not perform any normalization and is only useful
+ * if you need to be able to recreate the original tree object.
+ *
+ * @param entry a tree entry
+ * @return filemode as an integer
+ */
+
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode_raw(const git_tree_entry *entry);
+/**
* Compare two tree entries
*
* @param e1 first tree entry
@@ -208,7 +219,7 @@ GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2);
/**
- * Convert a tree entry to the git_object it points too.
+ * Convert a tree entry to the git_object it points to.
*
* You must call `git_object_free()` on the object when you are done with it.
*
diff --git a/include/git2/types.h b/include/git2/types.h
index dc344075c..55505b110 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -174,6 +174,9 @@ typedef struct git_reference_iterator git_reference_iterator;
/** Merge heads, the input to merge */
typedef struct git_merge_head git_merge_head;
+/** Merge result */
+typedef struct git_merge_result git_merge_result;
+
/** Representation of a status collection */
typedef struct git_status_list git_status_list;
@@ -212,11 +215,21 @@ typedef struct git_remote_callbacks git_remote_callbacks;
/**
* This is passed as the first argument to the callback to allow the
* user to see the progress.
+ *
+ * - total_objects: number of objects in the packfile being downloaded
+ * - indexed_objects: received objects that have been hashed
+ * - received_objects: objects which have been downloaded
+ * - local_objects: locally-available objects that have been injected
+ * in order to fix a thin pack.
+ * - received-bytes: size of the packfile received up to now
*/
typedef struct git_transfer_progress {
unsigned int total_objects;
unsigned int indexed_objects;
unsigned int received_objects;
+ unsigned int local_objects;
+ unsigned int total_deltas;
+ unsigned int indexed_deltas;
size_t received_bytes;
} git_transfer_progress;
@@ -229,6 +242,87 @@ typedef struct git_transfer_progress {
*/
typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
+/**
+ * Opaque structure representing a submodule.
+ */
+typedef struct git_submodule git_submodule;
+
+/**
+ * Submodule update values
+ *
+ * These values represent settings for the `submodule.$name.update`
+ * configuration value which says how to handle `git submodule update` for
+ * this submodule. The value is usually set in the ".gitmodules" file and
+ * copied to ".git/config" when the submodule is initialized.
+ *
+ * You can override this setting on a per-submodule basis with
+ * `git_submodule_set_update()` and write the changed value to disk using
+ * `git_submodule_save()`. If you have overwritten the value, you can
+ * revert it by passing `GIT_SUBMODULE_UPDATE_RESET` to the set function.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_UPDATE_RESET: reset to the on-disk value.
+ * - GIT_SUBMODULE_UPDATE_CHECKOUT: the default; when a submodule is
+ * updated, checkout the new detached HEAD to the submodule directory.
+ * - GIT_SUBMODULE_UPDATE_REBASE: update by rebasing the current checked
+ * out branch onto the commit from the superproject.
+ * - GIT_SUBMODULE_UPDATE_MERGE: update by merging the commit in the
+ * superproject into the current checkout out branch of the submodule.
+ * - GIT_SUBMODULE_UPDATE_NONE: do not update this submodule even when
+ * the commit in the superproject is updated.
+ * - GIT_SUBMODULE_UPDATE_DEFAULT: not used except as static initializer
+ * when we don't want any particular update rule to be specified.
+ */
+typedef enum {
+ GIT_SUBMODULE_UPDATE_RESET = -1,
+
+ GIT_SUBMODULE_UPDATE_CHECKOUT = 1,
+ GIT_SUBMODULE_UPDATE_REBASE = 2,
+ GIT_SUBMODULE_UPDATE_MERGE = 3,
+ GIT_SUBMODULE_UPDATE_NONE = 4,
+
+ GIT_SUBMODULE_UPDATE_DEFAULT = 0
+} git_submodule_update_t;
+
+/**
+ * Submodule ignore values
+ *
+ * These values represent settings for the `submodule.$name.ignore`
+ * configuration value which says how deeply to look at the working
+ * directory when getting submodule status.
+ *
+ * You can override this value in memory on a per-submodule basis with
+ * `git_submodule_set_ignore()` and can write the changed value to disk
+ * with `git_submodule_save()`. If you have overwritten the value, you
+ * can revert to the on disk value by using `GIT_SUBMODULE_IGNORE_RESET`.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_IGNORE_RESET: reset to the on-disk value.
+ * - GIT_SUBMODULE_IGNORE_NONE: don't ignore any change - i.e. even an
+ * untracked file, will mark the submodule as dirty. Ignored files are
+ * still ignored, of course.
+ * - GIT_SUBMODULE_IGNORE_UNTRACKED: ignore untracked files; only changes
+ * to tracked files, or the index or the HEAD commit will matter.
+ * - GIT_SUBMODULE_IGNORE_DIRTY: ignore changes in the working directory,
+ * only considering changes if the HEAD of submodule has moved from the
+ * value in the superproject.
+ * - GIT_SUBMODULE_IGNORE_ALL: never check if the submodule is dirty
+ * - GIT_SUBMODULE_IGNORE_DEFAULT: not used except as static initializer
+ * when we don't want any particular ignore rule to be specified.
+ */
+typedef enum {
+ GIT_SUBMODULE_IGNORE_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_DEFAULT = 0
+} git_submodule_ignore_t;
+
/** @} */
GIT_END_DECL
diff --git a/include/git2/version.h b/include/git2/version.h
index d8a915fac..c4c5e8eb1 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -7,9 +7,9 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.19.0"
+#define LIBGIT2_VERSION "0.20.0"
#define LIBGIT2_VER_MAJOR 0
-#define LIBGIT2_VER_MINOR 19
+#define LIBGIT2_VER_MINOR 20
#define LIBGIT2_VER_REVISION 0
#endif