diff --git a/git2/frameworks/libgit2.0.17.0.dylib b/git2/frameworks/libgit2.0.17.0.dylib index e467d4702..933ca3765 100755 Binary files a/git2/frameworks/libgit2.0.17.0.dylib and b/git2/frameworks/libgit2.0.17.0.dylib differ diff --git a/git2/include/git2.h b/git2/include/git2.h index d55543986..e138e279a 100644 --- a/git2/include/git2.h +++ b/git2/include/git2.h @@ -23,6 +23,7 @@ #include "git2/repository.h" #include "git2/revwalk.h" #include "git2/merge.h" +#include "git2/graph.h" #include "git2/refs.h" #include "git2/reflog.h" #include "git2/revparse.h" @@ -36,9 +37,11 @@ #include "git2/index.h" #include "git2/config.h" +#include "git2/transport.h" #include "git2/remote.h" #include "git2/clone.h" #include "git2/checkout.h" +#include "git2/push.h" #include "git2/attr.h" #include "git2/ignore.h" @@ -52,5 +55,6 @@ #include "git2/reset.h" #include "git2/message.h" #include "git2/pack.h" +#include "git2/stash.h" #endif diff --git a/git2/include/git2/attr.h b/git2/include/git2/attr.h index 2de9f4b0e..b1a7e0eb6 100644 --- a/git2/include/git2/attr.h +++ b/git2/include/git2/attr.h @@ -183,6 +183,8 @@ GIT_EXTERN(int) git_attr_get_many( size_t num_attr, const char **names); +typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *payload); + /** * Loop over all the git attributes for a path. * @@ -204,7 +206,7 @@ GIT_EXTERN(int) git_attr_foreach( git_repository *repo, uint32_t flags, const char *path, - int (*callback)(const char *name, const char *value, void *payload), + git_attr_foreach_cb callback, void *payload); /** diff --git a/git2/include/git2/blob.h b/git2/include/git2/blob.h index f0719f15d..30055b614 100644 --- a/git2/include/git2/blob.h +++ b/git2/include/git2/blob.h @@ -68,6 +68,17 @@ GIT_INLINE(void) git_blob_free(git_blob *blob) git_object_free((git_object *) blob); } +/** + * Get the id of a blob. + * + * @param blob a previously loaded blob. + * @return SHA1 hash for this blob. + */ +GIT_INLINE(const git_oid *) git_blob_id(const git_blob *blob) +{ + return git_object_id((const git_object *)blob); +} + /** * Get a read-only buffer with the raw content of a blob. @@ -88,32 +99,35 @@ GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob); * @param blob pointer to the blob * @return size on bytes */ -GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob); +GIT_EXTERN(git_off_t) git_blob_rawsize(git_blob *blob); /** * Read a file from the working folder of a repository * and write it to the Object Database as a loose blob * - * @param oid return the id of the written blob + * @param id return the id of the written blob * @param repo repository where the blob will be written. * this repository cannot be bare - * @param path file from which the blob will be created, + * @param relative_path file from which the blob will be created, * relative to the repository's working dir * @return 0 or an error code */ -GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path); +GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path); /** * Read a file from the filesystem and write its content * to the Object Database as a loose blob * - * @param oid return the id of the written blob + * @param id return the id of the written blob * @param repo repository where the blob will be written. * this repository can be bare or not * @param path file from which the blob will be created * @return 0 or an error code */ -GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path); +GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path); + + +typedef int (*git_blob_chunk_cb)(char *content, size_t max_length, void *payload); /** * Write a loose blob to the Object Database from a @@ -141,7 +155,7 @@ GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, con * - When an error occurs, the callback should return -1. * * - * @param oid Return the id of the written blob + * @param id Return the id of the written blob * * @param repo repository where the blob will be written. * This repository can be bare or not. @@ -152,10 +166,10 @@ GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, con * @return GIT_SUCCESS or an error code */ GIT_EXTERN(int) git_blob_create_fromchunks( - git_oid *oid, + git_oid *id, git_repository *repo, const char *hintpath, - int (*source_cb)(char *content, size_t max_length, void *payload), + git_blob_chunk_cb callback, void *payload); /** @@ -169,6 +183,19 @@ GIT_EXTERN(int) git_blob_create_fromchunks( */ GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len); +/** + * Determine if the blob content is most certainly binary or not. + * + * The heuristic used to guess if a file is binary is taken from core git: + * Searching for NUL bytes and looking for a reasonable ratio of printable + * to non-printable characters among the first 4000 bytes. + * + * @param blob The blob which content should be analyzed + * @return 1 if the content of the blob is detected + * as binary; 0 otherwise. + */ +GIT_EXTERN(int) git_blob_is_binary(git_blob *blob); + /** @} */ GIT_END_DECL #endif diff --git a/git2/include/git2/branch.h b/git2/include/git2/branch.h index f06609a51..f55903cd6 100644 --- a/git2/include/git2/branch.h +++ b/git2/include/git2/branch.h @@ -29,7 +29,10 @@ GIT_BEGIN_DECL * * The returned reference must be freed by the user. * - * @param branch_out Pointer where to store the underlying reference. + * The branch name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * + * @param out Pointer where to store the underlying reference. * * @param branch_name Name for the branch; this name is * validated for consistency. It should also not conflict with @@ -42,15 +45,15 @@ GIT_BEGIN_DECL * * @param force Overwrite existing branch. * - * @return 0 or an error code. + * @return 0, GIT_EINVALIDSPEC or an error code. * A proper reference is written in the refs/heads namespace * pointing to the provided target commit. */ GIT_EXTERN(int) git_branch_create( - git_reference **branch_out, + git_reference **out, git_repository *repo, const char *branch_name, - const git_object *target, + const git_commit *target, int force); /** @@ -94,6 +97,9 @@ GIT_EXTERN(int) git_branch_foreach( /** * Move/rename an existing local branch reference. * + * The new branch name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * * @param branch Current underlying reference of the branch. * * @param new_branch_name Target name of the branch once the move @@ -101,7 +107,7 @@ GIT_EXTERN(int) git_branch_foreach( * * @param force Overwrite existing branch. * - * @return 0 on success, or an error code. + * @return 0 on success, GIT_EINVALIDSPEC or an error code. */ GIT_EXTERN(int) git_branch_move( git_reference *branch, @@ -113,7 +119,10 @@ GIT_EXTERN(int) git_branch_move( * * The generated reference must be freed by the user. * - * @param branch_out pointer to the looked-up branch reference + * The branch name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * + * @param out pointer to the looked-up branch reference * * @param repo the repository to look up the branch * @@ -124,10 +133,10 @@ GIT_EXTERN(int) git_branch_move( * be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE. * * @return 0 on success; GIT_ENOTFOUND when no matching branch - * exists, otherwise an error code. + * exists, GIT_EINVALIDSPEC, otherwise an error code. */ GIT_EXTERN(int) git_branch_lookup( - git_reference **branch_out, + git_reference **out, git_repository *repo, const char *branch_name, git_branch_t branch_type); @@ -136,7 +145,7 @@ GIT_EXTERN(int) git_branch_lookup( * Return the reference supporting the remote tracking branch, * given a local branch reference. * - * @param tracking_out Pointer where to store the retrieved + * @param out Pointer where to store the retrieved * reference. * * @param branch Current underlying reference of the branch. @@ -145,7 +154,7 @@ GIT_EXTERN(int) git_branch_lookup( * reference exists, otherwise an error code. */ GIT_EXTERN(int) git_branch_tracking( - git_reference **tracking_out, + git_reference **out, git_reference *branch); /** diff --git a/git2/include/git2/checkout.h b/git2/include/git2/checkout.h index 390d2f215..c36e2a41b 100644 --- a/git2/include/git2/checkout.h +++ b/git2/include/git2/checkout.h @@ -25,62 +25,170 @@ GIT_BEGIN_DECL * Checkout behavior flags * * These flags control what checkout does with files. Pass in a - * combination of these values OR'ed together. + * combination of these values OR'ed together. If you just pass zero + * (i.e. no flags), then you are effectively doing a "dry run" where no + * files will be modified. + * + * Checkout groups the working directory content into 3 classes of files: + * (1) files that don't need a change, and files that do need a change + * that either (2) we are allowed to modifed or (3) we are not. The flags + * you pass in will decide which files we are allowed to modify. + * + * By default, checkout is not allowed to modify any files. Anything + * needing a change would be considered a conflict. + * + * GIT_CHECKOUT_UPDATE_UNMODIFIED means that checkout is allowed to update + * any file where the working directory content matches the HEAD + * (e.g. either the files match or the file is absent in both places). + * + * GIT_CHECKOUT_UPDATE_MISSING means checkout can create a missing file + * that exists in the index and does not exist in the working directory. + * This is usually desirable for initial checkout, etc. Technically, the + * missing file differs from the HEAD, which is why this is separate. + * + * GIT_CHECKOUT_UPDATE_MODIFIED means checkout is allowed to update files + * where the working directory does not match the HEAD so long as the file + * actually exists in the HEAD. This option implies UPDATE_UNMODIFIED. + * + * GIT_CHECKOUT_UPDATE_UNTRACKED means checkout is allowed to update files + * even if there is a working directory version that does not exist in the + * HEAD (i.e. the file was independently created in the workdir). This + * implies UPDATE_UNMODIFIED | UPDATE_MISSING (but *not* UPDATE_MODIFIED). + * + * + * On top of these three basic strategies, there are some modifiers + * options that can be applied: + * + * If any files need update but are disallowed by the strategy, normally + * checkout calls the conflict callback (if given) and then aborts. + * GIT_CHECKOUT_ALLOW_CONFLICTS means it is okay to update the files that + * are allowed by the strategy even if there are conflicts. The conflict + * callbacks are still made, but non-conflicting files will be updated. + * + * Any unmerged entries in the index are automatically considered conflicts. + * If you want to proceed anyhow and just skip unmerged entries, you can use + * GIT_CHECKOUT_SKIP_UNMERGED which is less dangerous than just allowing all + * conflicts. Alternatively, use GIT_CHECKOUT_USE_OURS to proceed and + * checkout the stage 2 ("ours") version. GIT_CHECKOUT_USE_THEIRS means to + * proceed and use the stage 3 ("theirs") version. + * + * GIT_CHECKOUT_UPDATE_ONLY means that update is not allowed to create new + * files or delete old ones, only update existing content. With this + * flag, files that needs to be created or deleted are not conflicts - + * they are just skipped. This also skips typechanges to existing files + * (because the old would have to be removed). + * + * GIT_CHECKOUT_REMOVE_UNTRACKED means that files in the working directory + * that are untracked (and not ignored) will be removed altogether. These + * untracked files (that do not shadow index entries) are not considered + * conflicts and would normally be ignored. + * + * + * Checkout is "semi-atomic" as in it will go through the work to be done + * before making any changes and if may decide to abort if there are + * conflicts, or you can use the conflict callback to explicitly abort the + * action before any updates are made. Despite this, if a second process + * is modifying the filesystem while checkout is running, it can't + * guarantee that the choices is makes while initially examining the + * filesystem are still going to be correct as it applies them. */ typedef enum { - /** Checkout does not update any files in the working directory. */ - GIT_CHECKOUT_DEFAULT = (1 << 0), + GIT_CHECKOUT_DEFAULT = 0, /** default is a dry run, no actual updates */ - /** When a file exists and is modified, replace it with new version. */ - GIT_CHECKOUT_OVERWRITE_MODIFIED = (1 << 1), + /** Allow update of entries where working dir matches HEAD. */ + GIT_CHECKOUT_UPDATE_UNMODIFIED = (1u << 0), - /** When a file does not exist in the working directory, create it. */ - GIT_CHECKOUT_CREATE_MISSING = (1 << 2), + /** Allow update of entries where working dir does not have file. */ + GIT_CHECKOUT_UPDATE_MISSING = (1u << 1), + + /** Allow safe updates that cannot overwrite uncommited data */ + GIT_CHECKOUT_SAFE = + (GIT_CHECKOUT_UPDATE_UNMODIFIED | GIT_CHECKOUT_UPDATE_MISSING), + + /** Allow update of entries in working dir that are modified from HEAD. */ + GIT_CHECKOUT_UPDATE_MODIFIED = (1u << 2), + + /** Update existing untracked files that are now present in the index. */ + GIT_CHECKOUT_UPDATE_UNTRACKED = (1u << 3), + + /** Allow all updates to force working directory to look like index */ + GIT_CHECKOUT_FORCE = + (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_MODIFIED | GIT_CHECKOUT_UPDATE_UNTRACKED), + + /** Allow checkout to make updates even if conflicts are found */ + GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4), + + /** Remove untracked files not in index (that are not ignored) */ + GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5), + + /** Only update existing files, don't create new ones */ + GIT_CHECKOUT_UPDATE_ONLY = (1u << 6), + + /** + * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED + */ + + /** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */ + GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10), + /** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */ + GIT_CHECKOUT_USE_OURS = (1u << 11), + /** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */ + GIT_CHECKOUT_USE_THEIRS = (1u << 12), + + /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */ + GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), + /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ + GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17), - /** If an untracked file in found in the working dir, delete it. */ - GIT_CHECKOUT_REMOVE_UNTRACKED = (1 << 3), } git_checkout_strategy_t; /** * Checkout options structure * * Use zeros to indicate default settings. + * This needs to be initialized with the `GIT_CHECKOUT_OPTS_INIT` macro: + * + * git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; */ typedef struct git_checkout_opts { - unsigned int checkout_strategy; /** default: GIT_CHECKOUT_DEFAULT */ + unsigned int version; + unsigned int checkout_strategy; /** default will be a dry run */ + int disable_filters; /** don't apply filters like CRLF conversion */ int dir_mode; /** default is 0755 */ int file_mode; /** default is 0644 or 0755 as dictated by blob */ int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */ - /** Optional callback to notify the consumer of files that - * haven't be checked out because a modified version of them - * exist in the working directory. - * - * When provided, this callback will be invoked when the flag - * GIT_CHECKOUT_OVERWRITE_MODIFIED isn't part of the checkout strategy. + /** Optional callback made on files where the index differs from the + * working directory but the rules do not allow update. Return a + * non-zero value to abort the checkout. All such callbacks will be + * made before any changes are made to the working directory. */ - int (* skipped_notify_cb)( - const char *skipped_file, - const git_oid *blob_oid, - int file_mode, + int (*conflict_cb)( + const char *conflicting_path, + const git_oid *index_oid, + unsigned int index_mode, + unsigned int wd_mode, void *payload); - void *notify_payload; + void *conflict_payload; /* Optional callback to notify the consumer of checkout progress. */ - void (* progress_cb)( - const char *path, - size_t completed_steps, - size_t total_steps, - void *payload); + void (*progress_cb)( + const char *path, + size_t completed_steps, + size_t total_steps, + void *payload); void *progress_payload; - /** When not NULL, array of fnmatch patterns specifying - * which paths should be taken into account + /** When not zeroed out, array of fnmatch patterns specifying which + * paths should be taken into account, otherwise all files. */ - git_strarray paths; + git_strarray paths; } git_checkout_opts; +#define GIT_CHECKOUT_OPTS_VERSION 1 +#define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION} + /** * Updates files in the index and the working tree to match the content of the * commit pointed at by HEAD. @@ -98,13 +206,15 @@ GIT_EXTERN(int) git_checkout_head( /** * Updates files in the working tree to match the content of the index. * - * @param repo repository to check out (must be non-bare) + * @param repo repository into which to check out (must be non-bare) + * @param index index to be checked out (or NULL to use repository index) * @param opts specifies checkout options (may be NULL) * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information * about the error) */ GIT_EXTERN(int) git_checkout_index( git_repository *repo, + git_index *index, git_checkout_opts *opts); /** @@ -120,7 +230,7 @@ GIT_EXTERN(int) git_checkout_index( */ GIT_EXTERN(int) git_checkout_tree( git_repository *repo, - git_object *treeish, + const git_object *treeish, git_checkout_opts *opts); /** @} */ diff --git a/git2/include/git2/clone.h b/git2/include/git2/clone.h index 7d8d32118..c6ab8032b 100644 --- a/git2/include/git2/clone.h +++ b/git2/include/git2/clone.h @@ -11,6 +11,7 @@ #include "types.h" #include "indexer.h" #include "checkout.h" +#include "remote.h" /** @@ -22,48 +23,81 @@ */ GIT_BEGIN_DECL +/** + * Clone options structure + * + * Use zeros to indicate default settings. It's easiest to use the + * `GIT_CLONE_OPTIONS_INIT` macro: + * + * git_clone_options opts = GIT_CLONE_OPTIONS_INIT; + * + * - `checkout_opts` is options for the checkout step. To disable checkout, + * set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT. + * - `bare` should be set to zero to create a standard repo, non-zero for + * a bare repo + * - `fetch_progress_cb` is optional callback for fetch progress. Be aware that + * this is called inline with network and indexing operations, so performance + * may be affected. + * - `fetch_progress_payload` is payload for fetch_progress_cb + * + * ** "origin" remote options: ** + * - `remote_name` is the name given to the "origin" remote. The default is + * "origin". + * - `pushurl` is a URL to be used for pushing. NULL means use the fetch url. + * - `fetch_spec` is the fetch specification to be used for fetching. NULL + * results in the same behavior as GIT_REMOTE_DEFAULT_FETCH. + * - `push_spec` is the fetch specification to be used for pushing. NULL means + * use the same spec as for fetching. + * - `cred_acquire_cb` is a callback to be used if credentials are required + * during the initial fetch. + * - `cred_acquire_payload` is the payload for the above callback. + * - `transport` is a custom transport to be used for the initial fetch. NULL + * means use the transport autodetected from the URL. + * - `remote_callbacks` may be used to specify custom progress callbacks for + * the origin remote before the fetch is initiated. + * - `remote_autotag` may be used to specify the autotag setting before the + * initial fetch. + */ + +typedef struct git_clone_options { + unsigned int version; + + git_checkout_opts checkout_opts; + int bare; + git_transfer_progress_callback fetch_progress_cb; + void *fetch_progress_payload; + + const char *remote_name; + const char *pushurl; + const char *fetch_spec; + const char *push_spec; + git_cred_acquire_cb cred_acquire_cb; + void *cred_acquire_payload; + git_transport *transport; + git_remote_callbacks *remote_callbacks; + git_remote_autotag_option_t remote_autotag; +} 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}} + /** * Clone a remote repository, and checkout the branch pointed to by the remote * HEAD. * * @param out pointer that will receive the resulting repository object - * @param origin_url repository to clone from - * @param workdir_path local directory to clone to - * @param fetch_progress_cb optional callback for fetch progress. Be aware that - * this is called inline with network and indexing operations, so performance - * may be affected. - * @param fetch_progress_payload payload for fetch_progress_cb - * @param checkout_opts options for the checkout step. If NULL, no checkout - * is performed + * @param origin_remote a remote which will act as the initial fetch source + * @param local_path local directory to clone to + * @param options configuration options for the clone. If NULL, the function + * works as though GIT_OPTIONS_INIT were passed. * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information * about the error) */ GIT_EXTERN(int) git_clone( git_repository **out, - const char *origin_url, - const char *workdir_path, - git_transfer_progress_callback fetch_progress_cb, - void *fetch_progress_payload, - git_checkout_opts *checkout_opts); - -/** - * Create a bare clone of a remote repository. - * - * @param out pointer that will receive the resulting repository object - * @param origin_url repository to clone from - * @param dest_path local directory to clone to - * @param fetch_progress_cb optional callback for fetch progress. Be aware that - * this is called inline with network and indexing operations, so performance - * may be affected. - * @param fetch_progress_payload payload for fetch_progress_cb - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error) - */ -GIT_EXTERN(int) git_clone_bare( - git_repository **out, - const char *origin_url, - const char *dest_path, - git_transfer_progress_callback fetch_progress_cb, - void *fetch_progress_payload); + const char *url, + const char *local_path, + const git_clone_options *options); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/commit.h b/git2/include/git2/commit.h index a159b79e1..872f691ce 100644 --- a/git2/include/git2/commit.h +++ b/git2/include/git2/commit.h @@ -76,7 +76,10 @@ GIT_INLINE(void) git_commit_free(git_commit *commit) * @param commit a previously loaded commit. * @return object identity for the commit. */ -GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit); +GIT_INLINE(const git_oid *) git_commit_id(const git_commit *commit) +{ + return git_object_id((const git_object *)commit); +} /** * Get the encoding for the message of a commit, @@ -88,7 +91,7 @@ GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit); * @param commit a previously loaded commit. * @return NULL, or the encoding */ -GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit); +GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit); /** * Get the full message of a commit. @@ -96,7 +99,7 @@ GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit); * @param commit a previously loaded commit. * @return the message of a commit */ -GIT_EXTERN(const char *) git_commit_message(git_commit *commit); +GIT_EXTERN(const char *) git_commit_message(const git_commit *commit); /** * Get the commit time (i.e. committer time) of a commit. @@ -104,7 +107,7 @@ GIT_EXTERN(const char *) git_commit_message(git_commit *commit); * @param commit a previously loaded commit. * @return the time of a commit */ -GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit); +GIT_EXTERN(git_time_t) git_commit_time(const git_commit *commit); /** * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit. @@ -112,7 +115,7 @@ GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit); * @param commit a previously loaded commit. * @return positive or negative timezone offset, in minutes from UTC */ -GIT_EXTERN(int) git_commit_time_offset(git_commit *commit); +GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit); /** * Get the committer of a commit. @@ -120,7 +123,7 @@ GIT_EXTERN(int) git_commit_time_offset(git_commit *commit); * @param commit a previously loaded commit. * @return the committer of a commit */ -GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit); +GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit); /** * Get the author of a commit. @@ -128,7 +131,7 @@ GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit); * @param commit a previously loaded commit. * @return the author of a commit */ -GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit); +GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit); /** * Get the tree pointed to by a commit. @@ -137,7 +140,7 @@ GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit); * @param commit a previously loaded commit. * @return 0 or an error code */ -GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit); +GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, const git_commit *commit); /** * Get the id of the tree pointed to by a commit. This differs from @@ -147,7 +150,7 @@ GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit); * @param commit a previously loaded commit. * @return the id of tree pointed to by commit. */ -GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit); +GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit); /** * Get the number of parents of this commit @@ -155,17 +158,17 @@ GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit); * @param commit a previously loaded commit. * @return integer of count of parents */ -GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit); +GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit); /** * Get the specified parent of the commit. * - * @param parent Pointer where to store the parent commit + * @param out Pointer where to store the parent commit * @param commit a previously loaded commit. * @param n the position of the parent (from 0 to `parentcount`) * @return 0 or an error code */ -GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n); +GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n); /** * Get the oid of a specified parent for a commit. This is different from @@ -176,7 +179,7 @@ GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsig * @param n the position of the parent (from 0 to `parentcount`) * @return the id of the parent, NULL on error. */ -GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned int n); +GIT_EXTERN(const git_oid *) git_commit_parent_id(git_commit *commit, unsigned int n); /** * Get the commit object that is the th generation ancestor @@ -204,7 +207,7 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( * The message will not be cleaned up. This can be achieved * through `git_message_prettify()`. * - * @param oid Pointer where to store the OID of the + * @param id Pointer where to store the OID of the * newly created commit * * @param repo Repository where to store the commit @@ -245,7 +248,7 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( * the given reference will be updated to point to it */ GIT_EXTERN(int) git_commit_create( - git_oid *oid, + git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, @@ -273,7 +276,7 @@ GIT_EXTERN(int) git_commit_create( * @see git_commit_create */ GIT_EXTERN(int) git_commit_create_v( - git_oid *oid, + git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, diff --git a/git2/include/git2/common.h b/git2/include/git2/common.h index dd6909f90..ad23d2d34 100644 --- a/git2/include/git2/common.h +++ b/git2/include/git2/common.h @@ -85,6 +85,11 @@ GIT_BEGIN_DECL */ #define GIT_PATH_MAX 4096 +/** + * The string representation of the null object ID. + */ +#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000" + /** * Return the version of the libgit2 library * being currently used. diff --git a/git2/include/git2/config.h b/git2/include/git2/config.h index 67408f90f..b186e70da 100644 --- a/git2/include/git2/config.h +++ b/git2/include/git2/config.h @@ -41,23 +41,30 @@ typedef struct { unsigned int level; } git_config_entry; +typedef int (*git_config_foreach_cb)(const git_config_entry *, void *); + + /** * Generic backend that implements the interface to * access a configuration file */ -struct git_config_file { +struct git_config_backend { + unsigned int version; struct git_config *cfg; /* Open means open the file/database and parse if necessary */ - int (*open)(struct git_config_file *, unsigned int level); - int (*get)(struct git_config_file *, const char *key, const git_config_entry **entry); - int (*get_multivar)(struct git_config_file *, const char *key, const char *regexp, int (*fn)(const git_config_entry *, void *), void *data); - int (*set)(struct git_config_file *, const char *key, const char *value); - int (*set_multivar)(git_config_file *cfg, const char *name, const char *regexp, const char *value); - int (*del)(struct git_config_file *, const char *key); - int (*foreach)(struct git_config_file *, const char *, int (*fn)(const git_config_entry *, void *), void *data); - void (*free)(struct git_config_file *); + int (*open)(struct git_config_backend *, unsigned int level); + int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); + int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); + int (*set)(struct git_config_backend *, const char *key, const char *value); + int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); + int (*del)(struct git_config_backend *, const char *key); + int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); + int (*refresh)(struct git_config_backend *); + void (*free)(struct git_config_backend *); }; +#define GIT_CONFIG_BACKEND_VERSION 1 +#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION} typedef enum { GIT_CVAR_FALSE = 0, @@ -86,11 +93,11 @@ typedef struct { * This method will not guess the path to the xdg compatible * config file (.config/git/config). * - * @param global_config_path Buffer of GIT_PATH_MAX length to store the path - * @return 0 if a global configuration file has been - * found. Its path will be stored in `buffer`. + * @param out Buffer to store the path in + * @param length size of the buffer in bytes + * @return 0 if a global configuration file has been found. Its path will be stored in `buffer`. */ -GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length); +GIT_EXTERN(int) git_config_find_global(char *out, size_t length); /** * Locate the path to the global xdg compatible configuration file @@ -103,11 +110,12 @@ GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length); * may be used on any `git_config` call to load the * xdg compatible configuration file. * - * @param xdg_config_path Buffer of GIT_PATH_MAX length to store the path + * @param out Buffer to store the path in + * @param length size of the buffer in bytes * @return 0 if a xdg compatible configuration file has been * found. Its path will be stored in `buffer`. */ -GIT_EXTERN(int) git_config_find_xdg(char *xdg_config_path, size_t length); +GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length); /** * Locate the path to the system configuration file @@ -115,11 +123,12 @@ GIT_EXTERN(int) git_config_find_xdg(char *xdg_config_path, size_t length); * If /etc/gitconfig doesn't exist, it will look for * %PROGRAMFILES%\Git\etc\gitconfig. - * @param system_config_path Buffer of GIT_PATH_MAX length to store the path + * @param global_config_path Buffer to store the path in + * @param length size of the buffer in bytes * @return 0 if a system configuration file has been * found. Its path will be stored in `buffer`. */ -GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length); +GIT_EXTERN(int) git_config_find_system(char *out, size_t length); /** * Open the global, XDG and system configuration files @@ -133,19 +142,6 @@ GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length); */ GIT_EXTERN(int) git_config_open_default(git_config **out); -/** - * Create a configuration file backend for ondisk files - * - * These are the normal `.gitconfig` files that Core Git - * processes. Note that you first have to add this file to a - * configuration object before you can query it for configuration - * variables. - * - * @param out the new backend - * @param path where the config file is located - */ -GIT_EXTERN(int) git_config_file__ondisk(struct git_config_file **out, const char *path); - /** * Allocate a new configuration object * @@ -175,9 +171,9 @@ GIT_EXTERN(int) git_config_new(git_config **out); * @return 0 on success, GIT_EEXISTS when adding more than one file * for a given priority level (and force_replace set to 0), or error code */ -GIT_EXTERN(int) git_config_add_file( +GIT_EXTERN(int) git_config_add_backend( git_config *cfg, - git_config_file *file, + git_config_backend *file, unsigned int level, int force); @@ -201,7 +197,8 @@ GIT_EXTERN(int) git_config_add_file( * @param force if a config file already exists for the given * priority level, replace it * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), or error code + * for a given priority level (and force_replace set to 0), + * GIT_ENOTFOUND when the file doesn't exist or error code */ GIT_EXTERN(int) git_config_add_file_ondisk( git_config *cfg, @@ -209,7 +206,6 @@ GIT_EXTERN(int) git_config_add_file_ondisk( unsigned int level, int force); - /** * Create a new config instance containing a single on-disk file * @@ -218,11 +214,12 @@ GIT_EXTERN(int) git_config_add_file_ondisk( * - git_config_new * - git_config_add_file_ondisk * - * @param cfg The configuration instance to create + * @param out The configuration instance to create * @param path Path to the on-disk file to open - * @return 0 or an error code + * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist + * or an error code */ -GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path); +GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path); /** * Build a single-level focused config object from a multi-level one. @@ -234,14 +231,30 @@ GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path); * will return different config instances, but containing the same config_file * instance. * + * @param out The configuration instance to create + * @param parent Multi-level config to search for the given level + * @param level Configuration level to search for * @return 0, GIT_ENOTFOUND if the passed level cannot be found in the * multi-level parent config, or an error code */ GIT_EXTERN(int) git_config_open_level( - git_config **cfg_out, - git_config *cfg_parent, + git_config **out, + const git_config *parent, unsigned int level); +/** + * Reload changed config files + * + * A config file may be changed on disk out from under the in-memory + * config object. This function causes us to look for files that have + * been modified since we last loaded them and refresh the config with + * the latest information. + * + * @param cfg The configuration to refresh + * @return 0 or an error code + */ +GIT_EXTERN(int) git_config_refresh(git_config *cfg); + /** * Free the configuration and its associated memory and files * @@ -260,7 +273,10 @@ GIT_EXTERN(void) git_config_free(git_config *cfg); * @param name the variable's name * @return 0 or an error code */ -GIT_EXTERN(int) git_config_get_config_entry(const git_config_entry **out, git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_get_entry( + const git_config_entry **out, + const git_config *cfg, + const char *name); /** * Get the value of an integer config variable. @@ -274,7 +290,7 @@ GIT_EXTERN(int) git_config_get_config_entry(const git_config_entry **out, git_co * @param name the variable's name * @return 0 or an error code */ -GIT_EXTERN(int) git_config_get_int32(int32_t *out, git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name); /** * Get the value of a long integer config variable. @@ -288,7 +304,7 @@ GIT_EXTERN(int) git_config_get_int32(int32_t *out, git_config *cfg, const char * * @param name the variable's name * @return 0 or an error code */ -GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name); /** * Get the value of a boolean config variable. @@ -305,7 +321,7 @@ GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char * * @param name the variable's name * @return 0 or an error code */ -GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name); /** * Get the value of a string config variable. @@ -322,7 +338,7 @@ GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name) * @param name the variable's name * @return 0 or an error code */ -GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name); /** * Get each value of a multivar. @@ -336,7 +352,7 @@ GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const c * @param fn the function to be called on each value of the variable * @param data opaque pointer to pass to the callback */ -GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const char *regexp, int (*fn)(const git_config_entry *, void *), void *data); +GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); /** * Set the value of an integer config variable in the config file @@ -402,7 +418,7 @@ GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const * @param cfg the configuration * @param name the variable to delete */ -GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name); +GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name); /** * Perform an operation on each config variable. @@ -418,8 +434,8 @@ GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name); * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_config_foreach( - git_config *cfg, - int (*callback)(const git_config_entry *, void *payload), + const git_config *cfg, + git_config_foreach_cb callback, void *payload); /** @@ -436,9 +452,9 @@ GIT_EXTERN(int) git_config_foreach( * @return 0 or the return value of the callback which didn't return 0 */ GIT_EXTERN(int) git_config_foreach_match( - git_config *cfg, + const git_config *cfg, const char *regexp, - int (*callback)(const git_config_entry *entry, void *payload), + git_config_foreach_cb callback, void *payload); /** @@ -475,7 +491,12 @@ GIT_EXTERN(int) git_config_foreach_match( * @param map_n number of mapping objects in `maps` * @return 0 on success, error code otherwise */ -GIT_EXTERN(int) git_config_get_mapped(int *out, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n); +GIT_EXTERN(int) git_config_get_mapped( + int *out, + const git_config *cfg, + const char *name, + const git_cvar_map *maps, + size_t map_n); /** * Maps a string value to an integer constant @@ -487,7 +508,7 @@ GIT_EXTERN(int) git_config_get_mapped(int *out, git_config *cfg, const char *nam */ GIT_EXTERN(int) git_config_lookup_map_value( int *out, - git_cvar_map *maps, + const git_cvar_map *maps, size_t map_n, const char *value); @@ -503,18 +524,6 @@ GIT_EXTERN(int) git_config_lookup_map_value( */ GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value); -/** - * Parse a string value as an int64. - * - * An optional value suffix of 'k', 'm', or 'g' will - * cause the value to be multiplied by 1024, 1048576, - * or 1073741824 prior to output. - * - * @param out place to store the result of the parsing - * @param value value to parse - */ -GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); - /** * Parse a string value as an int32. * @@ -527,6 +536,18 @@ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); */ GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value); +/** + * Parse a string value as an int64. + * + * An optional value suffix of 'k', 'm', or 'g' will + * cause the value to be multiplied by 1024, 1048576, + * or 1073741824 prior to output. + * + * @param out place to store the result of the parsing + * @param value value to parse + */ +GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); + /** @} */ GIT_END_DECL diff --git a/git2/include/git2/diff.h b/git2/include/git2/diff.h index 1932db029..b26dd4214 100644 --- a/git2/include/git2/diff.h +++ b/git2/include/git2/diff.h @@ -17,6 +17,9 @@ * @file git2/diff.h * @brief Git tree and file differencing routines. * + * Overview + * -------- + * * Calculating diffs is generally done in two phases: building a diff list * then traversing the diff list. This makes is easier to share logic * across the various types of diffs (tree vs tree, workdir vs index, etc.), @@ -24,6 +27,35 @@ * such as rename detected, in between the steps. When you are done with a * diff list object, it must be freed. * + * Terminology + * ----------- + * + * To understand the diff APIs, you should know the following terms: + * + * - A `diff` or `diff list` represents the cumulative list of differences + * between two snapshots of a repository (possibly filtered by a set of + * file name patterns). This is the `git_diff_list` object. + * - A `delta` is a file pair with an old and new revision. The old version + * may be absent if the file was just created and the new version may be + * absent if the file was deleted. A diff is mostly just a list of deltas. + * - A `binary` file / delta is a file (or pair) for which no text diffs + * should be generated. A diff list can contain delta entries that are + * binary, but no diff content will be output for those files. There is + * a base heuristic for binary detection and you can further tune the + * behavior with git attributes or diff flags and option settings. + * - A `hunk` is a span of modified lines in a delta along with some stable + * surrounding context. You can configure the amount of context and other + * properties of how hunks are generated. Each hunk also comes with a + * header that described where it starts and ends in both the old and new + * versions in the delta. + * - A `line` is a range of characters inside a hunk. It could be a context + * line (i.e. in both old and new versions), an added line (i.e. only in + * the new version), or a removed line (i.e. only in the old version). + * Unfortunately, we don't know anything about the encoding of data in the + * file being diffed, so we cannot tell you much about the line content. + * Line data will not be NUL-byte terminated, however, because it will be + * just a span of bytes inside the larger file. + * * @ingroup Git * @{ */ @@ -33,7 +65,7 @@ GIT_BEGIN_DECL * Flags for diff options. A combination of these flags can be passed * in via the `flags` value in the `git_diff_options`. */ -enum { +typedef enum { /** Normal diff, the default */ GIT_DIFF_NORMAL = 0, /** Reverse the sides of the diff */ @@ -86,7 +118,9 @@ enum { * mode set to tree. Note: the tree SHA will not be available. */ GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16), -}; + /** Ignore file mode changes */ + GIT_DIFF_IGNORE_FILEMODE = (1 << 17), +} git_diff_option_t; /** * Structure describing options about how the diff should be executed. @@ -95,36 +129,50 @@ enum { * values. Similarly, passing NULL for the options structure will * give the defaults. The default values are marked below. * - * - flags: a combination of the GIT_DIFF_... values above - * - context_lines: number of lines of context to show around diffs - * - interhunk_lines: min lines between diff hunks to merge them - * - old_prefix: "directory" to prefix to old file names (default "a") - * - new_prefix: "directory" to prefix to new file names (default "b") - * - pathspec: array of paths / patterns to constrain diff - * - max_size: maximum blob size to diff, above this treated as binary + * - `flags` is a combination of the `git_diff_option_t` values above + * - `context_lines` is the number of unchanged lines that define the + * boundary of a hunk (and to display before and after) + * - `interhunk_lines` is the maximum number of unchanged lines between + * hunk boundaries before the hunks will be merged into a one. + * - `old_prefix` is the virtual "directory" to prefix to old file names + * in hunk headers (default "a") + * - `new_prefix` is the virtual "directory" to prefix to new file names + * in hunk headers (default "b") + * - `pathspec` is an array of paths / fnmatch patterns to constrain diff + * - `max_size` is a file size (in bytes) above which a blob will be marked + * as binary automatically; pass a negative value to disable. */ typedef struct { - uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */ - uint16_t context_lines; /**< defaults to 3 */ - uint16_t interhunk_lines; /**< defaults to 0 */ - char *old_prefix; /**< defaults to "a" */ - char *new_prefix; /**< defaults to "b" */ - git_strarray pathspec; /**< defaults to show all paths */ - git_off_t max_size; /**< defaults to 512Mb */ + unsigned int version; /**< version for the struct */ + uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */ + uint16_t context_lines; /**< defaults to 3 */ + uint16_t interhunk_lines; /**< defaults to 0 */ + const char *old_prefix; /**< defaults to "a" */ + const char *new_prefix; /**< defaults to "b" */ + git_strarray pathspec; /**< defaults to include all paths */ + git_off_t max_size; /**< defaults to 512MB */ } git_diff_options; +#define GIT_DIFF_OPTIONS_VERSION 1 +#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION} + /** * The diff list 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. */ typedef struct git_diff_list git_diff_list; /** - * Flags that can be set for the file on side of a diff. + * Flags for the file object on each side of a diff. * - * Most of the flags are just for internal consumption by libgit2, - * but some of them may be interesting to external users. + * Note: most of these flags are just for **internal** consumption by + * libgit2, but some of them may be interesting to external users. */ -enum { +typedef enum { GIT_DIFF_FILE_VALID_OID = (1 << 0), /** `oid` value is known correct */ GIT_DIFF_FILE_FREE_PATH = (1 << 1), /** `path` is allocated memory */ GIT_DIFF_FILE_BINARY = (1 << 2), /** should be considered binary data */ @@ -132,25 +180,51 @@ enum { GIT_DIFF_FILE_FREE_DATA = (1 << 4), /** internal file data is allocated */ GIT_DIFF_FILE_UNMAP_DATA = (1 << 5), /** internal file data is mmap'ed */ GIT_DIFF_FILE_NO_DATA = (1 << 6), /** file data should not be loaded */ -}; +} git_diff_file_flag_t; /** * What type of change is described by a git_diff_delta? + * + * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run + * `git_diff_find_similar()` on the diff list object. + * + * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE` + * in the option flags (otherwise type changes will be split into ADDED / + * DELETED pairs). */ typedef enum { - GIT_DELTA_UNMODIFIED = 0, - GIT_DELTA_ADDED = 1, - GIT_DELTA_DELETED = 2, - GIT_DELTA_MODIFIED = 3, - GIT_DELTA_RENAMED = 4, - GIT_DELTA_COPIED = 5, - GIT_DELTA_IGNORED = 6, - GIT_DELTA_UNTRACKED = 7, - GIT_DELTA_TYPECHANGE = 8, + GIT_DELTA_UNMODIFIED = 0, /** no changes */ + GIT_DELTA_ADDED = 1, /** entry does not exist in old version */ + GIT_DELTA_DELETED = 2, /** entry does not exist in new version */ + GIT_DELTA_MODIFIED = 3, /** entry content changed between old and new */ + GIT_DELTA_RENAMED = 4, /** entry was renamed between old and new */ + GIT_DELTA_COPIED = 5, /** entry was copied from another old entry */ + GIT_DELTA_IGNORED = 6, /** entry is ignored item in workdir */ + GIT_DELTA_UNTRACKED = 7, /** entry is untracked item in workdir */ + GIT_DELTA_TYPECHANGE = 8, /** type of entry changed between old and new */ } git_delta_t; /** - * Description of one side of a diff. + * Description of one side of a diff entry. + * + * Although this is called a "file", it may actually represent a file, a + * symbolic link, a submodule commit id, or even a tree (although that only + * if you are tracking type changes or ignored/untracked directories). + * + * The `oid` is the `git_oid` of the item. If the entry represents an + * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta), + * then the oid will be zeroes. + * + * `path` is the NUL-terminated path to the entry relative to the working + * directory of the repository. + * + * `size` is the size of the entry in bytes. + * + * `flags` is a combination of the `git_diff_file_flag_t` types, but those + * are largely internal values. + * + * `mode` is, roughly, the stat() `st_mode` value for the item. This will + * be restricted to one of the `git_filemode_t` values. */ typedef struct { git_oid oid; @@ -161,17 +235,27 @@ typedef struct { } git_diff_file; /** - * Description of changes to one file. + * Description of changes to one entry. * - * When iterating over a diff list object, this will generally be passed to - * most callback functions and you can use the contents to understand - * exactly what has changed. + * When iterating over a diff list object, this will be passed to most + * callback functions and you can use the contents to understand exactly + * what has changed. * - * Under some circumstances, not all fields will be filled in, but the code - * generally tries to fill in as much as possible. One example is that the - * "binary" field will not actually look at file contents if you do not - * pass in hunk and/or line callbacks to the diff foreach iteration function. - * It will just use the git attributes for those files. + * The `old_file` repesents the "from" side of the diff and the `new_file` + * repesents to "to" side of the diff. What those means depend on the + * function that was used to generate the diff and will be documented below. + * You can also use the `GIT_DIFF_REVERSE` flag to flip it around. + * + * Although the two sides of the delta are named "old_file" and "new_file", + * they actually may correspond to entries that represent a file, a symbolic + * link, a submodule commit id, or even a tree (if you are tracking type + * changes or ignored/untracked directories). + * + * Under some circumstances, in the name of efficiency, not all fields will + * be filled in, but we generally try to fill in as much as possible. One + * example is that the "binary" field will not examine file contents if you + * do not pass in hunk and/or line callbacks to the diff foreach iteration + * function. It will just use the git attributes for those files. */ typedef struct { git_diff_file old_file; @@ -183,57 +267,61 @@ typedef struct { /** * When iterating over a diff, callback that will be made per file. + * + * @param delta A pointer to the delta data for the file + * @param progress Goes from 0 to 1 over the diff list + * @param payload User-specified pointer from foreach function */ -typedef int (*git_diff_file_fn)( - void *cb_data, +typedef int (*git_diff_file_cb)( const git_diff_delta *delta, - float progress); + float progress, + void *payload); /** * Structure describing a hunk of a diff. */ typedef struct { - int old_start; - int old_lines; - int new_start; - int new_lines; + int old_start; /** Starting line number in old_file */ + int old_lines; /** Number of lines in old_file */ + int new_start; /** Starting line number in new_file */ + int new_lines; /** Number of lines in new_file */ } git_diff_range; /** * When iterating over a diff, callback that will be made per hunk. */ -typedef int (*git_diff_hunk_fn)( - void *cb_data, +typedef int (*git_diff_hunk_cb)( const git_diff_delta *delta, const git_diff_range *range, const char *header, - size_t header_len); + size_t header_len, + void *payload); /** * Line origin constants. * * These values describe where a line came from and will be passed to - * the git_diff_data_fn when iterating over a diff. There are some + * the git_diff_data_cb when iterating over a diff. There are some * special origin constants at the end that are used for the text * output callbacks to demarcate lines that are actually part of * the file or hunk headers. */ -enum { - /* These values will be sent to `git_diff_data_fn` along with the line */ +typedef enum { + /* These values will be sent to `git_diff_data_cb` along with the line */ GIT_DIFF_LINE_CONTEXT = ' ', GIT_DIFF_LINE_ADDITION = '+', GIT_DIFF_LINE_DELETION = '-', GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */ GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */ - /* The following values will only be sent to a `git_diff_data_fn` when + /* The following values will only be sent to a `git_diff_data_cb` when * the content of a diff is being formatted (eg. through * git_diff_print_patch() or git_diff_print_compact(), for instance). */ GIT_DIFF_LINE_FILE_HDR = 'F', GIT_DIFF_LINE_HUNK_HDR = 'H', GIT_DIFF_LINE_BINARY = 'B' -}; +} git_diff_line_t; /** * When iterating over a diff, callback that will be made per text diff @@ -243,13 +331,13 @@ enum { * of text. This uses some extra GIT_DIFF_LINE_... constants for output * of lines of file and hunk headers. */ -typedef int (*git_diff_data_fn)( - void *cb_data, - const git_diff_delta *delta, - const git_diff_range *range, - char line_origin, /**< GIT_DIFF_LINE_... value from above */ - const char *content, - size_t content_len); +typedef int (*git_diff_data_cb)( + const git_diff_delta *delta, /** delta that contains this data */ + const git_diff_range *range, /** range of lines containing this data */ + char line_origin, /** git_diff_list_t value from above */ + const char *content, /** diff data - not NUL terminated */ + size_t content_len, /** number of bytes of diff data */ + void *payload); /** user reference data */ /** * The diff patch is used to store all the text diffs for a delta. @@ -259,6 +347,50 @@ typedef int (*git_diff_data_fn)( */ typedef struct git_diff_patch git_diff_patch; +/** + * Flags to control the behavior of diff rename/copy detection. + */ +typedef enum { + /** look for renames? (`--find-renames`) */ + GIT_DIFF_FIND_RENAMES = (1 << 0), + /** consider old size of modified for renames? (`--break-rewrites=N`) */ + GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1 << 1), + + /** look for copies? (a la `--find-copies`) */ + GIT_DIFF_FIND_COPIES = (1 << 2), + /** consider unmodified as copy sources? (`--find-copies-harder`) */ + GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3), + + /** split large rewrites into delete/add pairs (`--break-rewrites=/M`) */ + GIT_DIFF_FIND_AND_BREAK_REWRITES = (1 << 4), +} git_diff_find_t; + +/** + * Control behavior of rename and copy detection + */ +typedef struct { + unsigned int version; + + /** Combination of git_diff_find_t values (default FIND_RENAMES) */ + unsigned int flags; + + /** Similarity to consider a file renamed (default 50) */ + unsigned int rename_threshold; + /** Similarity of modified to be eligible rename source (default 50) */ + unsigned int rename_from_rewrite_threshold; + /** Similarity to consider a file a copy (default 50) */ + unsigned int copy_threshold; + /** Similarity to split modify into delete/add pair (default 60) */ + unsigned int break_rewrite_threshold; + + /** Maximum similarity sources to examine (a la diff's `-l` option or + * the `diff.renameLimit` config) (default 200) + */ + unsigned int target_limit; +} git_diff_find_options; + +#define GIT_DIFF_FIND_OPTIONS_VERSION 1 +#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION} /** @name Diff List Generator Functions * @@ -273,89 +405,104 @@ typedef struct git_diff_patch git_diff_patch; GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); /** - * Compute a difference between two tree objects. + * Create a diff list with the difference between two tree objects. * - * This is equivalent to `git diff ` + * This is equivalent to `git diff ` * + * The first tree will be used for the "old_file" side of the delta and the + * second tree will be used for the "new_file" side of the delta. + * + * @param diff Output pointer to a git_diff_list pointer to be allocated. * @param repo The repository containing the trees. - * @param opts Structure with options to influence diff or NULL for defaults. * @param old_tree A git_tree object to diff from. * @param new_tree A git_tree object to diff to. - * @param diff A pointer to a git_diff_list pointer that will be allocated. + * @param opts Structure with options to influence diff or NULL for defaults. */ GIT_EXTERN(int) git_diff_tree_to_tree( + git_diff_list **diff, git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ git_tree *old_tree, git_tree *new_tree, - git_diff_list **diff); + const git_diff_options *opts); /**< can be NULL for defaults */ /** - * Compute a difference between a tree and the index. + * Create a diff list between a tree and repository index. * * This is equivalent to `git diff --cached ` or if you pass * the HEAD tree, then like `git diff --cached`. * + * The tree you pass will be used for the "old_file" side of the delta, and + * the index will be used for the "new_file" side of the delta. + * + * @param diff Output pointer to a git_diff_list pointer to be allocated. * @param repo The repository containing the tree and index. - * @param opts Structure with options to influence diff or NULL for defaults. * @param old_tree A git_tree object to diff from. - * @param diff A pointer to a git_diff_list pointer that will be allocated. + * @param index The index to diff with; repo index used if NULL. + * @param opts Structure with options to influence diff or NULL for defaults. */ -GIT_EXTERN(int) git_diff_index_to_tree( +GIT_EXTERN(int) git_diff_tree_to_index( + git_diff_list **diff, git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ git_tree *old_tree, - git_diff_list **diff); + git_index *index, + const git_diff_options *opts); /**< can be NULL for defaults */ /** - * Compute a difference between the working directory and the index. + * Create a diff list between the repository index and the workdir directory. * * This matches the `git diff` command. See the note below on - * `git_diff_workdir_to_tree` for a discussion of the difference between + * `git_diff_tree_to_workdir` for a discussion of the difference between * `git diff` and `git diff HEAD` and how to emulate a `git diff ` * using libgit2. * + * The index will be used for the "old_file" side of the delta, and the + * working directory will be used for the "new_file" side of the delta. + * + * @param diff Output pointer to a git_diff_list pointer to be allocated. * @param repo The repository. + * @param index The index to diff from; repo index used if NULL. * @param opts Structure with options to influence diff or NULL for defaults. - * @param diff A pointer to a git_diff_list pointer that will be allocated. */ -GIT_EXTERN(int) git_diff_workdir_to_index( +GIT_EXTERN(int) git_diff_index_to_workdir( + git_diff_list **diff, git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ - git_diff_list **diff); + git_index *index, + const git_diff_options *opts); /**< can be NULL for defaults */ /** - * Compute a difference between the working directory and a tree. + * Create a diff list between a tree and the working directory. * - * This is *NOT* the same as `git diff `. Running `git diff HEAD` - * or the like actually uses information from the index, along with the tree - * and workdir dir info. + * The tree you provide will be used for the "old_file" side of the delta, + * and the working directory will be used for the "new_file" side. + * + * Please note: this is *NOT* the same as `git diff `. Running + * `git diff HEAD` or the like actually uses information from the index, + * along with the tree and working directory info. * * This function returns strictly the differences between the tree and the * files contained in the working directory, regardless of the state of * files in the index. It may come as a surprise, but there is no direct * equivalent in core git. * - * To emulate `git diff `, you should call both - * `git_diff_index_to_tree` and `git_diff_workdir_to_index`, then call - * `git_diff_merge` on the results. That will yield a `git_diff_list` that - * matches the git output. + * To emulate `git diff `, 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. * * 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 repo The repository containing the tree. - * @param opts Structure with options to influence diff or NULL for defaults. - * @param old_tree A git_tree object to diff from. * @param diff A pointer to a git_diff_list pointer that will be allocated. + * @param repo The repository containing the tree. + * @param old_tree A git_tree object to diff from. + * @param opts Structure with options to influence diff or NULL for defaults. */ -GIT_EXTERN(int) git_diff_workdir_to_tree( +GIT_EXTERN(int) git_diff_tree_to_workdir( + git_diff_list **diff, git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ git_tree *old_tree, - git_diff_list **diff); + const git_diff_options *opts); /**< can be NULL for defaults */ /** * Merge one diff list into another. @@ -374,6 +521,22 @@ GIT_EXTERN(int) git_diff_merge( git_diff_list *onto, const git_diff_list *from); +/** + * Transform a diff list marking file renames, copies, etc. + * + * This modifies a diff list in place, replacing old entries that look + * like renames or copies with new entries reflecting those changes. + * This also will, if requested, break modified files into add/remove + * pairs if the amount of change is above a threshold. + * + * @param diff Diff list to run detection algorithms on + * @param options Control how detection should be run, NULL for defaults + * @return 0 on success, -1 on failure + */ +GIT_EXTERN(int) git_diff_find_similar( + git_diff_list *diff, + git_diff_find_options *options); + /**@}*/ @@ -399,7 +562,6 @@ GIT_EXTERN(int) git_diff_merge( * the iteration and cause this return `GIT_EUSER`. * * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callbacks. * @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 @@ -407,14 +569,15 @@ GIT_EXTERN(int) git_diff_merge( * @param line_cb Optional callback to make per line of diff text. This * same callback will be made for context lines, added, and * removed lines, and even for a deleted trailing newline. + * @param payload Reference pointer that will be passed to your callbacks. * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_diff_foreach( git_diff_list *diff, - void *cb_data, - git_diff_file_fn file_cb, - git_diff_hunk_fn hunk_cb, - git_diff_data_fn line_cb); + git_diff_file_cb file_cb, + git_diff_hunk_cb hunk_cb, + git_diff_data_cb line_cb, + void *payload); /** * Iterate over a diff generating text output like "git diff --name-status". @@ -423,14 +586,14 @@ GIT_EXTERN(int) git_diff_foreach( * iteration and cause this return `GIT_EUSER`. * * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callback. * @param print_cb Callback to make per line of diff text. + * @param payload Reference pointer that will be passed to your callback. * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_diff_print_compact( git_diff_list *diff, - void *cb_data, - git_diff_data_fn print_cb); + git_diff_data_cb print_cb, + void *payload); /** * Look up the single character abbreviation for a delta status code. @@ -455,7 +618,7 @@ GIT_EXTERN(char) git_diff_status_char(git_delta_t status); * iteration and cause this return `GIT_EUSER`. * * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callbacks. + * @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 @@ -465,8 +628,8 @@ GIT_EXTERN(char) git_diff_status_char(git_delta_t status); */ GIT_EXTERN(int) git_diff_print_patch( git_diff_list *diff, - void *cb_data, - git_diff_data_fn print_cb); + git_diff_data_cb print_cb, + void *payload); /** * Query how many diff records are there in a diff list. @@ -510,15 +673,15 @@ GIT_EXTERN(size_t) git_diff_num_deltas_of_type( * It is okay to pass NULL for either of the output parameters; if you pass * NULL for the `git_diff_patch`, then the text diff will not be calculated. * - * @param patch Output parameter for the delta patch object - * @param delta Output parameter for the delta object + * @param patch_out Output parameter for the delta patch object + * @param delta_out Output parameter for the delta object * @param diff Diff list object * @param idx Index into diff list * @return 0 on success, other value < 0 on error */ GIT_EXTERN(int) git_diff_get_patch( - git_diff_patch **patch, - const git_diff_delta **delta, + git_diff_patch **patch_out, + const git_diff_delta **delta_out, git_diff_list *diff, size_t idx); @@ -603,6 +766,34 @@ GIT_EXTERN(int) git_diff_patch_get_line_in_hunk( size_t hunk_idx, size_t line_of_hunk); +/** + * Serialize the patch to text via callback. + * + * Returning a non-zero value from the callback will terminate the iteration + * and cause this return `GIT_EUSER`. + * + * @param patch A git_diff_patch representing changes to one file + * @param print_cb Callback function to output lines of the patch. Will be + * called for file headers, hunk headers, and diff lines. + * @param payload Reference pointer that will be passed to your callbacks. + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +GIT_EXTERN(int) git_diff_patch_print( + git_diff_patch *patch, + git_diff_data_cb print_cb, + void *payload); + +/** + * Get the content of a patch as a single diff text. + * + * @param string Allocated string; caller must free. + * @param patch A git_diff_patch representing changes to one file + * @return 0 on success, <0 on failure. + */ +GIT_EXTERN(int) git_diff_patch_to_str( + char **string, + git_diff_patch *patch); + /**@}*/ @@ -628,10 +819,10 @@ GIT_EXTERN(int) git_diff_blobs( git_blob *old_blob, git_blob *new_blob, const git_diff_options *options, - void *cb_data, - git_diff_file_fn file_cb, - git_diff_hunk_fn hunk_cb, - git_diff_data_fn line_cb); + git_diff_file_cb file_cb, + git_diff_hunk_cb hunk_cb, + git_diff_data_cb line_cb, + void *payload); GIT_END_DECL diff --git a/git2/include/git2/errors.h b/git2/include/git2/errors.h index fb56dcc6b..4eb9e94ef 100644 --- a/git2/include/git2/errors.h +++ b/git2/include/git2/errors.h @@ -29,6 +29,8 @@ enum { GIT_EBAREREPO = -8, GIT_EORPHANEDHEAD = -9, GIT_EUNMERGED = -10, + GIT_ENONFASTFORWARD = -11, + GIT_EINVALIDSPEC = -12, GIT_PASSTHROUGH = -30, GIT_ITEROVER = -31, @@ -59,6 +61,10 @@ typedef enum { GITERR_SSL, GITERR_SUBMODULE, GITERR_THREAD, + GITERR_STASH, + GITERR_CHECKOUT, + GITERR_FETCHHEAD, + GITERR_MERGE, } git_error_t; /** diff --git a/git2/include/git2/graph.h b/git2/include/git2/graph.h new file mode 100644 index 000000000..c89efa6dd --- /dev/null +++ b/git2/include/git2/graph.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_graph_h__ +#define INCLUDE_git_graph_h__ + +#include "common.h" +#include "types.h" +#include "oid.h" + +/** + * @file git2/graph.h + * @brief Git graph traversal routines + * @defgroup git_revwalk Git graph traversal routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Count the number of unique commits between two commit objects + * + * @param ahead number of commits, starting at `one`, unique from commits in `two` + * @param behind number of commits, starting at `two`, unique from commits in `one` + * @param repo the repository where the commits exist + * @param one one of the commits + * @param two the other commit + */ +GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *one, const git_oid *two); + +/** @} */ +GIT_END_DECL +#endif diff --git a/git2/include/git2/ignore.h b/git2/include/git2/ignore.h index e18615edd..592c96e65 100644 --- a/git2/include/git2/ignore.h +++ b/git2/include/git2/ignore.h @@ -41,9 +41,10 @@ GIT_EXTERN(int) git_ignore_add_rule( /** * Clear ignore rules that were explicitly added. * - * Clears the internal ignore rules that have been set up. This will not - * turn off the rules in .gitignore files that actually exist in the - * filesystem. + * Resets to the default internal ignore rules. This will not turn off + * rules in .gitignore files that actually exist in the filesystem. + * + * The default internal ignores ignore ".", ".." and ".git" entries. * * @param repo The repository to remove ignore rules from. * @return 0 on success diff --git a/git2/include/git2/index.h b/git2/include/git2/index.h index d8282e80f..fa9a19785 100644 --- a/git2/include/git2/index.h +++ b/git2/include/git2/index.h @@ -21,10 +21,10 @@ */ GIT_BEGIN_DECL -#define GIT_IDXENTRY_NAMEMASK (0x0fff) +#define GIT_IDXENTRY_NAMEMASK (0x0fff) #define GIT_IDXENTRY_STAGEMASK (0x3000) -#define GIT_IDXENTRY_EXTENDED (0x4000) -#define GIT_IDXENTRY_VALID (0x8000) +#define GIT_IDXENTRY_EXTENDED (0x4000) +#define GIT_IDXENTRY_VALID (0x8000) #define GIT_IDXENTRY_STAGESHIFT 12 /* @@ -34,26 +34,26 @@ GIT_BEGIN_DECL * * In-memory only flags: */ -#define GIT_IDXENTRY_UPDATE (1 << 0) -#define GIT_IDXENTRY_REMOVE (1 << 1) -#define GIT_IDXENTRY_UPTODATE (1 << 2) -#define GIT_IDXENTRY_ADDED (1 << 3) +#define GIT_IDXENTRY_UPDATE (1 << 0) +#define GIT_IDXENTRY_REMOVE (1 << 1) +#define GIT_IDXENTRY_UPTODATE (1 << 2) +#define GIT_IDXENTRY_ADDED (1 << 3) -#define GIT_IDXENTRY_HASHED (1 << 4) -#define GIT_IDXENTRY_UNHASHED (1 << 5) -#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ -#define GIT_IDXENTRY_CONFLICTED (1 << 7) +#define GIT_IDXENTRY_HASHED (1 << 4) +#define GIT_IDXENTRY_UNHASHED (1 << 5) +#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ +#define GIT_IDXENTRY_CONFLICTED (1 << 7) -#define GIT_IDXENTRY_UNPACKED (1 << 8) +#define GIT_IDXENTRY_UNPACKED (1 << 8) #define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) /* * Extended on-disk flags: */ -#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) -#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) +#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) +#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) /* GIT_IDXENTRY_EXTENDED2 is for future extension */ -#define GIT_IDXENTRY_EXTENDED2 (1 << 15) +#define GIT_IDXENTRY_EXTENDED2 (1 << 15) #define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) @@ -84,12 +84,12 @@ typedef struct git_index_entry { char *path; } git_index_entry; -/** Representation of an unmerged file entry in the index. */ -typedef struct git_index_entry_unmerged { +/** Representation of a resolve undo entry in the index. */ +typedef struct git_index_reuc_entry { unsigned int mode[3]; git_oid oid[3]; char *path; -} git_index_entry_unmerged; +} git_index_reuc_entry; /** Capabilities of system that affect index actions. */ enum { @@ -99,6 +99,12 @@ enum { GIT_INDEXCAP_FROM_OWNER = ~0u }; +/** @name Index File Functions + * + * These functions work on the index file itself. + */ +/**@{*/ + /** * Create a new bare Git index object as a memory representation * of the Git index file in 'index_path', without a repository @@ -113,20 +119,24 @@ enum { * * The index must be freed once it's no longer in use. * - * @param index the pointer for the new index + * @param out the pointer for the new index * @param index_path the path to the index file in disk * @return 0 or an error code */ -GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path); +GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path); /** - * Clear the contents (all the entries) of an index object. - * This clears the index object in memory; changes must be manually - * written to disk for them to take effect. + * Create an in-memory index object. * - * @param index an existing index object + * This index object cannot be read/written to the filesystem, + * but may be used to perform in-memory index operations. + * + * The index must be freed once it's no longer in use. + * + * @param out the pointer for the new index + * @return 0 or an error code */ -GIT_EXTERN(void) git_index_clear(git_index *index); +GIT_EXTERN(int) git_index_new(git_index **out); /** * Free an existing index object. @@ -135,6 +145,14 @@ GIT_EXTERN(void) git_index_clear(git_index *index); */ GIT_EXTERN(void) git_index_free(git_index *index); +/** + * Get the repository this index relates to + * + * @param index The index + * @return A pointer to the repository + */ +GIT_EXTERN(git_repository *) git_index_owner(const git_index *index); + /** * Read index capabilities flags. * @@ -175,112 +193,64 @@ GIT_EXTERN(int) git_index_read(git_index *index); GIT_EXTERN(int) git_index_write(git_index *index); /** - * Find the first index of any entries which point to given - * path in the Git index. + * Read a tree into the index file with stats + * + * The current index contents will be replaced by the specified tree. * * @param index an existing index object - * @param path path to search - * @return an index >= 0 if found, -1 otherwise - */ -GIT_EXTERN(int) git_index_find(git_index *index, const char *path); - -/** - * Remove all entries with equal path except last added - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_uniq(git_index *index); - -/** - * Add or update an index entry from a file in disk - * - * The file `path` must be relative to the repository's - * working folder and must be readable. - * - * This method will fail in bare index instances. - * - * This forces the file to be added to the index, not looking - * at gitignore rules. Those rules can be evaluated through - * the git_status APIs (in status.h) before calling this. - * - * @param index an existing index object - * @param path filename to add - * @param stage stage for the entry + * @param tree tree to read * @return 0 or an error code */ -GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage); +GIT_EXTERN(int) git_index_read_tree(git_index *index, const git_tree *tree); /** - * Add or update an index entry from an in-memory struct + * Write the index as a tree * - * A full copy (including the 'path' string) of the given - * 'source_entry' will be inserted on the index. + * This method will scan the index and write a representation + * of its current state back to disk; it recursively creates + * tree objects for each of the subtrees stored in the index, + * but only returns the OID of the root tree. This is the OID + * that can be used e.g. to create a commit. * - * @param index an existing index object - * @param source_entry new entry object - * @return 0 or an error code + * The index instance cannot be bare, and needs to be associated + * to an existing repository. + * + * The index must not contain any file in conflict. + * + * @param out Pointer where to store the OID of the written tree + * @param index Index to write + * @return 0 on success, GIT_EUNMERGED when the index is not clean + * or an error code */ -GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry); +GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index); /** - * Add (append) an index entry from a file in disk + * Write the index as a tree to the given repository * - * A new entry will always be inserted into the index; - * if the index already contains an entry for such - * path, the old entry will **not** be replaced. + * This method will do the same as `git_index_write_tree`, but + * letting the user choose the repository where the tree will + * be written. * - * The file `path` must be relative to the repository's - * working folder and must be readable. + * The index must not contain any file in conflict. * - * This method will fail in bare index instances. - * - * @param index an existing index object - * @param path filename to add - * @param stage stage for the entry - * @return 0 or an error code + * @param out Pointer where to store OID of the the written tree + * @param index Index to write + * @param repo Repository where to write the tree + * @return 0 on success, GIT_EUNMERGED when the index is not clean + * or an error code */ -GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage); +GIT_EXTERN(int) git_index_write_tree_to(git_oid *out, git_index *index, git_repository *repo); -/** - * Add (append) an index entry from an in-memory struct +/**@}*/ + +/** @name Raw Index Entry Functions * - * A new entry will always be inserted into the index; - * if the index already contains an entry for the path - * in the `entry` struct, the old entry will **not** be - * replaced. - * - * A full copy (including the 'path' string) of the given - * 'source_entry' will be inserted on the index. - * - * @param index an existing index object - * @param source_entry new entry object - * @return 0 or an error code + * These functions work on index entries, and allow for raw manipulation + * of the entries. */ -GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry); +/**@{*/ -/** - * Remove an entry from the index - * - * @param index an existing index object - * @param position position of the entry to remove - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_remove(git_index *index, int position); - - -/** - * Get a pointer to one of the entries in the index - * - * This entry can be modified, and the changes will be written - * back to disk on the next write() call. - * - * The entry should not be freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the entry; NULL if out of bounds - */ -GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, size_t n); +/* Index entry manipulation */ /** * Get the count of entries currently in the index @@ -288,39 +258,75 @@ GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, size_t n); * @param index an existing index object * @return integer of count of current entries */ -GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index); +GIT_EXTERN(size_t) git_index_entrycount(const git_index *index); /** - * Get the count of unmerged entries currently in the index + * Clear the contents (all the entries) of an index object. + * This clears the index object in memory; changes must be manually + * written to disk for them to take effect. * * @param index an existing index object - * @return integer of count of current unmerged entries */ -GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index); +GIT_EXTERN(void) git_index_clear(git_index *index); /** - * Get an unmerged entry from the index. + * Get a pointer to one of the entries in the index * - * The returned entry is read-only and should not be modified - * of freed by the caller. + * The values of this entry can be modified (except the path) + * and the changes will be written back to disk on the next + * write() call. * - * @param index an existing index object - * @param path path to search - * @return the unmerged entry; NULL if not found - */ -GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_bypath(git_index *index, const char *path); - -/** - * Get an unmerged entry from the index. - * - * The returned entry is read-only and should not be modified - * of freed by the caller. + * The entry should not be freed by the caller. * * @param index an existing index object * @param n the position of the entry - * @return a pointer to the unmerged entry; NULL if out of bounds + * @return a pointer to the entry; NULL if out of bounds */ -GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_index *index, size_t n); +GIT_EXTERN(const git_index_entry *) git_index_get_byindex( + git_index *index, size_t n); + +/** + * Get a pointer to one of the entries in the index + * + * The values of this entry can be modified (except the path) + * and the changes will be written back to disk on the next + * write() call. + * + * The entry should not be freed by the caller. + * + * @param index an existing index object + * @param path path to search + * @param stage stage to search + * @return a pointer to the entry; NULL if it was not found + */ +GIT_EXTERN(const git_index_entry *) git_index_get_bypath( + git_index *index, const char *path, int stage); + +/** + * Remove an entry from the index + * + * @param index an existing index object + * @param path path to search + * @param stage stage to search + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage); + +/** + * Add or update an index entry from an in-memory struct + * + * If a previous index entry exists that has the same path and stage + * as the given 'source_entry', it will be replaced. Otherwise, the + * 'source_entry' will be added. + * + * A full copy (including the 'path' string) of the given + * 'source_entry' will be inserted on the index. + * + * @param index an existing index object + * @param source_entry new entry object + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry); /** * Return the stage number from a git index entry @@ -335,17 +341,200 @@ GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_ */ GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry); -/** - * Read a tree into the index file with stats +/**@}*/ + +/** @name Workdir Index Entry Functions * - * The current index contents will be replaced by the specified tree. The total - * node count is collected in stats. + * These functions work on index entries specifically in the working + * directory (ie, stage 0). + */ +/**@{*/ + +/** + * Add or update an index entry from a file in disk + * + * The file `path` must be relative to the repository's + * working folder and must be readable. + * + * This method will fail in bare index instances. + * + * This forces the file to be added to the index, not looking + * at gitignore rules. Those rules can be evaluated through + * the git_status APIs (in status.h) before calling this. + * + * If this file currently is the result of a merge conflict, this + * file will no longer be marked as conflicting. The data about + * the conflict will be moved to the "resolve undo" (REUC) section. * * @param index an existing index object - * @param tree tree to read + * @param path filename to add * @return 0 or an error code */ -GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree); +GIT_EXTERN(int) git_index_add_from_workdir(git_index *index, const char *path); + +/** + * Find the first index of any entries which point to given + * path in the Git index. + * + * @param index an existing index object + * @param path path to search + * @return an index >= 0 if found, -1 otherwise + */ +GIT_EXTERN(int) git_index_find(git_index *index, const char *path); + +/**@}*/ + +/** @name Conflict Index Entry Functions + * + * These functions work on conflict index entries specifically (ie, stages 1-3) + */ +/**@{*/ + +/** + * Add or update index entries to represent a conflict + * + * The entries are the entries from the tree included in the merge. Any + * entry may be null to indicate that that file was not present in the + * trees during the merge. For example, ancestor_entry may be NULL to + * indicate that a file was added in both branches and must be resolved. + * + * @param index an existing index object + * @param ancestor_entry the entry data for the ancestor of the conflict + * @param our_entry the entry data for our side of the merge conflict + * @param their_entry the entry data for their side of the merge conflict + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_conflict_add( + git_index *index, + const git_index_entry *ancestor_entry, + const git_index_entry *our_entry, + const git_index_entry *their_entry); + +/** + * Get the index entries that represent a conflict of a single file. + * + * The values of this entry can be modified (except the paths) + * and the changes will be written back to disk on the next + * write() call. + * + * @param ancestor_out Pointer to store the ancestor entry + * @param our_out Pointer to store the our entry + * @param their_out Pointer to store the their entry + * @param index an existing index object + * @param path path to search + */ +GIT_EXTERN(int) git_index_conflict_get(git_index_entry **ancestor_out, git_index_entry **our_out, git_index_entry **their_out, git_index *index, const char *path); + +/** + * Removes the index entries that represent a conflict of a single file. + * + * @param index an existing index object + * @param path to search + */ +GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path); + +/** + * Remove all conflicts in the index (entries with a stage greater than 0.) + * + * @param index an existing index object + */ +GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index); + +/** + * Determine if the index contains entries representing file conflicts. + * + * @return 1 if at least one conflict is found, 0 otherwise. + */ +GIT_EXTERN(int) git_index_has_conflicts(const git_index *index); + +/**@}*/ + +/** @name Resolve Undo (REUC) index entry manipulation. + * + * These functions work on the Resolve Undo index extension and contains + * data about the original files that led to a merge conflict. + */ +/**@{*/ + +/** + * Get the count of resolve undo entries currently in the index. + * + * @param index an existing index object + * @return integer of count of current resolve undo entries + */ +GIT_EXTERN(unsigned int) git_index_reuc_entrycount(git_index *index); + +/** + * Finds the resolve undo entry that points to the given path in the Git + * index. + * + * @param index an existing index object + * @param path path to search + * @return an index >= 0 if found, -1 otherwise + */ +GIT_EXTERN(int) git_index_reuc_find(git_index *index, const char *path); + +/** + * Get a resolve undo entry from the index. + * + * The returned entry is read-only and should not be modified + * or freed by the caller. + * + * @param index an existing index object + * @param path path to search + * @return the resolve undo entry; NULL if not found + */ +GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path); + +/** + * Get a resolve undo entry from the index. + * + * The returned entry is read-only and should not be modified + * or freed by the caller. + * + * @param index an existing index object + * @param n the position of the entry + * @return a pointer to the resolve undo entry; NULL if out of bounds + */ +GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n); + +/** + * Adds a resolve undo entry for a file based on the given parameters. + * + * The resolve undo entry contains the OIDs of files that were involved + * in a merge conflict after the conflict has been resolved. This allows + * conflicts to be re-resolved later. + * + * If there exists a resolve undo entry for the given path in the index, + * it will be removed. + * + * This method will fail in bare index instances. + * + * @param index an existing index object + * @param path filename to add + * @param ancestor_mode mode of the ancestor file + * @param ancestor_id oid of the ancestor file + * @param our_mode mode of our file + * @param our_id oid of our file + * @param their_mode mode of their file + * @param their_id oid of their file + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path, + int ancestor_mode, git_oid *ancestor_id, + int our_mode, git_oid *our_id, + int their_mode, git_oid *their_id); + +/** + * Remove an resolve undo entry from the index + * + * @param index an existing index object + * @param n position of the resolve undo entry to remove + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n); + +/**@}*/ /** @} */ GIT_END_DECL diff --git a/git2/include/git2/indexer.h b/git2/include/git2/indexer.h index a2a155473..41a1503a4 100644 --- a/git2/include/git2/indexer.h +++ b/git2/include/git2/indexer.h @@ -44,14 +44,14 @@ GIT_EXTERN(int) git_indexer_stream_new( git_indexer_stream **out, const char *path, git_transfer_progress_callback progress_cb, - void *progress_callback_payload); + void *progress_cb_payload); /** * Add data to the indexer * * @param idx the indexer * @param data the data to add - * @param size the size of the data + * @param size the size of the data in bytes * @param stats stat storage */ GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_transfer_progress *stats); @@ -73,7 +73,7 @@ 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(git_indexer_stream *idx); +GIT_EXTERN(const git_oid *) git_indexer_stream_hash(const git_indexer_stream *idx); /** * Free the indexer and its resources @@ -120,7 +120,7 @@ GIT_EXTERN(int) git_indexer_write(git_indexer *idx); * * @param idx the indexer instance */ -GIT_EXTERN(const git_oid *) git_indexer_hash(git_indexer *idx); +GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); /** * Free the indexer and its resources diff --git a/git2/include/git2/merge.h b/git2/include/git2/merge.h index 37b1c787d..59493969c 100644 --- a/git2/include/git2/merge.h +++ b/git2/include/git2/merge.h @@ -27,8 +27,13 @@ GIT_BEGIN_DECL * @param repo the repository where the commits exist * @param one one of the commits * @param two the other commit + * @return Zero on success; GIT_ENOTFOUND or -1 on failure. */ -GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two); +GIT_EXTERN(int) git_merge_base( + git_oid *out, + git_repository *repo, + const git_oid *one, + const git_oid *two); /** * Find a merge base given a list of commits @@ -37,8 +42,13 @@ GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, const git_oid * @param repo the repository where the commits exist * @param input_array oids of the commits * @param length The number of commits in the provided `input_array` + * @return Zero on success; GIT_ENOTFOUND or -1 on failure. */ -GIT_EXTERN(int) git_merge_base_many(git_oid *out, git_repository *repo, const git_oid input_array[], size_t length); +GIT_EXTERN(int) git_merge_base_many( + git_oid *out, + git_repository *repo, + const git_oid input_array[], + size_t length); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/message.h b/git2/include/git2/message.h index b42cb7677..e89d022a1 100644 --- a/git2/include/git2/message.h +++ b/git2/include/git2/message.h @@ -23,21 +23,27 @@ GIT_BEGIN_DECL * * Optionally, can remove lines starting with a "#". * - * @param message_out The user allocated buffer which will be filled with - * the cleaned up message. Pass NULL if you just want to get the size of the - * prettified message as the output value. + * @param out The user-allocated buffer which will be filled with the + * cleaned up message. Pass NULL if you just want to get the needed + * size of the prettified message as the output value. * - * @param size The size of the allocated buffer message_out. + * @param out_size Size of the `out` buffer in bytes. * * @param message The message to be prettified. * - * @param strip_comments 1 to remove lines starting with a "#", 0 otherwise. + * @param strip_comments Non-zero to remove lines starting with "#", 0 to + * leave them in. * * @return -1 on error, else number of characters in prettified message - * including the trailing NUL byte + * including the trailing NUL byte */ -GIT_EXTERN(int) git_message_prettify(char *message_out, size_t buffer_size, const char *message, int strip_comments); +GIT_EXTERN(int) git_message_prettify( + char *out, + size_t out_size, + const char *message, + int strip_comments); /** @} */ GIT_END_DECL + #endif /* INCLUDE_git_message_h__ */ diff --git a/git2/include/git2/net.h b/git2/include/git2/net.h index c2301b6f1..2543ff8e0 100644 --- a/git2/include/git2/net.h +++ b/git2/include/git2/net.h @@ -4,8 +4,8 @@ * This file is part of libgit2, distributed under the GNU GPL v2 with * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_net_h__ -#define INCLUDE_net_h__ +#ifndef INCLUDE_git_net_h__ +#define INCLUDE_git_net_h__ #include "common.h" #include "oid.h" @@ -27,8 +27,10 @@ GIT_BEGIN_DECL * gets called. */ -#define GIT_DIR_FETCH 0 -#define GIT_DIR_PUSH 1 +typedef enum { + GIT_DIRECTION_FETCH = 0, + GIT_DIRECTION_PUSH = 1 +} git_direction; /** @@ -44,7 +46,7 @@ struct git_remote_head { /** * Callback for listing the remote heads */ -typedef int (*git_headlist_cb)(git_remote_head *, void *); +typedef int (*git_headlist_cb)(git_remote_head *rhead, void *payload); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/notes.h b/git2/include/git2/notes.h index af480a408..ddd54b039 100644 --- a/git2/include/git2/notes.h +++ b/git2/include/git2/notes.h @@ -18,21 +18,35 @@ */ GIT_BEGIN_DECL +/** + * Callback for git_note_foreach. + * + * Receives: + * - blob_id: Oid of the blob containing the message + * - annotated_object_id: Oid of the git object being annotated + * - payload: Payload data passed to `git_note_foreach` + */ +typedef int (*git_note_foreach_cb)( + const git_oid *blob_id, const git_oid *annotated_object_id, void *payload); + /** * Read the note for an object * * The note must be freed manually by the user. * - * @param note pointer to the read note; NULL in case of error + * @param out pointer to the read note; NULL in case of error * @param repo repository where to look up the note - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" + * @param notes_ref canonical name of the reference to use (optional); defaults to + * "refs/notes/commits" * @param oid OID of the git object to read the note from * * @return 0 or an error code */ -GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo, - const char *notes_ref, const git_oid *oid); +GIT_EXTERN(int) git_note_read( + git_note **out, + git_repository *repo, + const char *notes_ref, + const git_oid *oid); /** * Get the note message @@ -40,7 +54,7 @@ GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo, * @param note * @return the note message */ -GIT_EXTERN(const char *) git_note_message(git_note *note); +GIT_EXTERN(const char *) git_note_message(const git_note *note); /** @@ -49,7 +63,7 @@ GIT_EXTERN(const char *) git_note_message(git_note *note); * @param note * @return the note object OID */ -GIT_EXTERN(const git_oid *) git_note_oid(git_note *note); +GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note); /** * Add a note for an object @@ -62,13 +76,19 @@ GIT_EXTERN(const git_oid *) git_note_oid(git_note *note); * defaults to "refs/notes/commits" * @param oid OID of the git object to decorate * @param note Content of the note to add for object oid + * @param force Overwrite existing note * * @return 0 or an error code */ -GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo, - git_signature *author, git_signature *committer, - const char *notes_ref, const git_oid *oid, - const char *note); +GIT_EXTERN(int) git_note_create( + git_oid *out, + git_repository *repo, + const git_signature *author, + const git_signature *committer, + const char *notes_ref, + const git_oid *oid, + const char *note, + int force); /** @@ -83,9 +103,12 @@ GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo, * * @return 0 or an error code */ -GIT_EXTERN(int) git_note_remove(git_repository *repo, const char *notes_ref, - git_signature *author, git_signature *committer, - const git_oid *oid); +GIT_EXTERN(int) git_note_remove( + git_repository *repo, + const char *notes_ref, + const git_signature *author, + const git_signature *committer, + const git_oid *oid); /** * Free a git_note object @@ -104,17 +127,6 @@ GIT_EXTERN(void) git_note_free(git_note *note); */ GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo); -/** - * Basic components of a note - * - * - Oid of the blob containing the message - * - Oid of the git object being annotated - */ -typedef struct { - git_oid blob_oid; - git_oid annotated_object_oid; -} git_note_data; - /** * Loop over all the notes within a specified namespace * and issue a callback for each one. @@ -134,9 +146,8 @@ typedef struct { GIT_EXTERN(int) git_note_foreach( git_repository *repo, const char *notes_ref, - int (*note_cb)(git_note_data *note_data, void *payload), - void *payload -); + git_note_foreach_cb note_cb, + void *payload); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/object.h b/git2/include/git2/object.h index fd6ae95c1..e5ca17e16 100644 --- a/git2/include/git2/object.h +++ b/git2/include/git2/object.h @@ -179,13 +179,14 @@ GIT_EXTERN(size_t) git_object__size(git_otype type); * * @param peeled Pointer to the peeled git_object * @param object The object to be processed - * @param target_type The type of the requested object - * @return 0 or an error code + * @param target_type The type of the requested object (GIT_OBJ_COMMIT, + * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY). + * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code */ GIT_EXTERN(int) git_object_peel( - git_object **peeled, - git_object *object, - git_otype target_type); + git_object **peeled, + const git_object *object, + git_otype target_type); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/odb.h b/git2/include/git2/odb.h index c6e73571b..3854fa6f6 100644 --- a/git2/include/git2/odb.h +++ b/git2/include/git2/odb.h @@ -11,6 +11,7 @@ #include "types.h" #include "oid.h" #include "odb_backend.h" +#include "indexer.h" /** * @file git2/odb.h @@ -87,6 +88,23 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int */ GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); +/** + * Add an on-disk alternate to an existing Object DB. + * + * Note that the added path must point to an `objects`, not + * to a full repository, to use it as an alternate store. + * + * Alternate backends are always checked for objects *after* + * all the main backends have been exhausted. + * + * Writing is disabled on alternate backends. + * + * @param odb database to add the backend to + * @param path path to the objects folder for the alternate + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path); + /** * Close an open object database. * @@ -135,9 +153,10 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i * @param db database to search for the object in. * @param short_id a prefix of the id of the object to read. * @param len the length of the prefix - * @return 0 if the object was read; - * GIT_ENOTFOUND if the object is not in the database. - * GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix) + * @return + * - 0 if the object was read; + * - GIT_ENOTFOUND if the object is not in the database. + * - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix) */ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len); @@ -151,15 +170,15 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git * of an object, so the whole object will be read and then the * header will be returned. * - * @param len_p pointer where to store the length - * @param type_p pointer where to store the type + * @param len_out pointer where to store the length + * @param type_out pointer where to store the type * @param db database to search for the object in. * @param id identity of the object to read. * @return * - 0 if the object was read; * - GIT_ENOTFOUND if the object is not in the database. */ -GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id); +GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id); /** * Determine if the given object can be found in the object database. @@ -182,10 +201,10 @@ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); * * @param db database to use * @param cb the callback to call for each object - * @param data data to pass to the callback + * @param payload data to pass to the callback * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ -GIT_EXTERN(int) git_odb_foreach(git_odb *db, int (*cb)(git_oid *oid, void *data), void *data); +GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload); /** * Write an object directly into the ODB @@ -198,14 +217,14 @@ GIT_EXTERN(int) git_odb_foreach(git_odb *db, int (*cb)(git_oid *oid, void *data) * This method is provided for compatibility with custom backends * which are not able to support streaming writes * - * @param oid pointer to store the OID result of the write + * @param out pointer to store the OID result of the write * @param odb object database where to store the object * @param data buffer with the data to store * @param len size of the buffer * @param type type of the data to store * @return 0 or an error code */ -GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type); +GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type); /** * Open a stream to write an object into the ODB @@ -228,13 +247,13 @@ GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size * * @see git_odb_stream * - * @param stream pointer where to store the stream + * @param out pointer where to store the stream * @param db object database where the stream will write * @param size final size of the object that will be written * @param type type of the object that will be written * @return 0 if the stream was created; error code otherwise */ -GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type); +GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type); /** * Open a stream to read an object from the ODB @@ -255,12 +274,36 @@ GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_ * * @see git_odb_stream * - * @param stream pointer where to store the stream + * @param out pointer where to store the stream * @param db object database where the stream will read from * @param oid oid of the object the stream will read from * @return 0 if the stream was created; error code otherwise */ -GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid); +GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const git_oid *oid); + +/** + * Open a stream for writing a pack file to the ODB. + * + * If the ODB layer understands pack files, then the given + * packfile will likely be streamed directly to disk (and a + * corresponding index created). If the ODB layer does not + * understand pack files, the objects will be stored in whatever + * format the ODB layer uses. + * + * @see git_odb_writepack + * + * @param out pointer to the writepack functions + * @param db object database where the stream will read from + * @param progress_cb function to call with progress information. + * Be aware that this is called inline with network and indexing operations, + * so performance may be affected. + * @param progress_payload payload for the progress callback + */ +GIT_EXTERN(int) git_odb_write_pack( + git_odb_writepack **out, + git_odb *db, + git_transfer_progress_callback progress_cb, + void *progress_payload); /** * Determine the object-ID (sha1 hash) of a data buffer @@ -268,13 +311,13 @@ GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const * The resulting SHA-1 OID will be the identifier for the data * buffer as if the data buffer it were to written to the ODB. * - * @param id the resulting object-ID. + * @param out the resulting object-ID. * @param data data to hash * @param len size of the data * @param type of the data to hash * @return 0 or an error code */ -GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type); +GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_otype type); /** * Read a file from disk and fill a git_oid with the object id diff --git a/git2/include/git2/odb_backend.h b/git2/include/git2/odb_backend.h index cb8069787..7b5a51ed9 100644 --- a/git2/include/git2/odb_backend.h +++ b/git2/include/git2/odb_backend.h @@ -10,6 +10,7 @@ #include "common.h" #include "types.h" #include "oid.h" +#include "indexer.h" /** * @file git2/backend.h @@ -21,9 +22,18 @@ GIT_BEGIN_DECL struct git_odb_stream; +struct git_odb_writepack; -/** An instance for a custom backend */ +/** + * Function type for callbacks from git_odb_foreach. + */ +typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); + +/** + * An instance for a custom backend + */ struct git_odb_backend { + unsigned int version; git_odb *odb; /* read and read_prefix each return to libgit2 a buffer which @@ -53,6 +63,10 @@ struct git_odb_backend { struct git_odb_backend *, const git_oid *); + /* The writer may assume that the object + * has already been hashed and is passed + * in the first parameter. + */ int (* write)( git_oid *, struct git_odb_backend *, @@ -75,15 +89,23 @@ struct git_odb_backend { struct git_odb_backend *, const git_oid *); - int (*foreach)( - struct git_odb_backend *, - int (*cb)(git_oid *oid, void *data), - void *data - ); + int (* foreach)( + struct git_odb_backend *, + git_odb_foreach_cb cb, + void *payload); + + int (* writepack)( + struct git_odb_writepack **, + struct git_odb_backend *, + git_transfer_progress_callback progress_cb, + void *progress_payload); void (* free)(struct git_odb_backend *); }; +#define GIT_ODB_BACKEND_VERSION 1 +#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} + /** Streaming mode */ enum { GIT_STREAM_RDONLY = (1 << 1), @@ -94,7 +116,7 @@ enum { /** A stream to read/write from a backend */ struct git_odb_stream { struct git_odb_backend *backend; - int mode; + unsigned int mode; int (*read)(struct git_odb_stream *stream, char *buffer, size_t len); int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len); @@ -102,12 +124,24 @@ struct git_odb_stream { void (*free)(struct git_odb_stream *stream); }; -GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir); -GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync); -GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **backend_out, const char *index_file); +/** A stream to write a pack file to the ODB */ +struct git_odb_writepack { + struct git_odb_backend *backend; + + int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats); + int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats); + void (*free)(struct git_odb_writepack *writepack); +}; GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); +/** + * Constructors for in-box ODB backends. + */ +GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); +GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync); +GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); + GIT_END_DECL #endif diff --git a/git2/include/git2/oid.h b/git2/include/git2/oid.h index 9e54a9f96..43717ad70 100644 --- a/git2/include/git2/oid.h +++ b/git2/include/git2/oid.h @@ -30,11 +30,10 @@ GIT_BEGIN_DECL #define GIT_OID_MINPREFIXLEN 4 /** Unique identity of any object (commit, tree, blob, tag). */ -typedef struct _git_oid git_oid; -struct _git_oid { +typedef struct git_oid { /** raw binary formatted id */ unsigned char id[GIT_OID_RAWSZ]; -}; +} git_oid; /** * Parse a hex formatted object id into a git_oid. @@ -71,14 +70,14 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw); /** * Format a git_oid into a hex string. * - * @param str output hex string; must be pointing at the start of + * @param out output hex string; must be pointing at the start of * the hex sequence and have at least the number of bytes * needed for an oid encoded in hex (40 bytes). Only the * oid digits are written; a '\\0' terminator must be added * by the caller if it is required. * @param oid oid structure to format. */ -GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid); +GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id); /** * Format a git_oid into a loose-object path string. @@ -86,14 +85,14 @@ GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid); * The resulting string is "aa/...", where "aa" is the first two * hex digits of the oid and "..." is the remaining 38 digits. * - * @param str output hex string; must be pointing at the start of + * @param out output hex string; must be pointing at the start of * the hex sequence and have at least the number of bytes * needed for an oid encoded in hex (41 bytes). Only the * oid digits are written; a '\\0' terminator must be added * by the caller if it is required. - * @param oid oid structure to format. + * @param id oid structure to format. */ -GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid); +GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id); /** * Format a git_oid into a newly allocated c-string. @@ -102,7 +101,7 @@ GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid); * @return the c-string; NULL if memory is exhausted. Caller must * deallocate the string with git__free(). */ -GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid); +GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id); /** * Format a git_oid into a buffer as a hex format c-string. @@ -115,11 +114,11 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid); * * @param out the buffer into which the oid string is output. * @param n the size of the out buffer. - * @param oid the oid structure to format. + * @param id the oid structure to format. * @return the out buffer pointer, assuming no input parameter * errors, otherwise a pointer to an empty string. */ -GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *oid); +GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id); /** * Copy an oid from one structure to another. @@ -176,19 +175,19 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len); /** * Check if an oid equals an hex formatted object id. * - * @param a oid structure. + * @param id oid structure. * @param str input hex string of an object id. * @return GIT_ENOTOID if str is not a valid hex string, * 0 in case of a match, GIT_ERROR otherwise. */ -GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str); +GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str); /** * Check is an oid is all zeros. * * @return 1 if all zeros, 0 otherwise. */ -GIT_EXTERN(int) git_oid_iszero(const git_oid *a); +GIT_EXTERN(int) git_oid_iszero(const git_oid *id); /** * OID Shortener object @@ -230,12 +229,12 @@ GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length); * GIT_ENOMEM error * * @param os a `git_oid_shorten` instance - * @param text_oid an OID in text form + * @param text_id an OID in text form * @return the minimal length to uniquely identify all OIDs * added so far to the set; or an error code (<0) if an * error occurs. */ -GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_oid); +GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id); /** * Free an OID shortener instance diff --git a/git2/include/git2/pack.h b/git2/include/git2/pack.h index 748ad2e11..585cffef6 100644 --- a/git2/include/git2/pack.h +++ b/git2/include/git2/pack.h @@ -38,8 +38,9 @@ GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo) * * @param pb The packbuilder * @param n Number of threads to spawn + * @return number of actual threads to be used */ -GIT_EXTERN(void) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n); +GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n); /** * Insert a single object @@ -48,12 +49,12 @@ GIT_EXTERN(void) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n * commits followed by trees and blobs. * * @param pb The packbuilder - * @param oid The oid of the commit - * @param oid The name; might be NULL + * @param id The oid of the commit + * @param name The name; might be NULL * * @return 0 or an error code */ -GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, const char *name); +GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name); /** * Insert a root tree object @@ -61,11 +62,11 @@ GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, * This will add the tree as well as all referenced trees and blobs. * * @param pb The packbuilder - * @param oid The oid of the root tree + * @param id The oid of the root tree * * @return 0 or an error code */ -GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *oid); +GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id); /** * Write the new pack and the corresponding index to path @@ -77,6 +78,33 @@ GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid * */ GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file); +/** + * Create the new pack and pass each object to the callback + * + * @param pb the packbuilder + * @param cb the callback to call with each packed object's buffer + * @param payload the callback's data + * @return 0 or an error code + */ +typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload); +GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload); + +/** + * Get the total number of objects the packbuilder will write out + * + * @param pb the packbuilder + * @return + */ +GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb); + +/** + * Get the number of objects the packbuilder has already written out + * + * @param pb the packbuilder + * @return + */ +GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb); + /** * Free the packbuilder and all associated data * diff --git a/git2/include/git2/push.h b/git2/include/git2/push.h new file mode 100644 index 000000000..900a1833e --- /dev/null +++ b/git2/include/git2/push.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_push_h__ +#define INCLUDE_git_push_h__ + +#include "common.h" + +/** + * @file git2/push.h + * @brief Git push management functions + * @defgroup git_push push management functions + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a new push object + * + * @param out New push object + * @param remote Remote instance + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote); + +/** + * Add a refspec to be pushed + * + * @param push The push object + * @param refspec Refspec string + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_push_add_refspec(git_push *push, const char *refspec); + +/** + * Actually push all given refspecs + * + * @param push The push object + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_push_finish(git_push *push); + +/** + * Check if remote side successfully unpacked + * + * @param push The push object + * + * @return true if equal, false otherwise + */ +GIT_EXTERN(int) git_push_unpack_ok(git_push *push); + +/** + * Call callback `cb' on each status + * + * @param push The push object + * @param cb The callback to call on each object + * + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +GIT_EXTERN(int) git_push_status_foreach(git_push *push, + int (*cb)(const char *ref, const char *msg, void *data), + void *data); + +/** + * Free the given push object + * + * @param push The push object + */ +GIT_EXTERN(void) git_push_free(git_push *push); + +/** @} */ +GIT_END_DECL +#endif diff --git a/git2/include/git2/reflog.h b/git2/include/git2/reflog.h index 447915ef8..418826d1d 100644 --- a/git2/include/git2/reflog.h +++ b/git2/include/git2/reflog.h @@ -30,11 +30,11 @@ GIT_BEGIN_DECL * The reflog must be freed manually by using * git_reflog_free(). * - * @param reflog pointer to reflog + * @param out pointer to reflog * @param ref reference to read the reflog for * @return 0 or an error code */ -GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref); +GIT_EXTERN(int) git_reflog_read(git_reflog **out, const git_reference *ref); /** * Write an existing in-memory reflog object back to disk @@ -51,23 +51,26 @@ GIT_EXTERN(int) git_reflog_write(git_reflog *reflog); * `msg` is optional and can be NULL. * * @param reflog an existing reflog object - * @param new_oid the OID the reference is now pointing to + * @param id the OID the reference is now pointing to * @param committer the signature of the committer * @param msg the reflog message * @return 0 or an error code */ -GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg); +GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg); /** * Rename the reflog for the given reference * * The reflog to be renamed is expected to already exist * + * The new name will be checked for validity. + * See `git_reference_create_symbolic()` for rules about valid names. + * * @param ref the reference - * @param new_name the new name of the reference - * @return 0 or an error code + * @param name the new name of the reference + * @return 0 on success, GIT_EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name); +GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name); /** * Delete the reflog for the given reference @@ -83,13 +86,17 @@ GIT_EXTERN(int) git_reflog_delete(git_reference *ref); * @param reflog the previously loaded reflog * @return the number of log entries */ -GIT_EXTERN(unsigned int) git_reflog_entrycount(git_reflog *reflog); +GIT_EXTERN(size_t) git_reflog_entrycount(git_reflog *reflog); /** * Lookup an entry by its index * + * Requesting the reflog entry with an index of 0 (zero) will + * return the most recently created entry. + * * @param reflog a previously loaded reflog - * @param idx the position to lookup + * @param idx the position of the entry to lookup. Should be greater than or + * equal to 0 (zero) and less than `git_reflog_entrycount()`. * @return the entry; NULL if not found */ GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog, size_t idx); @@ -97,21 +104,23 @@ GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog /** * Remove an entry from the reflog by its index * - * To ensure there's no gap in the log history, set the `rewrite_previosu_entry` to 1. - * When deleting entry `n`, member old_oid of entry `n-1` (if any) will be updated with - * the value of memeber new_oid of entry `n+1`. + * To ensure there's no gap in the log history, set `rewrite_previous_entry` + * param value to 1. When deleting entry `n`, member old_oid of entry `n-1` + * (if any) will be updated with the value of member new_oid of entry `n+1`. * * @param reflog a previously loaded reflog. * - * @param idx the position of the entry to remove. + * @param idx the position of the entry to remove. Should be greater than or + * equal to 0 (zero) and less than `git_reflog_entrycount()`. * * @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise. * - * @return 0 on success or an error code. + * @return 0 on success, GIT_ENOTFOUND if the entry doesn't exist + * or an error code. */ GIT_EXTERN(int) git_reflog_drop( git_reflog *reflog, - unsigned int idx, + size_t idx, int rewrite_previous_entry); /** @@ -120,7 +129,7 @@ GIT_EXTERN(int) git_reflog_drop( * @param entry a reflog entry * @return the old oid */ -GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entry); +GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry); /** * Get the new oid @@ -128,7 +137,7 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entr * @param entry a reflog entry * @return the new oid at this time */ -GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entry); +GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry); /** * Get the committer of this entry @@ -136,15 +145,15 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entr * @param entry a reflog entry * @return the committer */ -GIT_EXTERN(git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry); +GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry); /** - * Get the log msg + * Get the log message * * @param entry a reflog entry * @return the log msg */ -GIT_EXTERN(char *) git_reflog_entry_msg(const git_reflog_entry *entry); +GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry); /** * Free the reflog diff --git a/git2/include/git2/refs.h b/git2/include/git2/refs.h index 001c2bcc7..cfc96a68c 100644 --- a/git2/include/git2/refs.h +++ b/git2/include/git2/refs.h @@ -22,175 +22,212 @@ GIT_BEGIN_DECL /** - * Lookup a reference by its name in a repository. + * Lookup a reference by name in a repository. * - * The generated reference must be freed by the user. + * The returned reference must be freed by the user. * - * @param reference_out pointer to the looked-up reference + * The name will be checked for validity. + * See `git_reference_create_symbolic()` for rules about valid names. + * + * @param out pointer to the looked-up reference * @param repo the repository to look up the reference - * @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...) - * @return 0 or an error code + * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...) + * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code. */ -GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name); +GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name); /** * Lookup a reference by name and resolve immediately to OID. * - * @param oid Pointer to oid to be filled in + * This function provides a quick way to resolve a reference name straight + * through to the object id that it refers to. This avoids having to + * allocate or free any `git_reference` objects for simple situations. + * + * The name will be checked for validity. + * See `git_reference_create_symbolic()` for rules about valid names. + * + * @param out Pointer to oid to be filled in * @param repo The repository in which to look up the reference * @param name The long name for the reference - * @return 0 on success, -1 if name could not be resolved + * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code. */ -GIT_EXTERN(int) git_reference_name_to_oid( +GIT_EXTERN(int) git_reference_name_to_id( git_oid *out, git_repository *repo, const char *name); /** * Create a new symbolic reference. * - * The reference will be created in the repository and written - * to the disk. + * A symbolic reference is a reference name that refers to another + * reference name. If the other name moves, the symbolic name will move, + * too. As a simple example, the "HEAD" reference might refer to + * "refs/heads/master" while on the "master" branch of a repository. * - * The generated reference must be freed by the user. + * The symbolic reference will be created in the repository and written to + * the disk. The generated reference object must be freed by the user. * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. + * Valid reference names must follow one of two patterns: * - * @param ref_out Pointer to the newly created reference + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * This function will return an error if a reference already exists with the + * given name unless `force` is true, in which case it will be overwritten. + * + * @param out Pointer to the newly created reference * @param repo Repository where that reference will live * @param name The name of the reference * @param target The target of the reference * @param force Overwrite existing references - * @return 0 or an error code + * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force); +GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force); /** - * Create a new object id reference. + * Create a new direct reference. * - * The reference will be created in the repository and written - * to the disk. + * A direct reference (also called an object id reference) refers directly + * to a specific object id (a.k.a. OID or SHA) in the repository. The id + * permanently refers to the object (although the reference itself can be + * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0" + * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977. * - * The generated reference must be freed by the user. + * The direct reference will be created in the repository and written to + * the disk. The generated reference object must be freed by the user. * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. + * Valid reference names must follow one of two patterns: * - * @param ref_out Pointer to the newly created reference + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * This function will return an error if a reference already exists with the + * given name unless `force` is true, in which case it will be overwritten. + * + * @param out Pointer to the newly created reference * @param repo Repository where that reference will live * @param name The name of the reference * @param id The object id pointed to by the reference. * @param force Overwrite existing references - * @return 0 or an error code + * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force); +GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force); /** - * Get the OID pointed to by a reference. + * Get the OID pointed to by a direct reference. * - * Only available if the reference is direct (i.e. not symbolic) + * Only available if the reference is direct (i.e. an object id reference, + * not a symbolic one). + * + * To find the OID of a symbolic ref, call `git_reference_resolve()` and + * then this function (or maybe use `git_reference_name_to_oid()` to + * directly resolve a reference name all the way through to an OID). * * @param ref The reference * @return a pointer to the oid if available, NULL otherwise */ -GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref); +GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref); /** - * Get full name to the reference pointed by this reference + * Get full name to the reference pointed to by a symbolic reference. * - * Only available if the reference is symbolic + * Only available if the reference is symbolic. * * @param ref The reference * @return a pointer to the name if available, NULL otherwise */ -GIT_EXTERN(const char *) git_reference_target(git_reference *ref); +GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref); /** - * Get the type of a reference + * Get the type of a reference. * * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC) * * @param ref The reference * @return the type */ -GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref); +GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref); /** - * Get the full name of a reference + * Get the full name of a reference. + * + * See `git_reference_create_symbolic()` for rules about valid names. * * @param ref The reference * @return the full name for the ref */ -GIT_EXTERN(const char *) git_reference_name(git_reference *ref); +GIT_EXTERN(const char *) git_reference_name(const git_reference *ref); /** - * Resolve a symbolic reference + * Resolve a symbolic reference to a direct reference. * - * This method iteratively peels a symbolic reference - * until it resolves to a direct reference to an OID. + * This method iteratively peels a symbolic reference until it resolves to + * a direct reference to an OID. * - * The peeled reference is returned in the `resolved_ref` - * argument, and must be freed manually once it's no longer - * needed. + * The peeled reference is returned in the `resolved_ref` argument, and + * must be freed manually once it's no longer needed. * - * If a direct reference is passed as an argument, - * a copy of that reference is returned. This copy must - * be manually freed too. + * If a direct reference is passed as an argument, a copy of that + * reference is returned. This copy must be manually freed too. * * @param resolved_ref Pointer to the peeled reference * @param ref The reference * @return 0 or an error code */ -GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref); +GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref); /** - * Get the repository where a reference resides + * Get the repository where a reference resides. * * @param ref The reference * @return a pointer to the repo */ -GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref); +GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref); /** * Set the symbolic target of a reference. * - * The reference must be a symbolic reference, otherwise - * this method will fail. + * The reference must be a symbolic reference, otherwise this will fail. * - * The reference will be automatically updated in - * memory and on disk. + * The reference will be automatically updated in memory and on disk. + * + * The target name will be checked for validity. + * See `git_reference_create_symbolic()` for rules about valid names. * * @param ref The reference * @param target The new target for the reference - * @return 0 or an error code + * @return 0 on success, EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target); +GIT_EXTERN(int) git_reference_symbolic_set_target(git_reference *ref, const char *target); /** * Set the OID target of a reference. * - * The reference must be a direct reference, otherwise - * this method will fail. + * The reference must be a direct reference, otherwise this will fail. * - * The reference will be automatically updated in - * memory and on disk. + * The reference will be automatically updated in memory and on disk. * * @param ref The reference * @param id The new target OID for the reference * @return 0 or an error code */ -GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); +GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const git_oid *id); /** - * Rename an existing reference + * Rename an existing reference. * * This method works for both direct and symbolic references. - * The new name will be checked for validity and may be - * modified into a normalized form. + * + * The new name will be checked for validity. + * See `git_reference_create_symbolic()` for rules about valid names. * * The given git_reference will be updated in place. * - * The reference will be immediately renamed in-memory - * and on disk. + * The reference will be immediately renamed in-memory and on disk. * * If the `force` flag is not enabled, and there's already * a reference with the given name, the renaming will fail. @@ -201,20 +238,20 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); * the reflog if it exists. * * @param ref The reference to rename - * @param new_name The new name for the reference + * @param name The new name for the reference * @param force Overwrite an existing reference - * @return 0 or an error code + * @return 0 on success, EINVALIDSPEC, EEXISTS or an error code * */ -GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force); +GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *name, int force); /** - * Delete an existing reference + * Delete an existing reference. * * This method works for both direct and symbolic references. * - * The reference will be immediately removed on disk and from - * memory. The given reference pointer will no longer be valid. + * The reference will be immediately removed on disk and from memory + * (i.e. freed). The given reference pointer will no longer be valid. * * @param ref The reference to remove * @return 0 or an error code @@ -222,7 +259,7 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i GIT_EXTERN(int) git_reference_delete(git_reference *ref); /** - * Pack all the loose references in the repository + * Pack all the loose references in the repository. * * This method will load into the cache all the loose * references on the repository and update the @@ -237,52 +274,56 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref); GIT_EXTERN(int) git_reference_packall(git_repository *repo); /** - * Fill a list with all the references that can be found - * in a repository. + * Fill a list with all the references that can be found in a repository. * - * The listed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * Using the `list_flags` parameter, the listed references may be filtered + * by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of + * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. + * For convenience, use the value `GIT_REF_LISTALL` to obtain all + * references, including packed ones. * - * The string array will be filled with the names of all - * references; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. + * The string array will be filled with the names of all references; these + * values are owned by the user and should be free'd manually when no + * longer needed, using `git_strarray_free()`. * * @param array Pointer to a git_strarray structure where * the reference names will be stored * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. + * @param list_flags Filtering flags for the reference listing * @return 0 or an error code */ GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags); +typedef int (*git_reference_foreach_cb)(const char *refname, void *payload); + /** - * Perform an operation on each reference in the repository + * Perform a callback on each reference in the repository. * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * Using the `list_flags` parameter, the references may be filtered by + * type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of + * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. + * For convenience, use the value `GIT_REF_LISTALL` to obtain all + * references, including packed ones. * - * The `callback` function will be called for each of the references - * in the repository, and will receive the name of the reference and - * the `payload` value passed to this method. Returning a non-zero - * value from the callback will terminate the iteration. + * The `callback` function will be called for each reference in the + * repository, receiving the name of the reference and the `payload` value + * passed to this method. Returning a non-zero value from the callback + * will terminate the iteration. * * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. + * @param list_flags Filtering flags for the reference listing. * @param callback Function which will be called for every listed ref * @param payload Additional data to pass to the callback * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ -GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload); +GIT_EXTERN(int) git_reference_foreach( + git_repository *repo, + unsigned int list_flags, + git_reference_foreach_cb callback, + void *payload); /** - * Check if a reference has been loaded from a packfile + * Check if a reference has been loaded from a packfile. * * @param ref A git reference * @return 0 in case it's not packed; 1 otherwise @@ -290,19 +331,17 @@ GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_fl GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); /** - * Reload a reference from disk + * Reload a reference from disk. * - * Reference pointers may become outdated if the Git - * repository is accessed simultaneously by other clients - * while the library is open. + * Reference pointers can become outdated if the Git repository is + * accessed simultaneously by other clients while the library is open. * - * This method forces a reload of the reference from disk, - * to ensure that the provided information is still - * reliable. + * This method forces a reload of the reference from disk, to ensure that + * the provided information is still reliable. * - * If the reload fails (e.g. the reference no longer exists - * on disk, or has become corrupted), an error code will be - * returned and the reference pointer will be invalidated. + * If the reload fails (e.g. the reference no longer exists on disk, or + * has become corrupted), an error code will be returned and the reference + * pointer will be invalidated and freed. * * @param ref The reference to reload * @return 0 on success, or an error code @@ -310,7 +349,7 @@ GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); GIT_EXTERN(int) git_reference_reload(git_reference *ref); /** - * Free the given reference + * Free the given reference. * * @param ref git_reference */ @@ -326,36 +365,30 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref); GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); /** - * Loop over all the references and issue a callback for each one - * which name matches the given glob pattern. + * Perform a callback on each reference in the repository whose name + * matches the given pattern. * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * This function acts like `git_reference_foreach()` with an additional + * pattern match being applied to the reference name before issuing the + * callback function. See that function for more information. * - * @param repo Repository where to find the references. + * The pattern is matched using fnmatch or "glob" style where a '*' matches + * any sequence of letters, a '?' matches any letter, and square brackets + * can be used to define character ranges (such as "[0-9]" for digits). * - * @param glob Glob pattern references should match. - * - * @param list_flags Filtering flags for the reference - * listing. - * - * @param callback Callback to invoke per found reference. - * - * @param payload Extra parameter to callback function. - * - * @return 0 or an error code. + * @param repo Repository where to find the refs + * @param glob Pattern to match (fnmatch-style) against reference name. + * @param list_flags Filtering flags for the reference listing. + * @param callback Function which will be called for every listed ref + * @param payload Additional data to pass to the callback + * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_reference_foreach_glob( - git_repository *repo, - const char *glob, - unsigned int list_flags, - int (*callback)( - const char *reference_name, - void *payload), - void *payload -); + git_repository *repo, + const char *glob, + unsigned int list_flags, + git_reference_foreach_cb callback, + void *payload); /** * Check if a reflog exists for the specified reference. @@ -387,7 +420,8 @@ GIT_EXTERN(int) git_reference_is_branch(git_reference *ref); */ GIT_EXTERN(int) git_reference_is_remote(git_reference *ref); -enum { + +typedef enum { GIT_REF_FORMAT_NORMAL = 0, /** @@ -406,27 +440,27 @@ enum { * (e.g., foo//bar but not foo/bar). */ GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1), -}; +} git_reference_normalize_t; /** - * Normalize the reference name by removing any leading - * slash (/) characters and collapsing runs of adjacent slashes - * between name components into a single slash. + * Normalize reference name and check validity. * - * Once normalized, if the reference name is valid, it will be - * returned in the user allocated buffer. + * This will normalize the reference name by removing any leading slash + * '/' characters and collapsing runs of adjacent slashes between name + * components into a single slash. * - * @param buffer_out The user allocated buffer where the - * normalized name will be stored. + * Once normalized, if the reference name is valid, it will be returned in + * the user allocated buffer. * - * @param buffer_size buffer_out size + * See `git_reference_create_symbolic()` for rules about valid names. * - * @param name name to be checked. - * - * @param flags Flags to determine the options to be applied while - * checking the validatity of the name. - * - * @return 0 or an error code. + * @param buffer_out User allocated buffer to store normalized name + * @param buffer_size Size of buffer_out + * @param name Reference name to be checked. + * @param flags Flags to constrain name validation rules - see the + * GIT_REF_FORMAT constants above. + * @return 0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC + * or an error code. */ GIT_EXTERN(int) git_reference_normalize_name( char *buffer_out, @@ -435,8 +469,7 @@ GIT_EXTERN(int) git_reference_normalize_name( unsigned int flags); /** - * Recursively peel an reference until an object of the - * specified type is met. + * Recursively peel reference until object of the specified type is found. * * The retrieved `peeled` object is owned by the repository * and should be closed with the `git_object_free` method. @@ -446,8 +479,9 @@ GIT_EXTERN(int) git_reference_normalize_name( * * @param peeled Pointer to the peeled git_object * @param ref The reference to be processed - * @param target_type The type of the requested object - * @return 0 or an error code + * @param target_type The type of the requested object (GIT_OBJ_COMMIT, + * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY). + * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code */ GIT_EXTERN(int) git_reference_peel( git_object **out, @@ -457,12 +491,18 @@ GIT_EXTERN(int) git_reference_peel( /** * Ensure the reference name is well-formed. * - * @param refname name to be checked. + * Valid reference names must follow one of two patterns: * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * @param refname name to be checked. * @return 1 if the reference name is acceptable; 0 if it isn't */ -GIT_EXTERN(int) git_reference_is_valid_name( - const char *refname); +GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/remote.h b/git2/include/git2/remote.h index ad5c38902..5f6a78097 100644 --- a/git2/include/git2/remote.h +++ b/git2/include/git2/remote.h @@ -13,6 +13,7 @@ #include "net.h" #include "indexer.h" #include "strarray.h" +#include "transport.h" /** * @file git2/remote.h @@ -23,6 +24,7 @@ */ GIT_BEGIN_DECL +typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); /* * TODO: This functions still need to be implemented: * - _listcb/_foreach @@ -31,36 +33,75 @@ GIT_BEGIN_DECL * - _del (needs support from config) */ +/** + * Add a remote with the default fetch refspec to the repository's configuration. This + * calls git_remote_save before returning. + * + * @param out the resulting remote + * @param repo the repository in which to create the remote + * @param name the remote's name + * @param url the remote's url + * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code + */ +GIT_EXTERN(int) git_remote_create( + git_remote **out, + git_repository *repo, + const char *name, + const char *url); + /** * Create a remote in memory * - * Create a remote with the default refspecs in memory. You can use - * this when you have a URL instead of a remote's name. + * Create a remote with the given refspec in memory. You can use + * this when you have a URL instead of a remote's name. Note that in-memory + * remotes cannot be converted to persisted remotes. + * + * The name, when provided, will be checked for validity. + * See `git_tag_create()` for rules about valid names. * * @param out pointer to the new remote object - * @param repo the associated repository - * @param name the remote's name + * @param repo the associated repository. May be NULL for a "dangling" remote. + * @param fetch the fetch refspec to use for this remote. May be NULL for defaults. * @param url the remote repository's URL - * @param fetch the fetch refspec to use for this remote * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch); +GIT_EXTERN(int) git_remote_create_inmemory( + git_remote **out, + git_repository *repo, + const char *fetch, + const char *url); + +/** + * Sets the owning repository for the remote. This is only allowed on + * dangling remotes. + * + * @param remote the remote to configure + * @param repo the repository that will own the remote + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_set_repository(git_remote *remote, git_repository *repo); /** * Get the information for a particular remote * + * The name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * * @param out pointer to the new remote object - * @param cfg the repository's configuration + * @param repo the associated repository * @param name the remote's name - * @return 0 or an error code + * @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code */ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name); /** * Save a remote to its repository's configuration * + * One can't save a in-memory remote. Doing so will + * result in a GIT_EINVALIDSPEC being returned. + * * @param remote the remote to save to config - * @return 0 or an error code + * @return 0, GIT_EINVALIDSPEC or an error code */ GIT_EXTERN(int) git_remote_save(const git_remote *remote); @@ -68,9 +109,9 @@ GIT_EXTERN(int) git_remote_save(const git_remote *remote); * Get the remote's name * * @param remote the remote - * @return a pointer to the name + * @return a pointer to the name or NULL for in-memory remotes */ -GIT_EXTERN(const char *) git_remote_name(git_remote *remote); +GIT_EXTERN(const char *) git_remote_name(const git_remote *remote); /** * Get the remote's url @@ -78,7 +119,7 @@ GIT_EXTERN(const char *) git_remote_name(git_remote *remote); * @param remote the remote * @return a pointer to the url */ -GIT_EXTERN(const char *) git_remote_url(git_remote *remote); +GIT_EXTERN(const char *) git_remote_url(const git_remote *remote); /** * Get the remote's url for pushing @@ -86,7 +127,7 @@ GIT_EXTERN(const char *) git_remote_url(git_remote *remote); * @param remote the remote * @return a pointer to the url or NULL if no special url for pushing is set */ -GIT_EXTERN(const char *) git_remote_pushurl(git_remote *remote); +GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote); /** * Set the remote's url @@ -125,7 +166,7 @@ GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec); * @param remote the remote * @return a pointer to the fetch refspec or NULL if it doesn't exist */ -GIT_EXTERN(const git_refspec *) git_remote_fetchspec(git_remote *remote); +GIT_EXTERN(const git_refspec *) git_remote_fetchspec(const git_remote *remote); /** * Set the remote's push refspec @@ -143,7 +184,7 @@ GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec); * @return a pointer to the push refspec or NULL if it doesn't exist */ -GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote); +GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote); /** * Open a connection to a remote @@ -156,7 +197,7 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote); * @param direction whether you want to receive or send data * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction); +GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction); /** * Get a list of refs at the remote @@ -167,8 +208,9 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction); * If you a return a non-zero value from the callback, this will stop * looping over the refs. * - * @param refs where to store the refs * @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 */ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload); @@ -192,7 +234,7 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void GIT_EXTERN(int) git_remote_download( git_remote *remote, git_transfer_progress_callback progress_cb, - void *progress_payload); + void *payload); /** * Check whether the remote is connected @@ -200,6 +242,7 @@ GIT_EXTERN(int) git_remote_download( * Check whether the remote's underlying transport is connected to the * remote host. * + * @param remote the remote * @return 1 if it's connected, 0 otherwise. */ GIT_EXTERN(int) git_remote_connected(git_remote *remote); @@ -209,6 +252,8 @@ GIT_EXTERN(int) git_remote_connected(git_remote *remote); * * At certain points in its operation, the network code checks whether * the operation has been cancelled and if so stops the operation. + * + * @param remote the remote */ GIT_EXTERN(void) git_remote_stop(git_remote *remote); @@ -236,7 +281,7 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote); * Update the tips to the new state * * @param remote the remote to update - * @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value + * @return 0 or an error code */ GIT_EXTERN(int) git_remote_update_tips(git_remote *remote); @@ -261,21 +306,11 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url); * * The string array must be freed by the user. * - * @param remotes_list a string array with the names of the remotes + * @param out a string array which receives the names of the remotes * @param repo the repository to query * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo); - -/** - * Add a remote with the default fetch refspec to the repository's configuration - * - * @param out the resulting remote - * @param repo the repository in which to create the remote - * @param name the remote's name - * @param url the remote's url - */ -GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url); +GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo); /** * Choose whether to check the server's certificate (applies to HTTPS only) @@ -283,9 +318,39 @@ GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const cha * @param remote the remote to configure * @param check whether to check the server's certificate (defaults to yes) */ - GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); +/** + * Set a credentials acquisition callback for this remote. If the remote is + * not available for anonymous access, then you must set this callback in order + * to provide credentials to the transport at the time of authentication + * failure so that retry can be performed. + * + * @param remote the remote to configure + * @param cred_acquire_cb The credentials acquisition callback to use (defaults + * to NULL) + */ +GIT_EXTERN(void) git_remote_set_cred_acquire_cb( + git_remote *remote, + git_cred_acquire_cb cred_acquire_cb, + void *payload); + +/** + * Sets a custom transport for the remote. The caller can use this function + * to bypass the automatic discovery of a transport by URL scheme (i.e. + * http://, https://, git://) and supply their own transport to be used + * instead. After providing the transport to a remote using this function, + * the transport object belongs exclusively to that remote, and the remote will + * free it when it is freed with git_remote_free. + * + * @param remote the remote to configure + * @param transport the transport object for the remote to use + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_set_transport( + git_remote *remote, + git_transport *transport); + /** * Argument to the completion callback which tells it which operation * finished. @@ -302,12 +367,16 @@ typedef enum git_remote_completion_type { * Set the calbacks to be called by the remote. */ struct git_remote_callbacks { + unsigned int version; void (*progress)(const char *str, int len, void *data); int (*completion)(git_remote_completion_type type, void *data); int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data); - void *data; + void *payload; }; +#define GIT_REMOTE_CALLBACKS_VERSION 1 +#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION} + /** * Set the callbacks for a remote * @@ -316,20 +385,21 @@ struct git_remote_callbacks { * * @param remote the remote to configure * @param callbacks a pointer to the user's callback settings + * @return 0 or an error code */ -GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); +GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); /** * Get the statistics structure that is filled in by the fetch operation. */ GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote); -enum { +typedef enum { GIT_REMOTE_DOWNLOAD_TAGS_UNSET, GIT_REMOTE_DOWNLOAD_TAGS_NONE, GIT_REMOTE_DOWNLOAD_TAGS_AUTO, GIT_REMOTE_DOWNLOAD_TAGS_ALL -}; +} git_remote_autotag_option_t; /** * Retrieve the tag auto-follow setting @@ -337,7 +407,7 @@ enum { * @param remote the remote to query * @return the auto-follow setting */ -GIT_EXTERN(int) git_remote_autotag(git_remote *remote); +GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(git_remote *remote); /** * Set the tag auto-follow setting @@ -345,7 +415,9 @@ GIT_EXTERN(int) git_remote_autotag(git_remote *remote); * @param remote the remote to configure * @param value a GIT_REMOTE_DOWNLOAD_TAGS value */ -GIT_EXTERN(void) git_remote_set_autotag(git_remote *remote, int value); +GIT_EXTERN(void) git_remote_set_autotag( + git_remote *remote, + git_remote_autotag_option_t value); /** * Give the remote a new name @@ -353,19 +425,41 @@ GIT_EXTERN(void) git_remote_set_autotag(git_remote *remote, int value); * All remote-tracking branches and configuration settings * for the remote are updated. * + * The new name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * + * A temporary in-memory remote cannot be given a name with this method. + * * @param remote the remote to rename * @param new_name the new name the remote should bear * @param callback Optional callback to notify the consumer of fetch refspecs * that haven't been automatically updated and need potential manual tweaking. * @param payload Additional data to pass to the callback - * @return 0 or an error code + * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code */ GIT_EXTERN(int) git_remote_rename( git_remote *remote, const char *new_name, - int (*callback)(const char *problematic_refspec, void *payload), + git_remote_rename_problem_cb callback, void *payload); +/** + * Retrieve the update FETCH_HEAD setting. + * + * @param remote the remote to query + * @return the update FETCH_HEAD setting + */ +GIT_EXTERN(int) git_remote_update_fetchhead(git_remote *remote); + +/** + * Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be + * updated on every fetch. Set to 0 to disable. + * + * @param remote the remote to configure + * @param value 0 to disable updating FETCH_HEAD + */ +GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value); + /** @} */ GIT_END_DECL #endif diff --git a/git2/include/git2/repository.h b/git2/include/git2/repository.h index d72431538..1371d5409 100644 --- a/git2/include/git2/repository.h +++ b/git2/include/git2/repository.h @@ -29,11 +29,11 @@ GIT_BEGIN_DECL * The method will automatically detect if 'path' is a normal * or bare repository or fail is 'path' is neither. * - * @param repository pointer to the repo which will be opened + * @param out pointer to the repo which will be opened * @param path the path to the repository * @return 0 or an error code */ -GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path); +GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path); /** * Create a "fake" repository to wrap an object database @@ -42,11 +42,11 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat * with the API when all you have is an object database. This doesn't * have any paths associated with it, so use with care. * - * @param repository pointer to the repo + * @param out pointer to the repo * @param odb the object database to wrap * @return 0 or an error code */ -GIT_EXTERN(int) git_repository_wrap_odb(git_repository **repository, git_odb *odb); +GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb); /** * Look for a git repository and copy its path in the given buffer. @@ -58,10 +58,10 @@ GIT_EXTERN(int) git_repository_wrap_odb(git_repository **repository, git_odb *od * The method will automatically detect if the repository is bare * (if there is a repository). * - * @param repository_path The user allocated buffer which will + * @param path_out The user allocated buffer which will * contain the found path. * - * @param size repository_path size + * @param path_size repository_path size * * @param start_path The base path where the lookup starts. * @@ -77,8 +77,8 @@ GIT_EXTERN(int) git_repository_wrap_odb(git_repository **repository, git_odb *od * @return 0 or an error code */ GIT_EXTERN(int) git_repository_discover( - char *repository_path, - size_t size, + char *path_out, + size_t path_size, const char *start_path, int across_fs, const char *ceiling_dirs); @@ -95,18 +95,18 @@ GIT_EXTERN(int) git_repository_discover( * directory "/home/user/source/" will not return "/.git/" as the found * repo if "/" is a different filesystem than "/home".) */ -enum { +typedef enum { GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0), GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1), -}; +} git_repository_open_flag_t; /** * Find and open a repository with extended controls. * - * @param repo_out Pointer to the repo which will be opened. This can + * @param out Pointer to the repo which will be opened. This can * actually be NULL if you only want to use the error code to * see if a repo at this path could be opened. - * @param start_path Path to open as git repository. If the flags + * @param path Path to open as git repository. If the flags * permit "searching", then this can be a path to a subdirectory * inside the working directory of the repository. * @param flags A combination of the GIT_REPOSITORY_OPEN flags above. @@ -118,9 +118,9 @@ enum { * (such as repo corruption or system errors). */ GIT_EXTERN(int) git_repository_open_ext( - git_repository **repo, - const char *start_path, - uint32_t flags, + git_repository **out, + const char *path, + unsigned int flags, const char *ceiling_dirs); /** @@ -142,7 +142,7 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo); * TODO: * - Reinit the repository * - * @param repo_out pointer to the repo which will be created or reinitialized + * @param out pointer to the repo which will be created or reinitialized * @param path the path to the repository * @param is_bare if true, a Git repository without a working directory is * created at the pointed path. If false, provided path will be @@ -152,7 +152,7 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo); * @return 0 or an error code */ GIT_EXTERN(int) git_repository_init( - git_repository **repo_out, + git_repository **out, const char *path, unsigned is_bare); @@ -182,14 +182,14 @@ GIT_EXTERN(int) git_repository_init( * `init.templatedir` global config if not, or falling back on * "/usr/share/git-core/templates" if it exists. */ -enum { +typedef enum { GIT_REPOSITORY_INIT_BARE = (1u << 0), GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1), GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2), GIT_REPOSITORY_INIT_MKDIR = (1u << 3), GIT_REPOSITORY_INIT_MKPATH = (1u << 4), GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5), -}; +} git_repository_init_flag_t; /** * Mode options for `git_repository_init_ext`. @@ -204,11 +204,11 @@ enum { * * SHARED_ALL - Use "--shared=all" behavior, adding world readability. * * Anything else - Set to custom value. */ -enum { +typedef enum { GIT_REPOSITORY_INIT_SHARED_UMASK = 0, GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775, GIT_REPOSITORY_INIT_SHARED_ALL = 0002777, -}; +} git_repository_init_mode_t; /** * Extended options structure for `git_repository_init_ext`. @@ -239,6 +239,7 @@ enum { * will be added pointing to this URL. */ typedef struct { + unsigned int version; uint32_t flags; uint32_t mode; const char *workdir_path; @@ -248,6 +249,9 @@ typedef struct { const char *origin_url; } git_repository_init_options; +#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1 +#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION} + /** * Create a new Git repository in the given folder with extended controls. * @@ -256,26 +260,30 @@ typedef struct { * auto-detect the case sensitivity of the file system and if the * file system supports file mode bits correctly. * - * @param repo_out Pointer to the repo which will be created or reinitialized. + * @param out Pointer to the repo which will be created or reinitialized. * @param repo_path The path to the repository. * @param opts Pointer to git_repository_init_options struct. * @return 0 or an error code on failure. */ GIT_EXTERN(int) git_repository_init_ext( - git_repository **repo_out, + git_repository **out, const char *repo_path, git_repository_init_options *opts); /** * Retrieve and resolve the reference pointed at by HEAD. * - * @param head_out pointer to the reference which will be retrieved + * The returned `git_reference` will be owned by caller and + * `git_reference_free()` must be called when done with it to release the + * allocated memory and prevent a leak. + * + * @param out pointer to the reference which will be retrieved * @param repo a repository object * * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing - * branch, an error code otherwise + * branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise */ -GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *repo); +GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo); /** * Check if a repository's HEAD is detached @@ -305,7 +313,7 @@ GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo); * Check if a repository is empty * * An empty repository has just been initialized and contains - * no commits. + * no references. * * @param repo Repo to test * @return 1 if the repository is empty, 0 if it isn't, error code @@ -468,12 +476,12 @@ GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index * Use this function to get the contents of this file. Don't forget to * remove the file after you create the commit. * - * @param buffer Buffer to write data into or NULL to just read required size + * @param out Buffer to write data into or NULL to just read required size * @param len Length of buffer in bytes * @param repo Repository to read prepared message from * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error */ -GIT_EXTERN(int) git_repository_message(char *buffer, size_t len, git_repository *repo); +GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo); /** * Remove git's prepared message. @@ -482,6 +490,49 @@ GIT_EXTERN(int) git_repository_message(char *buffer, size_t len, git_repository */ GIT_EXTERN(int) git_repository_message_remove(git_repository *repo); +/** + * Remove all the metadata associated with an ongoing git merge, including + * MERGE_HEAD, MERGE_MSG, etc. + * + * @param repo A repository object + * @return 0 on success, or error + */ +GIT_EXTERN(int) git_repository_merge_cleanup(git_repository *repo); + +typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name, + const char *remote_url, + const git_oid *oid, + unsigned int is_merge, + void *payload); + +/** + * Call callback 'callback' for each entry in the given FETCH_HEAD file. + * + * @param repo A repository object + * @param callback Callback function + * @param payload Pointer to callback data (optional) + * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error + */ +GIT_EXTERN(int) git_repository_fetchhead_foreach(git_repository *repo, + git_repository_fetchhead_foreach_cb callback, + void *payload); + +typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid, + void *payload); + +/** + * If a merge is in progress, call callback 'cb' for each commit ID in the + * MERGE_HEAD file. + * + * @param repo A repository object + * @param callback Callback function + * @param apyload Pointer to callback data (optional) + * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error + */ +GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo, + git_repository_mergehead_foreach_cb callback, + void *payload); + /** * Calculate hash of file using repository filtering rules. * @@ -574,6 +625,12 @@ typedef enum { GIT_REPOSITORY_STATE_MERGE, GIT_REPOSITORY_STATE_REVERT, GIT_REPOSITORY_STATE_CHERRY_PICK, + GIT_REPOSITORY_STATE_BISECT, + GIT_REPOSITORY_STATE_REBASE, + GIT_REPOSITORY_STATE_REBASE_INTERACTIVE, + GIT_REPOSITORY_STATE_REBASE_MERGE, + GIT_REPOSITORY_STATE_APPLY_MAILBOX, + GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE, } git_repository_state_t; /** diff --git a/git2/include/git2/reset.h b/git2/include/git2/reset.h index cdcfb7671..b5fc4a6cb 100644 --- a/git2/include/git2/reset.h +++ b/git2/include/git2/reset.h @@ -15,17 +15,27 @@ */ GIT_BEGIN_DECL +/** + * Kinds of reset operation + */ +typedef enum { + GIT_RESET_SOFT = 1, /** Move the head to the given commit */ + GIT_RESET_MIXED = 2, /** SOFT plus reset index to the commit */ + GIT_RESET_HARD = 3, /** MIXED plus changes in working tree discarded */ +} git_reset_t; + /** * Sets the current head to the specified commit oid and optionally * resets the index and working tree to match. * - * When specifying a Soft kind of reset, the head will be moved to the commit. + * SOFT reset means the head will be moved to the commit. * - * Specifying a Mixed kind of reset will trigger a Soft reset and the index will - * be replaced with the content of the commit tree. + * MIXED reset will trigger a SOFT reset, plus the index will be replaced + * with the content of the commit tree. * - * Specifying a Hard kind of reset will trigger a Mixed reset and the working - * directory will be replaced with the content of the index. + * HARD reset will trigger a MIXED reset and the working directory will be + * replaced with the content of the index. (Untracked and ignored files + * will be left alone, however.) * * TODO: Implement remaining kinds of resets. * @@ -38,9 +48,10 @@ GIT_BEGIN_DECL * * @param reset_type Kind of reset operation to perform. * - * @return GIT_SUCCESS or an error code + * @return 0 on success or an error code < 0 */ -GIT_EXTERN(int) git_reset(git_repository *repo, git_object *target, git_reset_type reset_type); +GIT_EXTERN(int) git_reset( + git_repository *repo, git_object *target, git_reset_t reset_type); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/revparse.h b/git2/include/git2/revparse.h index 4567027e5..3df6fef7f 100644 --- a/git2/include/git2/revparse.h +++ b/git2/include/git2/revparse.h @@ -27,7 +27,8 @@ GIT_BEGIN_DECL * @param out pointer to output object * @param repo the repository to search in * @param spec the textual specification for an object - * @return on success, GIT_ERROR otherwise (use git_error_last for information about the error) + * @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); diff --git a/git2/include/git2/revwalk.h b/git2/include/git2/revwalk.h index 0a85a4c60..893ad2c9d 100644 --- a/git2/include/git2/revwalk.h +++ b/git2/include/git2/revwalk.h @@ -63,11 +63,11 @@ GIT_BEGIN_DECL * it is possible to have several revision walkers in * several different threads walking the same repository. * - * @param walker pointer to the new revision walker + * @param out pointer to the new revision walker * @param repo the repo to walk through * @return 0 or an error code */ -GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo); +GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo); /** * Reset the revision walker for reuse. @@ -96,10 +96,10 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker); * be started. * * @param walk the walker being used for the traversal. - * @param oid the oid of the commit to start from. + * @param id the oid of the commit to start from. * @return 0 or an error code */ -GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid); +GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id); /** * Push matching references @@ -134,10 +134,10 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk); * output on the revision walk. * * @param walk the walker being used for the traversal. - * @param oid the oid of commit that will be ignored during the traversal + * @param commit_id the oid of commit that will be ignored during the traversal * @return 0 or an error code */ -GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid); +GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id); /** * Hide matching references. @@ -198,12 +198,12 @@ GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname); * * The revision walker is reset when the walk is over. * - * @param oid Pointer where to store the oid of the next commit + * @param out Pointer where to store the oid of the next commit * @param walk the walker to pop the commit from. * @return 0 if the next commit was found; * GIT_ITEROVER if there are no commits left to iterate */ -GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk); +GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk); /** * Change the sorting mode when iterating through the diff --git a/git2/include/git2/signature.h b/git2/include/git2/signature.h index cdbe67879..7a265bd8e 100644 --- a/git2/include/git2/signature.h +++ b/git2/include/git2/signature.h @@ -20,44 +20,52 @@ GIT_BEGIN_DECL /** - * Create a new action signature. The signature must be freed - * manually or using git_signature_free + * Create a new action signature. + * + * Call `git_signature_free()` to free the data. * * Note: angle brackets ('<' and '>') characters are not allowed * to be used in either the `name` or the `email` parameter. * - * @param sig_out new signature, in case of error NULL + * @param out new signature, in case of error NULL * @param name name of the person * @param email email of the person * @param time time when the action happened * @param offset timezone offset in minutes for the time * @return 0 or an error code */ -GIT_EXTERN(int) git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset); +GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const char *email, git_time_t time, int offset); /** - * Create a new action signature with a timestamp of 'now'. The - * signature must be freed manually or using git_signature_free + * Create a new action signature with a timestamp of 'now'. * - * @param sig_out new signature, in case of error NULL + * Call `git_signature_free()` to free the data. + * + * @param out new signature, in case of error NULL * @param name name of the person * @param email email of the person * @return 0 or an error code */ -GIT_EXTERN(int) git_signature_now(git_signature **sig_out, const char *name, const char *email); +GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email); /** - * Create a copy of an existing signature. + * Create a copy of an existing signature. All internal strings are also + * duplicated. + * + * Call `git_signature_free()` to free the data. * - * All internal strings are also duplicated. * @param sig signature to duplicated * @return a copy of sig, NULL on out of memory */ GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig); /** - * Free an existing signature + * Free an existing signature. + * + * Because the signature is not an opaque structure, it is legal to free it + * manually, but be sure to free the "name" and "email" strings in addition + * to the structure itself. * * @param sig signature to free */ diff --git a/git2/include/git2/stash.h b/git2/include/git2/stash.h new file mode 100644 index 000000000..b57d47b3a --- /dev/null +++ b/git2/include/git2/stash.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_stash_h__ +#define INCLUDE_git_stash_h__ + +#include "common.h" +#include "types.h" + +/** + * @file git2/stash.h + * @brief Git stash management routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +typedef enum { + GIT_STASH_DEFAULT = 0, + + /* All changes already added to the index + * are left intact in the working directory + */ + GIT_STASH_KEEP_INDEX = (1 << 0), + + /* All untracked files are also stashed and then + * cleaned up from the working directory + */ + GIT_STASH_INCLUDE_UNTRACKED = (1 << 1), + + /* All ignored files are also stashed and then + * cleaned up from the working directory + */ + GIT_STASH_INCLUDE_IGNORED = (1 << 2), +} git_stash_flags; + +/** + * Save the local modifications to a new stash. + * + * @param out Object id of the commit containing the stashed state. + * This commit is also the target of the direct reference refs/stash. + * + * @param repo The owning repository. + * + * @param stasher The identity of the person performing the stashing. + * + * @param message Optional description along with the stashed state. + * + * @param flags Flags to control the stashing process. (see GIT_STASH_* above) + * + * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash, + * or error code. + */ +GIT_EXTERN(int) git_stash_save( + git_oid *out, + git_repository *repo, + git_signature *stasher, + const char *message, + unsigned int flags); + +/** + * When iterating over all the stashed states, callback that will be + * issued per entry. + * + * @param index The position within the stash list. 0 points to the + * most recent stashed state. + * + * @param message The stash message. + * + * @param stash_id The commit oid of the stashed state. + * + * @param payload Extra parameter to callback function. + * + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +typedef int (*git_stash_cb)( + size_t index, + const char* message, + const git_oid *stash_id, + void *payload); + +/** + * Loop over all the stashed states and issue a callback for each one. + * + * If the callback returns a non-zero value, this will stop looping. + * + * @param repo Repository where to find the stash. + * + * @param callabck Callback to invoke per found stashed state. The most recent + * stash state will be enumerated first. + * + * @param payload Extra parameter to callback function. + * + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +GIT_EXTERN(int) git_stash_foreach( + git_repository *repo, + git_stash_cb callback, + void *payload); + +/** + * Remove a single stashed state from the stash list. + * + * @param repo The owning repository. + * + * @param index The position within the stash list. 0 points to the + * most recent stashed state. + * + * @return 0 on success, or error code + */ + +GIT_EXTERN(int) git_stash_drop( + git_repository *repo, + size_t index); + +/** @} */ +GIT_END_DECL +#endif diff --git a/git2/include/git2/status.h b/git2/include/git2/status.h index 979e6e4ff..a898d1f34 100644 --- a/git2/include/git2/status.h +++ b/git2/include/git2/status.h @@ -19,6 +19,16 @@ */ GIT_BEGIN_DECL +/** + * Status flags for a single file. + * + * A combination of these values will be returned to indicate the status of + * a file. Status compares the working directory, the index, and the + * current HEAD of the repository. The `GIT_STATUS_INDEX` set of flags + * represents the status of file in the index relative to the HEAD, and the + * `GIT_STATUS_WT` set of flags represent the status of the file in the + * working directory relative to the index. + */ typedef enum { GIT_STATUS_CURRENT = 0, @@ -36,24 +46,40 @@ typedef enum { GIT_STATUS_IGNORED = (1u << 14), } git_status_t; +/** + * Function pointer to receive status on individual files + * + * `path` is the relative path to the file from the root of the repository. + * + * `status_flags` is a combination of `git_status_t` values that apply. + * + * `payload` is the value you passed to the foreach function as payload. + */ +typedef int (*git_status_cb)( + const char *path, unsigned int status_flags, void *payload); + /** * Gather file statuses and run a callback for each one. * - * The callback is passed the path of the file, the status and the data - * pointer passed to this function. If the callback returns something other - * than 0, this function will stop looping and return GIT_EUSER. + * The callback is passed the path of the file, the status (a combination of + * the `git_status_t` values above) and the `payload` data pointer passed + * into this function. * - * @param repo a repository object - * @param callback the function to call on each file + * If the callback returns a non-zero value, this function will stop looping + * and return GIT_EUSER. + * + * @param repo A repository object + * @param callback The function to call on each file + * @param payload Pointer to pass through to callback function * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_status_foreach( git_repository *repo, - int (*callback)(const char *, unsigned int, void *), + git_status_cb callback, void *payload); /** - * Select the files on which to report status. + * For extended status, select the files on which to report status. * * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the * rough equivalent of `git status --porcelain` where each file @@ -81,65 +107,98 @@ typedef enum { /** * Flags to control status callbacks * - * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should - * be made on untracked files. These will only be made if the - * workdir files are included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should - * get callbacks. Again, these callbacks will only be made if - * the workdir files are included in the status "show" option. - * Right now, there is no option to include all files in - * directories that are ignored completely. - * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback - * should be made even on unmodified files. - * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories - * which appear to be submodules should just be skipped over. - * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the - * contents of untracked directories should be included in the - * status. Normally if an entire directory is new, then just - * the top-level directory will be included (with a trailing - * slash on the entry name). Given this flag, the directory - * itself will not be included, but all the files in it will. - * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given - * path will be treated as a literal path, and not as a pathspec. + * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made + * on untracked files. These will only be made if the workdir files are + * included in the status "show" option. + * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should get + * callbacks. Again, these callbacks will only be made if the workdir + * files are included in the status "show" option. Right now, there is + * no option to include all files in directories that are ignored + * completely. + * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be + * made even on unmodified files. + * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories which + * appear to be submodules should just be skipped over. + * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the contents of + * untracked directories should be included in the status. Normally if + * an entire directory is new, then just the top-level directory will be + * included (with a trailing slash on the entry name). Given this flag, + * the directory itself will not be included, but all the files in it + * will. + * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path + * will be treated as a literal path, and not as a pathspec. + * + * Calling `git_status_foreach()` is like calling the extended version + * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED, + * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. */ - -enum { +typedef enum { GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0), GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1), GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5), -}; +} git_status_opt_t; /** - * Options to control how callbacks will be made by - * `git_status_foreach_ext()`. + * Options to control how `git_status_foreach_ext()` will issue callbacks. + * + * This structure is set so that zeroing it out will give you relatively + * sane defaults. + * + * The `show` value is one of the `git_status_show_t` constants that + * control which files to scan and in what order. + * + * The `flags` value is an OR'ed combination of the `git_status_opt_t` + * values above. + * + * The `pathspec` is an array of path patterns to match (using + * fnmatch-style matching), or just an array of paths to match exactly if + * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags. */ typedef struct { + unsigned int version; git_status_show_t show; - unsigned int flags; - git_strarray pathspec; + unsigned int flags; + git_strarray pathspec; } git_status_options; +#define GIT_STATUS_OPTIONS_VERSION 1 +#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION} + /** * Gather file status information and run callbacks as requested. + * + * This is an extended version of the `git_status_foreach()` API that + * allows for more granular control over which paths will be processed and + * in what order. See the `git_status_options` structure for details + * about the additional controls that this makes available. + * + * @param repo Repository object + * @param opts Status options structure + * @param callback The function to call on each file + * @param payload Pointer to pass through to callback function + * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_status_foreach_ext( git_repository *repo, const git_status_options *opts, - int (*callback)(const char *, unsigned int, void *), + git_status_cb callback, void *payload); /** - * Get file status for a single file + * Get file status for a single file. * - * @param status_flags the status value - * @param repo a repository object - * @param path the file to retrieve status for, rooted at the repo's workdir - * @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when - * the file doesn't exist in any of HEAD, the index or the worktree, - * 0 otherwise + * This is not quite the same as calling `git_status_foreach_ext()` with + * the pathspec set to the specified path. + * + * @param status_flags The status value for the file + * @param repo A repository object + * @param path The file to retrieve status for, rooted at the repo's workdir + * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD, + * index, and work tree, GIT_EINVALIDPATH if `path` points at a folder, + * GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error. */ GIT_EXTERN(int) git_status_file( unsigned int *status_flags, @@ -156,9 +215,9 @@ GIT_EXTERN(int) git_status_file( * One way to think of this is if you were to do "git add ." on the * directory containing the file, would it be added or not? * - * @param ignored boolean returning 0 if the file is not ignored, 1 if it is - * @param repo a repository object - * @param path the file to check ignores for, rooted at the repo's workdir. + * @param ignored Boolean returning 0 if the file is not ignored, 1 if it is + * @param repo A repository object + * @param path The file to check ignores for, rooted at the repo's workdir. * @return 0 if ignore rules could be processed for the file (regardless * of whether it exists or not), or an error < 0 if they could not. */ diff --git a/git2/include/git2/strarray.h b/git2/include/git2/strarray.h index f6092fa9c..338d13873 100644 --- a/git2/include/git2/strarray.h +++ b/git2/include/git2/strarray.h @@ -19,30 +19,36 @@ GIT_BEGIN_DECL /** Array of strings */ -typedef struct _git_strarray git_strarray; -struct _git_strarray { +typedef struct git_strarray { char **strings; size_t count; -}; +} git_strarray; /** * Close a string array object * - * This method must always be called once a git_strarray is no - * longer needed, otherwise memory will leak. + * This method should be called on `git_strarray` objects where the strings + * array is allocated and contains allocated strings, such as what you + * would get from `git_strarray_copy()`. Not doing so, will result in a + * memory leak. * - * @param array array to close + * This does not free the `git_strarray` itself, since the library will + * never allocate that object directly itself (it is more commonly embedded + * inside another struct or created on the stack). + * + * @param array git_strarray from which to free string data */ GIT_EXTERN(void) git_strarray_free(git_strarray *array); /** * Copy a string array object from source to target. - * - * Note: target is overwritten and hence should be empty, + * + * Note: target is overwritten and hence should be empty, * otherwise its contents are leaked. * * @param tgt target * @param src source + * @return 0 on success, < 0 on allocation failure */ GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src); @@ -51,4 +57,4 @@ GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src); GIT_END_DECL #endif - + diff --git a/git2/include/git2/submodule.h b/git2/include/git2/submodule.h index b00fad2d4..90e45cebd 100644 --- a/git2/include/git2/submodule.h +++ b/git2/include/git2/submodule.h @@ -318,7 +318,7 @@ GIT_EXTERN(int) git_submodule_set_url(git_submodule *submodule, const char *url) * @param submodule Pointer to submodule object * @return Pointer to git_oid or NULL if submodule is not in index. */ -GIT_EXTERN(const git_oid *) git_submodule_index_oid(git_submodule *submodule); +GIT_EXTERN(const git_oid *) git_submodule_index_id(git_submodule *submodule); /** * Get the OID for the submodule in the current HEAD tree. @@ -326,7 +326,7 @@ GIT_EXTERN(const git_oid *) git_submodule_index_oid(git_submodule *submodule); * @param submodule Pointer to submodule object * @return Pointer to git_oid or NULL if submodule is not in the HEAD. */ -GIT_EXTERN(const git_oid *) git_submodule_head_oid(git_submodule *submodule); +GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule); /** * Get the OID for the submodule in the current working directory. @@ -339,7 +339,7 @@ GIT_EXTERN(const git_oid *) git_submodule_head_oid(git_submodule *submodule); * @param submodule Pointer to submodule object * @return Pointer to git_oid or NULL if submodule is not checked out. */ -GIT_EXTERN(const git_oid *) git_submodule_wd_oid(git_submodule *submodule); +GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule); /** * Get the ignore rule for the submodule. diff --git a/git2/include/git2/tag.h b/git2/include/git2/tag.h index 5602914f7..a9773be56 100644 --- a/git2/include/git2/tag.h +++ b/git2/include/git2/tag.h @@ -25,14 +25,16 @@ GIT_BEGIN_DECL /** * Lookup a tag object from the repository. * - * @param tag pointer to the looked up tag + * @param out pointer to the looked up tag * @param repo the repo to use when locating the tag. * @param id identity of the tag to locate. * @return 0 or an error code */ -GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id) +GIT_INLINE(int) git_tag_lookup( + git_tag **out, git_repository *repo, const git_oid *id) { - return git_object_lookup((git_object **)tag, repo, id, (git_otype)GIT_OBJ_TAG); + return git_object_lookup( + (git_object **)out, repo, id, (git_otype)GIT_OBJ_TAG); } /** @@ -41,32 +43,33 @@ GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oi * * @see git_object_lookup_prefix * - * @param tag pointer to the looked up tag + * @param out pointer to the looked up tag * @param repo the repo to use when locating the tag. * @param id identity of the tag to locate. * @param len the length of the short identifier * @return 0 or an error code */ -GIT_INLINE(int) git_tag_lookup_prefix(git_tag **tag, git_repository *repo, const git_oid *id, size_t len) +GIT_INLINE(int) git_tag_lookup_prefix( + git_tag **out, git_repository *repo, const git_oid *id, size_t len) { - return git_object_lookup_prefix((git_object **)tag, repo, id, len, (git_otype)GIT_OBJ_TAG); + return git_object_lookup_prefix( + (git_object **)out, repo, id, len, (git_otype)GIT_OBJ_TAG); } /** * Close an open tag * - * This is a wrapper around git_object_free() + * You can no longer use the git_tag pointer after this call. * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a tag. Failure to do so will cause a memory leak. + * IMPORTANT: You MUST call this method when you are through with a tag to + * release memory. Failure to do so will cause a memory leak. * * @param tag the tag to close */ GIT_INLINE(void) git_tag_free(git_tag *tag) { - git_object_free((git_object *) tag); + git_object_free((git_object *)tag); } @@ -76,7 +79,7 @@ GIT_INLINE(void) git_tag_free(git_tag *tag) * @param tag a previously loaded tag. * @return object identity for the tag. */ -GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag); +GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag); /** * Get the tagged object of a tag @@ -84,11 +87,11 @@ GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag); * This method performs a repository lookup for the * given object and returns it * - * @param target pointer where to store the target + * @param target_out pointer where to store the target * @param tag a previously loaded tag. * @return 0 or an error code */ -GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag); +GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag); /** * Get the OID of the tagged object of a tag @@ -96,7 +99,7 @@ GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag); * @param tag a previously loaded tag. * @return pointer to the OID */ -GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag); +GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag); /** * Get the type of a tag's tagged object @@ -104,7 +107,7 @@ GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag); * @param tag a previously loaded tag. * @return type of the tagged object */ -GIT_EXTERN(git_otype) git_tag_type(git_tag *tag); +GIT_EXTERN(git_otype) git_tag_target_type(const git_tag *tag); /** * Get the name of a tag @@ -112,7 +115,7 @@ GIT_EXTERN(git_otype) git_tag_type(git_tag *tag); * @param tag a previously loaded tag. * @return name of the tag */ -GIT_EXTERN(const char *) git_tag_name(git_tag *tag); +GIT_EXTERN(const char *) git_tag_name(const git_tag *tag); /** * Get the tagger (author) of a tag @@ -120,7 +123,7 @@ GIT_EXTERN(const char *) git_tag_name(git_tag *tag); * @param tag a previously loaded tag. * @return reference to the tag's author */ -GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag); +GIT_EXTERN(const git_signature *) git_tag_tagger(const git_tag *tag); /** * Get the message of a tag @@ -128,7 +131,7 @@ GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag); * @param tag a previously loaded tag. * @return message of the tag */ -GIT_EXTERN(const char *) git_tag_message(git_tag *tag); +GIT_EXTERN(const char *) git_tag_message(const git_tag *tag); /** @@ -141,6 +144,10 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag); * The message will not be cleaned up. This can be achieved * through `git_message_prettify()`. * + * The tag name will be checked for validity. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * * @param oid Pointer where to store the OID of the * newly created tag. If the tag already exists, this parameter * will be the oid of the existing tag, and the function will @@ -162,18 +169,18 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag); * * @param force Overwrite existing references * - * @return 0 or an error code + * @return 0 on success, GIT_EINVALIDSPEC or an error code * A tag object is written to the ODB, and a proper reference * is written in the /refs/tags folder, pointing to it */ GIT_EXTERN(int) git_tag_create( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - const git_signature *tagger, - const char *message, - int force); + git_oid *oid, + git_repository *repo, + const char *tag_name, + const git_object *target, + const git_signature *tagger, + const char *message, + int force); /** * Create a new tag in the repository from a buffer @@ -185,10 +192,10 @@ GIT_EXTERN(int) git_tag_create( * @return 0 on success; error code otherwise */ GIT_EXTERN(int) git_tag_create_frombuffer( - git_oid *oid, - git_repository *repo, - const char *buffer, - int force); + git_oid *oid, + git_repository *repo, + const char *buffer, + int force); /** * Create a new lightweight tag pointing at a target object @@ -197,6 +204,9 @@ GIT_EXTERN(int) git_tag_create_frombuffer( * this target object. If `force` is true and a reference * already exists with the given name, it'll be replaced. * + * The tag name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * * @param oid Pointer where to store the OID of the provided * target object. If the tag already exists, this parameter * will be filled with the oid of the existing pointed object @@ -213,30 +223,33 @@ GIT_EXTERN(int) git_tag_create_frombuffer( * * @param force Overwrite existing references * - * @return 0 or an error code + * @return 0 on success, GIT_EINVALIDSPEC or an error code * A proper reference is written in the /refs/tags folder, * pointing to the provided target object */ GIT_EXTERN(int) git_tag_create_lightweight( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - int force); + git_oid *oid, + git_repository *repo, + const char *tag_name, + const git_object *target, + int force); /** * Delete an existing tag reference. * + * The tag name will be checked for validity. + * See `git_tag_create()` for rules about valid names. + * * @param repo Repository where lives the tag * * @param tag_name Name of the tag to be deleted; * this name is validated for consistency. * - * @return 0 or an error code + * @return 0 on success, GIT_EINVALIDSPEC or an error code */ GIT_EXTERN(int) git_tag_delete( - git_repository *repo, - const char *tag_name); + git_repository *repo, + const char *tag_name); /** * Fill a list with all the tags in the Repository @@ -252,8 +265,8 @@ GIT_EXTERN(int) git_tag_delete( * @return 0 or an error code */ GIT_EXTERN(int) git_tag_list( - git_strarray *tag_names, - git_repository *repo); + git_strarray *tag_names, + git_repository *repo); /** * Fill a list with all the tags in the Repository @@ -274,39 +287,39 @@ GIT_EXTERN(int) git_tag_list( * @return 0 or an error code */ GIT_EXTERN(int) git_tag_list_match( - git_strarray *tag_names, - const char *pattern, - git_repository *repo); + git_strarray *tag_names, + const char *pattern, + git_repository *repo); -typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *data); +typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *payload); + /** * Call callback `cb' for each tag in the repository * * @param repo Repository - * @param cb Callback function - * @param cb_data Pointer to callback data (optional) + * @param callback Callback function + * @param payload Pointer to callback data (optional) */ GIT_EXTERN(int) git_tag_foreach( - git_repository *repo, - git_tag_foreach_cb cb, - void *cb_data); + git_repository *repo, + git_tag_foreach_cb callback, + void *payload); /** - * Recursively peel a tag until a non tag git_object - * is met + * Recursively peel a tag until a non tag git_object is found * * The retrieved `tag_target` object is owned by the repository * and should be closed with the `git_object_free` method. * - * @param tag_target Pointer to the peeled git_object + * @param tag_target_out Pointer to the peeled git_object * @param tag The tag to be processed * @return 0 or an error code */ GIT_EXTERN(int) git_tag_peel( - git_object **tag_target, - git_tag *tag); + git_object **tag_target_out, + const git_tag *tag); /** @} */ GIT_END_DECL diff --git a/git2/include/git2/threads.h b/git2/include/git2/threads.h index 567a10487..f448f6a4d 100644 --- a/git2/include/git2/threads.h +++ b/git2/include/git2/threads.h @@ -27,8 +27,10 @@ GIT_BEGIN_DECL * * If libgit2 has been built without GIT_THREADS * support, this function is a no-op. + * + * @return 0 or an error code */ -GIT_EXTERN(void) git_threads_init(void); +GIT_EXTERN(int) git_threads_init(void); /** * Shutdown the threading system. diff --git a/git2/include/git2/transport.h b/git2/include/git2/transport.h new file mode 100644 index 000000000..c2f205295 --- /dev/null +++ b/git2/include/git2/transport.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_transport_h__ +#define INCLUDE_git_transport_h__ + +#include "indexer.h" +#include "net.h" +#include "types.h" + +/** + * @file git2/transport.h + * @brief Git transport interfaces and functions + * @defgroup git_transport interfaces and functions + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/* + *** Begin interface for credentials acquisition *** + */ + +typedef enum { + /* git_cred_userpass_plaintext */ + GIT_CREDTYPE_USERPASS_PLAINTEXT = 1, +} git_credtype_t; + +/* The base structure for all credential types */ +typedef struct git_cred { + git_credtype_t credtype; + void (*free)( + struct git_cred *cred); +} git_cred; + +/* A plaintext username and password */ +typedef struct git_cred_userpass_plaintext { + git_cred parent; + char *username; + char *password; +} git_cred_userpass_plaintext; + +/** + * Creates a new plain-text username and password credential object. + * + * @param out The newly created credential object. + * @param username The username of the credential. + * @param password The password of the credential. + */ +GIT_EXTERN(int) git_cred_userpass_plaintext_new( + git_cred **out, + const char *username, + const char *password); + +/** + * Signature of a function which acquires a credential object. + * + * @param cred The newly created credential object. + * @param url The resource for which we are demanding a credential. + * @param allowed_types A bitmask stating which cred types are OK to return. + */ +typedef int (*git_cred_acquire_cb)( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload); + +/* + *** End interface for credentials acquisition *** + *** Begin base transport interface *** + */ + +typedef enum { + GIT_TRANSPORTFLAGS_NONE = 0, + /* If the connection is secured with SSL/TLS, the authenticity + * of the server certificate should not be verified. */ + GIT_TRANSPORTFLAGS_NO_CHECK_CERT = 1 +} git_transport_flags_t; + +typedef void (*git_transport_message_cb)(const char *str, int len, void *data); + +typedef struct git_transport { + unsigned int version; + /* Set progress and error callbacks */ + int (*set_callbacks)(struct git_transport *transport, + git_transport_message_cb progress_cb, + git_transport_message_cb error_cb, + void *payload); + + /* Connect the transport to the remote repository, using the given + * direction. */ + int (*connect)(struct git_transport *transport, + const char *url, + git_cred_acquire_cb cred_acquire_cb, + void *cred_acquire_payload, + int direction, + int flags); + + /* This function may be called after a successful call to connect(). The + * provided callback is invoked for each ref discovered on the remote + * end. */ + int (*ls)(struct git_transport *transport, + git_headlist_cb list_cb, + void *payload); + + /* Executes the push whose context is in the git_push object. */ + int (*push)(struct git_transport *transport, git_push *push); + + /* This function may be called after a successful call to connect(), when + * the direction is FETCH. The function performs a negotiation to calculate + * the wants list for the fetch. */ + int (*negotiate_fetch)(struct git_transport *transport, + git_repository *repo, + const git_remote_head * const *refs, + size_t count); + + /* This function may be called after a successful call to negotiate_fetch(), + * when the direction is FETCH. This function retrieves the pack file for + * the fetch from the remote end. */ + int (*download_pack)(struct git_transport *transport, + git_repository *repo, + git_transfer_progress *stats, + git_transfer_progress_callback progress_cb, + void *progress_payload); + + /* Checks to see if the transport is connected */ + int (*is_connected)(struct git_transport *transport); + + /* Reads the flags value previously passed into connect() */ + int (*read_flags)(struct git_transport *transport, int *flags); + + /* Cancels any outstanding transport operation */ + void (*cancel)(struct git_transport *transport); + + /* This function is the reverse of connect() -- it terminates the + * connection to the remote end. */ + int (*close)(struct git_transport *transport); + + /* Frees/destructs the git_transport object. */ + void (*free)(struct git_transport *transport); +} git_transport; + +#define GIT_TRANSPORT_VERSION 1 +#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION} + +/** + * Function to use to create a transport from a URL. The transport database + * is scanned to find a transport that implements the scheme of the URI (i.e. + * git:// or http://) and a transport object is returned to the caller. + * + * @param out The newly created transport (out) + * @param owner The git_remote which will own this transport + * @param url The URL to connect to + * @return 0 or an error code + */ +GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url); + +/** + * Function which checks to see if a transport could be created for the + * given URL (i.e. checks to see if libgit2 has a transport that supports + * the given URL's scheme) + * + * @param url The URL to check + * @return Zero if the URL is not valid; nonzero otherwise + */ +GIT_EXTERN(int) git_transport_valid_url(const char *url); + +/* Signature of a function which creates a transport */ +typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param); + +/* Transports which come with libgit2 (match git_transport_cb). The expected + * value for "param" is listed in-line below. */ + +/** + * Create an instance of the dummy transport. + * + * @param out The newly created transport (out) + * @param owner The git_remote which will own this transport + * @param payload You must pass NULL for this parameter. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_transport_dummy( + git_transport **out, + git_remote *owner, + /* NULL */ void *payload); + +/** + * Create an instance of the local transport. + * + * @param out The newly created transport (out) + * @param owner The git_remote which will own this transport + * @param payload You must pass NULL for this parameter. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_transport_local( + git_transport **out, + git_remote *owner, + /* NULL */ void *payload); + +/** + * Create an instance of the smart transport. + * + * @param out The newly created transport (out) + * @param owner The git_remote which will own this transport + * @param payload A pointer to a git_smart_subtransport_definition + * @return 0 or an error code + */ +GIT_EXTERN(int) git_transport_smart( + git_transport **out, + git_remote *owner, + /* (git_smart_subtransport_definition *) */ void *payload); + +/* + *** End of base transport interface *** + *** Begin interface for subtransports for the smart transport *** + */ + +/* The smart transport knows how to speak the git protocol, but it has no + * knowledge of how to establish a connection between it and another endpoint, + * or how to move data back and forth. For this, a subtransport interface is + * declared, and the smart transport delegates this work to the subtransports. + * Three subtransports are implemented: git, http, and winhttp. (The http and + * winhttp transports each implement both http and https.) */ + +/* Subtransports can either be RPC = 0 (persistent connection) or RPC = 1 + * (request/response). The smart transport handles the differences in its own + * logic. The git subtransport is RPC = 0, while http and winhttp are both + * RPC = 1. */ + +/* Actions that the smart transport can ask + * a subtransport to perform */ +typedef enum { + GIT_SERVICE_UPLOADPACK_LS = 1, + GIT_SERVICE_UPLOADPACK = 2, + GIT_SERVICE_RECEIVEPACK_LS = 3, + GIT_SERVICE_RECEIVEPACK = 4, +} git_smart_service_t; + +struct git_smart_subtransport; + +/* A stream used by the smart transport to read and write data + * from a subtransport */ +typedef struct git_smart_subtransport_stream { + /* The owning subtransport */ + struct git_smart_subtransport *subtransport; + + int (*read)( + struct git_smart_subtransport_stream *stream, + char *buffer, + size_t buf_size, + size_t *bytes_read); + + int (*write)( + struct git_smart_subtransport_stream *stream, + const char *buffer, + size_t len); + + void (*free)( + struct git_smart_subtransport_stream *stream); +} git_smart_subtransport_stream; + +/* An implementation of a subtransport which carries data for the + * smart transport */ +typedef struct git_smart_subtransport { + int (* action)( + git_smart_subtransport_stream **out, + struct git_smart_subtransport *transport, + const char *url, + git_smart_service_t action); + + /* Subtransports are guaranteed a call to close() between + * calls to action(), except for the following two "natural" progressions + * of actions against a constant URL. + * + * 1. UPLOADPACK_LS -> UPLOADPACK + * 2. RECEIVEPACK_LS -> RECEIVEPACK */ + int (* close)(struct git_smart_subtransport *transport); + + void (* free)(struct git_smart_subtransport *transport); +} git_smart_subtransport; + +/* A function which creates a new subtransport for the smart transport */ +typedef int (*git_smart_subtransport_cb)( + git_smart_subtransport **out, + git_transport* owner); + +typedef struct git_smart_subtransport_definition { + /* The function to use to create the git_smart_subtransport */ + git_smart_subtransport_cb callback; + + /* True if the protocol is stateless; false otherwise. For example, + * http:// is stateless, but git:// is not. */ + unsigned rpc : 1; +} git_smart_subtransport_definition; + +/* Smart transport subtransports that come with libgit2 */ + +/** + * Create an instance of the http subtransport. This subtransport + * also supports https. On Win32, this subtransport may be implemented + * using the WinHTTP library. + * + * @param out The newly created subtransport + * @param owner The smart transport to own this subtransport + * @return 0 or an error code + */ +GIT_EXTERN(int) git_smart_subtransport_http( + git_smart_subtransport **out, + git_transport* owner); + +/** + * Create an instance of the git subtransport. + * + * @param out The newly created subtransport + * @param owner The smart transport to own this subtransport + * @return 0 or an error code + */ +GIT_EXTERN(int) git_smart_subtransport_git( + git_smart_subtransport **out, + git_transport* owner); + +/* + *** End interface for subtransports for the smart transport *** + */ + +/** @} */ +GIT_END_DECL +#endif diff --git a/git2/include/git2/tree.h b/git2/include/git2/tree.h index 2ee1f4afa..b3c22e71d 100644 --- a/git2/include/git2/tree.h +++ b/git2/include/git2/tree.h @@ -24,14 +24,15 @@ GIT_BEGIN_DECL /** * Lookup a tree object from the repository. * - * @param tree pointer to the looked up tree - * @param repo the repo to use when locating the tree. - * @param id identity of the tree to locate. + * @param out Pointer to the looked up tree + * @param repo The repo to use when locating the tree. + * @param id Identity of the tree to locate. * @return 0 or an error code */ -GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id) +GIT_INLINE(int) git_tree_lookup( + git_tree **out, git_repository *repo, const git_oid *id) { - return git_object_lookup((git_object **)tree, repo, id, GIT_OBJ_TREE); + return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE); } /** @@ -47,53 +48,30 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git * @return 0 or an error code */ GIT_INLINE(int) git_tree_lookup_prefix( - git_tree **tree, + git_tree **out, git_repository *repo, const git_oid *id, size_t len) { - return git_object_lookup_prefix((git_object **)tree, repo, id, len, GIT_OBJ_TREE); + return git_object_lookup_prefix( + (git_object **)out, repo, id, len, GIT_OBJ_TREE); } /** * Close an open tree * - * This is a wrapper around git_object_free() + * You can no longer use the git_tree pointer after this call. * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a tree. Failure to do so will cause a memory leak. + * IMPORTANT: You MUST call this method when you stop using a tree to + * release memory. Failure to do so will cause a memory leak. * - * @param tree the tree to close + * @param tree The tree to close */ GIT_INLINE(void) git_tree_free(git_tree *tree) { - git_object_free((git_object *) tree); + git_object_free((git_object *)tree); } -/** - * Free a tree entry - * - * IMPORTANT: This function is only needed for tree - * entries owned by the user, such as the ones returned - * by `git_tree_entry_dup`. - * - * @param entry The entry to free - */ -GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry); - -/** - * Duplicate a tree entry - * - * Create a copy of a tree entry. The returned copy is owned - * by the user, and must be freed manually with - * `git_tree_entry_free`. - * - * @param entry A tree entry to duplicate - * @return a copy of the original entry - */ -GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); - /** * Get the id of a tree. * @@ -102,50 +80,101 @@ GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); */ GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree); +/** + * Get the repository that contains the tree. + * + * @param tree A previously loaded tree. + * @return Repository that contains this tree. + */ +GIT_EXTERN(git_repository *) git_tree_owner(const git_tree *tree); + /** * Get the number of entries listed in a tree * * @param tree a previously loaded tree. * @return the number of entries in the tree */ -GIT_EXTERN(unsigned int) git_tree_entrycount(const git_tree *tree); +GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree); /** * Lookup a tree entry by its filename * + * This returns a git_tree_entry that is owned by the git_tree. You don't + * have to free it, but you must not use it after the git_tree is released. + * * @param tree a previously loaded tree. * @param filename the filename of the desired entry * @return the tree entry; NULL if not found */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(git_tree *tree, const char *filename); +GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname( + git_tree *tree, const char *filename); /** * Lookup a tree entry by its position in the tree * + * This returns a git_tree_entry that is owned by the git_tree. You don't + * have to free it, but you must not use it after the git_tree is released. + * * @param tree a previously loaded tree. * @param idx the position in the entry list * @return the tree entry; NULL if not found */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(git_tree *tree, size_t idx); +GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex( + git_tree *tree, size_t idx); /** * Lookup a tree entry by SHA value. * + * This returns a git_tree_entry that is owned by the git_tree. You don't + * have to free it, but you must not use it after the git_tree is released. + * * Warning: this must examine every entry in the tree, so it is not fast. * * @param tree a previously loaded tree. * @param oid the sha being looked for * @return the tree entry; NULL if not found */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid(git_tree *tree, const git_oid *oid); +GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid( + const git_tree *tree, const git_oid *oid); /** - * Get the UNIX file attributes of a tree entry + * Retrieve a tree entry contained in a tree or in any of its subtrees, + * given its relative path. * - * @param entry a tree entry - * @return filemode as an integer + * Unlike the other lookup functions, the returned tree entry is owned by + * the user and must be freed explicitly with `git_tree_entry_free()`. + * + * @param out Pointer where to store the tree entry + * @param root Previously loaded tree which is the root of the relative path + * @param subtree_path Path to the contained entry + * @return 0 on success; GIT_ENOTFOUND if the path does not exist */ -GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry); +GIT_EXTERN(int) git_tree_entry_bypath( + git_tree_entry **out, + git_tree *root, + const char *path); + +/** + * Duplicate a tree entry + * + * Create a copy of a tree entry. The returned copy is owned by the user, + * and must be freed explicitly with `git_tree_entry_free()`. + * + * @param entry A tree entry to duplicate + * @return a copy of the original entry or NULL on error (alloc failure) + */ +GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); + +/** + * Free a user-owned tree entry + * + * IMPORTANT: This function is only needed for tree entries owned by the + * user, such as the ones returned by `git_tree_entry_dup()` or + * `git_tree_entry_bypath()`. + * + * @param entry The entry to free + */ +GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry); /** * Get the filename of a tree entry @@ -171,9 +200,19 @@ GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry); */ GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry); +/** + * Get the UNIX file attributes of a tree entry + * + * @param entry a tree entry + * @return filemode as an integer + */ +GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry); + /** * Convert a tree entry to the git_object it points too. * + * You must call `git_object_free()` on the object when you are done with it. + * * @param object pointer to the converted object * @param repo repository where to lookup the pointed object * @param entry a tree entry @@ -184,42 +223,24 @@ GIT_EXTERN(int) git_tree_entry_to_object( git_repository *repo, const git_tree_entry *entry); -/** - * Write a tree to the ODB from the index file - * - * This method will scan the index and write a representation - * of its current state back to disk; it recursively creates - * tree objects for each of the subtrees stored in the index, - * but only returns the OID of the root tree. This is the OID - * that can be used e.g. to create a commit. - * - * The index instance cannot be bare, and needs to be associated - * to an existing repository. - * - * @param oid Pointer where to store the written tree - * @param index Index to write - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index); - /** * Create a new tree builder. * - * The tree builder can be used to create or modify - * trees in memory and write them as tree objects to the - * database. + * The tree builder can be used to create or modify trees in memory and + * write them as tree objects to the database. * - * If the `source` parameter is not NULL, the tree builder - * will be initialized with the entries of the given tree. + * If the `source` parameter is not NULL, the tree builder will be + * initialized with the entries of the given tree. * - * If the `source` parameter is NULL, the tree builder will - * have no entries and will have to be filled manually. + * If the `source` parameter is NULL, the tree builder will start with no + * entries and will have to be filled manually. * - * @param builder_p Pointer where to store the tree builder + * @param out Pointer where to store the tree builder * @param source Source tree to initialize the builder (optional) * @return 0 on success; error code otherwise */ -GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source); +GIT_EXTERN(int) git_treebuilder_create( + git_treebuilder **out, const git_tree *source); /** * Clear all the entires in the builder @@ -249,7 +270,8 @@ GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld); * @param filename Name of the entry * @return pointer to the entry; NULL if not found */ -GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, const char *filename); +GIT_EXTERN(const git_tree_entry *) git_treebuilder_get( + git_treebuilder *bld, const char *filename); /** * Add or update an entry to the builder @@ -257,17 +279,17 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con * Insert a new entry for `filename` in the builder with the * given attributes. * - * if an entry named `filename` already exists, its attributes + * If an entry named `filename` already exists, its attributes * will be updated with the given ones. * - * The optional pointer `entry_out` can be used to retrieve a - * pointer to the newly created/updated entry. + * The optional pointer `out` can be used to retrieve a pointer to + * the newly created/updated entry. Pass NULL if you do not need it. * * No attempt is being made to ensure that the provided oid points * to an existing git object in the object database, nor that the * attributes make sense regarding the type of the pointed at object. * - * @param entry_out Pointer to store the entry (optional) + * @param out Pointer to store the entry (optional) * @param bld Tree builder * @param filename Filename of the entry * @param id SHA1 oid of the entry @@ -277,7 +299,7 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con * @return 0 or an error code */ GIT_EXTERN(int) git_treebuilder_insert( - const git_tree_entry **entry_out, + const git_tree_entry **out, git_treebuilder *bld, const char *filename, const git_oid *id, @@ -289,85 +311,75 @@ GIT_EXTERN(int) git_treebuilder_insert( * @param bld Tree builder * @param filename Filename of the entry to remove */ -GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filename); +GIT_EXTERN(int) git_treebuilder_remove( + git_treebuilder *bld, const char *filename); + +typedef int (*git_treebuilder_filter_cb)( + const git_tree_entry *entry, void *payload); /** * Filter the entries in the tree * - * The `filter` callback will be called for each entry - * in the tree with a pointer to the entry and the - * provided `payload`: if the callback returns 1, the - * entry will be filtered (removed from the builder). + * The `filter` callback will be called for each entry in the tree with a + * pointer to the entry and the provided `payload`; if the callback returns + * non-zero, the entry will be filtered (removed from the builder). * * @param bld Tree builder * @param filter Callback to filter entries + * @param payload Extra data to pass to filter */ GIT_EXTERN(void) git_treebuilder_filter( git_treebuilder *bld, - int (*filter)(const git_tree_entry *, void *), + git_treebuilder_filter_cb filter, void *payload); /** * Write the contents of the tree builder as a tree object * - * The tree builder will be written to the given `repo`, and - * it's identifying SHA1 hash will be stored in the `oid` - * pointer. + * The tree builder will be written to the given `repo`, and its + * identifying SHA1 hash will be stored in the `id` pointer. * - * @param oid Pointer where to store the written OID - * @param repo Repository where to store the object + * @param id Pointer to store the OID of the newly written tree + * @param repo Repository in which to store the object * @param bld Tree builder to write * @return 0 or an error code */ -GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld); +GIT_EXTERN(int) git_treebuilder_write( + git_oid *id, git_repository *repo, git_treebuilder *bld); -/** - * Retrieve a tree entry contained in a tree or in any - * of its subtrees, given its relative path. - * - * The returned tree entry is owned by the user and must - * be freed manually with `git_tree_entry_free`. - * - * @param entry Pointer where to store the tree entry - * @param root A previously loaded tree which will be the root of the relative path - * @param subtree_path Path to the contained entry - * @return 0 on success; GIT_ENOTFOUND if the path does not exist - */ -GIT_EXTERN(int) git_tree_entry_bypath( - git_tree_entry **entry, - git_tree *root, - const char *path); /** Callback for the tree traversal method */ -typedef int (*git_treewalk_cb)(const char *root, const git_tree_entry *entry, void *payload); +typedef int (*git_treewalk_cb)( + const char *root, const git_tree_entry *entry, void *payload); /** Tree traversal modes */ -enum git_treewalk_mode { +typedef enum { GIT_TREEWALK_PRE = 0, /* Pre-order */ GIT_TREEWALK_POST = 1, /* Post-order */ -}; +} git_treewalk_mode; /** - * Traverse the entries in a tree and its subtrees in - * post or pre order + * Traverse the entries in a tree and its subtrees in post or pre order. * - * The entries will be traversed in the specified order, - * children subtrees will be automatically loaded as required, - * and the `callback` will be called once per entry with - * the current (relative) root for the entry and the entry - * data itself. + * The entries will be traversed in the specified order, children subtrees + * will be automatically loaded as required, and the `callback` will be + * called once per entry with the current (relative) root for the entry and + * the entry data itself. * * If the callback returns a positive value, the passed entry will be - * skipped on the traversal (in pre mode). A negative value stops the - * walk. + * skipped on the traversal (in pre mode). A negative value stops the walk. * * @param tree The tree to walk - * @param callback Function to call on each tree entry * @param mode Traversal mode (pre or post-order) + * @param callback Function to call on each tree entry * @param payload Opaque pointer to be passed on each callback * @return 0 or an error code */ -GIT_EXTERN(int) git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payload); +GIT_EXTERN(int) git_tree_walk( + const git_tree *tree, + git_treewalk_mode mode, + git_treewalk_cb callback, + void *payload); /** @} */ diff --git a/git2/include/git2/types.h b/git2/include/git2/types.h index 01ddbf3d6..06fcf3613 100644 --- a/git2/include/git2/types.h +++ b/git2/include/git2/types.h @@ -89,6 +89,9 @@ typedef struct git_odb_object git_odb_object; /** A stream to read/write from the ODB */ typedef struct git_odb_stream git_odb_stream; +/** A stream to write a packfile to the ODB */ +typedef struct git_odb_writepack git_odb_writepack; + /** * Representation of an existing git repository, * including all its object contents @@ -126,7 +129,7 @@ typedef struct git_index git_index; typedef struct git_config git_config; /** Interface to access a configuration file */ -typedef struct git_config_file git_config_file; +typedef struct git_config_backend git_config_backend; /** Representation of a reference log entry */ typedef struct git_reflog_entry git_reflog_entry; @@ -172,13 +175,6 @@ typedef enum { GIT_BRANCH_REMOTE = 2, } git_branch_t; -/** Kinds of reset operation. */ -typedef enum { - GIT_RESET_SOFT = 1, - GIT_RESET_MIXED = 2, - GIT_RESET_HARD = 3, -} git_reset_type; - /** Valid modes for index and tree entries. */ typedef enum { GIT_FILEMODE_NEW = 0000000, @@ -191,6 +187,7 @@ typedef enum { typedef struct git_refspec git_refspec; typedef struct git_remote git_remote; +typedef struct git_push git_push; typedef struct git_remote_head git_remote_head; typedef struct git_remote_callbacks git_remote_callbacks; diff --git a/git2/libgit2.gypi b/git2/libgit2.gypi index 028551a47..0494be661 100644 --- a/git2/libgit2.gypi +++ b/git2/libgit2.gypi @@ -41,6 +41,10 @@ 'git2/include/git2/reset.h', 'git2/include/git2/revparse.h', 'git2/include/git2/strarray.h', + 'git2/include/git2/graph.h', + 'git2/include/git2/push.h', + 'git2/include/git2/stash.h', + 'git2/include/git2/transport.h', ], } } diff --git a/native/v8_extensions/git.mm b/native/v8_extensions/git.mm index 43f7e6d3f..2788723a5 100644 --- a/native/v8_extensions/git.mm +++ b/native/v8_extensions/git.mm @@ -33,7 +33,7 @@ public: git_reference *head; if (git_repository_head(&head, repo) == GIT_OK) { if (git_repository_head_detached(repo) == 1) { - const git_oid* sha = git_reference_oid(head); + const git_oid* sha = git_reference_target(head); if (sha) { char oid[GIT_OID_HEXSZ + 1]; git_oid_tostr(oid, GIT_OID_HEXSZ + 1, sha); @@ -91,9 +91,8 @@ public: char *copiedPath = (char *)malloc(sizeof(char) * (strlen(path) + 1)); strcpy(copiedPath, path); - git_checkout_opts options; - memset(&options, 0, sizeof(options)); - options.checkout_strategy = GIT_CHECKOUT_OVERWRITE_MODIFIED; + git_checkout_opts options = GIT_CHECKOUT_OPTS_INIT; + options.checkout_strategy = GIT_CHECKOUT_UPDATE_MODIFIED; git_strarray paths; paths.count = 1; paths.strings = &copiedPath; @@ -119,7 +118,7 @@ public: return CefV8Value::CreateNull(); } - const git_oid* sha = git_reference_oid(head); + const git_oid* sha = git_reference_target(head); git_commit *commit; int commitStatus = git_commit_lookup(&commit, repo, sha); git_reference_free(head); @@ -136,8 +135,7 @@ public: char *copiedPath = (char *)malloc(sizeof(char) * (strlen(path) + 1)); strcpy(copiedPath, path); - git_diff_options options; - memset(&options, 0, sizeof(options)); + git_diff_options options = GIT_DIFF_OPTIONS_INIT; git_strarray paths; paths.count = 1; paths.strings = &copiedPath; @@ -146,7 +144,7 @@ public: options.flags = GIT_DIFF_DISABLE_PATHSPEC_MATCH; git_diff_list *diffs; - int diffStatus = git_diff_workdir_to_tree(repo, &options, tree, &diffs); + int diffStatus = git_diff_tree_to_workdir(&diffs, repo, tree, &options); free(copiedPath); if (diffStatus != GIT_OK) { return CefV8Value::CreateNull(); @@ -165,12 +163,11 @@ public: for (int i = 0; i < hunks; i++) { int lines = git_diff_patch_num_lines_in_hunk(patch, i); for (int j = 0; j < lines; j++) { - char lineType[2]; - lineType[1] = '\0'; - if (git_diff_patch_get_line_in_hunk(lineType, NULL, NULL, NULL, NULL, patch, i, j) == GIT_OK) { - if (strcmp(lineType, "+") == 0) { + char lineType; + if (git_diff_patch_get_line_in_hunk(&lineType, NULL, NULL, NULL, NULL, patch, i, j) == GIT_OK) { + if (lineType == GIT_DIFF_LINE_ADDITION) { added++; - } else if(strcmp(lineType, "-") == 0) { + } else if(lineType == GIT_DIFF_LINE_DELETION) { deleted++; } } diff --git a/script/update-libgit2 b/script/update-libgit2 new file mode 100755 index 000000000..7f6face0c --- /dev/null +++ b/script/update-libgit2 @@ -0,0 +1,4 @@ +#!/bin/sh + +# update the id of the dylib +install_name_tool -id @executable_path/libgit2.0.17.0.dylib git2/frameworks/libgit2.0.17.0.dylib