diff options
Diffstat (limited to 'include/git2')
44 files changed, 2183 insertions, 964 deletions
diff --git a/include/git2/attr.h b/include/git2/attr.h index dea44f0e3..f256ff861 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -141,7 +141,7 @@ GIT_EXTERN(git_attr_t) git_attr_value(const char *attr); */ GIT_EXTERN(int) git_attr_get( const char **value_out, - git_repository *repo, + git_repository *repo, uint32_t flags, const char *path, const char *name); @@ -162,7 +162,7 @@ GIT_EXTERN(int) git_attr_get( * Then you could loop through the 3 values to get the settings for * the three attributes you asked about. * - * @param values An array of num_attr entries that will have string + * @param values_out An array of num_attr entries that will have string * pointers written into it for the values of the attributes. * You should not modify or free the values that are written * into this array (although of course, you should free the @@ -228,7 +228,7 @@ GIT_EXTERN(void) git_attr_cache_flush( * function allows you to add others. For example, to add the default * macro, you would call: * - * git_attr_add_macro(repo, "binary", "-diff -crlf"); + * git_attr_add_macro(repo, "binary", "-diff -crlf"); */ GIT_EXTERN(int) git_attr_add_macro( git_repository *repo, diff --git a/include/git2/blob.h b/include/git2/blob.h index 0a2aa9d36..8fca48966 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -29,10 +29,7 @@ GIT_BEGIN_DECL * @param id identity of the blob to locate. * @return 0 or an error code */ -GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)blob, repo, id, GIT_OBJ_BLOB); -} +GIT_EXTERN(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id); /** * Lookup a blob object from a repository, @@ -46,10 +43,7 @@ GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git * @param len the length of the short identifier * @return 0 or an error code */ -GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)blob, repo, id, len, GIT_OBJ_BLOB); -} +GIT_EXTERN(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len); /** * Close an open blob @@ -62,11 +56,7 @@ GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, co * * @param blob the blob to close */ - -GIT_INLINE(void) git_blob_free(git_blob *blob) -{ - git_object_free((git_object *) blob); -} +GIT_EXTERN(void) git_blob_free(git_blob *blob); /** * Get the id of a blob. @@ -74,11 +64,15 @@ GIT_INLINE(void) git_blob_free(git_blob *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); -} +GIT_EXTERN(const git_oid *) git_blob_id(const git_blob *blob); +/** + * Get the repository that contains the blob. + * + * @param blob A previously loaded blob. + * @return Repository that contains this blob. + */ +GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob); /** * Get a read-only buffer with the raw content of a blob. diff --git a/include/git2/branch.h b/include/git2/branch.h index b15171360..de414e9b0 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -58,7 +58,8 @@ GIT_EXTERN(int) git_branch_create( * Delete an existing branch reference. * * If the branch is successfully deleted, the passed reference - * object will be freed and invalidated. + * object will be invalidated. The reference must be freed manually + * by the user. * * @param branch A valid reference representing a branch * @return 0 on success, or an error code. @@ -237,7 +238,7 @@ GIT_EXTERN(int) git_branch_is_head( * * @return Number of characters in the reference name * including the trailing NUL byte; GIT_ENOTFOUND - * when no remote matching remote was gound, + * when no remote matching remote was found, * GIT_EAMBIGUOUS when the branch maps to several remotes, * otherwise an error code. */ diff --git a/include/git2/checkout.h b/include/git2/checkout.h index d3e971b43..a086408c7 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -134,6 +134,9 @@ typedef enum { /** Treat pathspec as simple list of exact match file paths */ GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13), + /** Ignore directories in use, they will be left empty */ + GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18), + /** * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED */ @@ -180,6 +183,8 @@ typedef enum { GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2), GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3), GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4), + + GIT_CHECKOUT_NOTIFY_ALL = 0x0FFFFu } git_checkout_notify_t; /** Checkout notification callback function */ @@ -231,6 +236,8 @@ typedef struct git_checkout_opts { git_strarray paths; git_tree *baseline; /** expected content of workdir, defaults to HEAD */ + + const char *target_directory; /** alternative checkout path to workdir */ } git_checkout_opts; #define GIT_CHECKOUT_OPTS_VERSION 1 diff --git a/include/git2/clone.h b/include/git2/clone.h index 20df49104..5858b4e32 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -51,6 +51,8 @@ GIT_BEGIN_DECL * - `cred_acquire_cb` is a callback to be used if credentials are required * during the initial fetch. * - `cred_acquire_payload` is the payload for the above callback. + * - `transport_flags` is flags used to create transport if no transport is + * provided. * - `transport` is a custom transport to be used for the initial fetch. NULL * means use the transport autodetected from the URL. * - `remote_callbacks` may be used to specify custom progress callbacks for @@ -75,6 +77,7 @@ typedef struct git_clone_options { const char *push_spec; git_cred_acquire_cb cred_acquire_cb; void *cred_acquire_payload; + git_transport_flags_t transport_flags; git_transport *transport; git_remote_callbacks *remote_callbacks; git_remote_autotag_option_t remote_autotag; diff --git a/include/git2/commit.h b/include/git2/commit.h index 764053eaa..544d21d87 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -30,10 +30,7 @@ GIT_BEGIN_DECL * an annotated tag it will be peeled back to the commit. * @return 0 or an error code */ -GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)commit, repo, id, GIT_OBJ_COMMIT); -} +GIT_EXTERN(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id); /** * Lookup a commit object from a repository, @@ -48,10 +45,7 @@ GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, con * @param len the length of the short identifier * @return 0 or an error code */ -GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)commit, repo, id, len, GIT_OBJ_COMMIT); -} +GIT_EXTERN(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len); /** * Close an open commit @@ -65,10 +59,7 @@ GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *re * @param commit the commit to close */ -GIT_INLINE(void) git_commit_free(git_commit *commit) -{ - git_object_free((git_object *) commit); -} +GIT_EXTERN(void) git_commit_free(git_commit *commit); /** * Get the id of a commit. @@ -76,10 +67,15 @@ GIT_INLINE(void) git_commit_free(git_commit *commit) * @param commit a previously loaded commit. * @return object identity for the commit. */ -GIT_INLINE(const git_oid *) git_commit_id(const git_commit *commit) -{ - return git_object_id((const git_object *)commit); -} +GIT_EXTERN(const git_oid *) git_commit_id(const git_commit *commit); + +/** + * Get the repository that contains the commit. + * + * @param commit A previously loaded commit. + * @return Repository that contains this commit. + */ +GIT_EXTERN(git_repository *) git_commit_owner(const git_commit *commit); /** * Get the encoding for the message of a commit, @@ -168,7 +164,10 @@ GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit); * @param n the position of the parent (from 0 to `parentcount`) * @return 0 or an error code */ -GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n); +GIT_EXTERN(int) git_commit_parent( + git_commit **out, + const git_commit *commit, + unsigned int n); /** * Get the oid of a specified parent for a commit. This is different from @@ -179,7 +178,9 @@ GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned * @param n the position of the parent (from 0 to `parentcount`) * @return the id of the parent, NULL on error. */ -GIT_EXTERN(const git_oid *) git_commit_parent_id(git_commit *commit, unsigned int n); +GIT_EXTERN(const git_oid *) git_commit_parent_id( + const git_commit *commit, + unsigned int n); /** * Get the commit object that is the <n>th generation ancestor @@ -201,14 +202,12 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( unsigned int n); /** - * Create a new commit in the repository using `git_object` - * instances as parameters. + * Create new commit in the repository from a list of `git_object` pointers * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. + * The message will not be cleaned up automatically. You can do that with + * the `git_message_prettify()` function. * - * @param id Pointer where to store the OID of the - * newly created commit + * @param id Pointer in which to store the OID of the newly created commit * * @param repo Repository where to store the commit * @@ -219,73 +218,69 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor( * make it point to this commit. If the reference doesn't * exist yet, it will be created. * - * @param author Signature representing the author and the authory - * time of this commit + * @param author Signature with author and author time of commit * - * @param committer Signature representing the committer and the - * commit time of this commit + * @param committer Signature with committer and * commit time of commit * * @param message_encoding The encoding for the message in the - * commit, represented with a standard encoding name. - * E.g. "UTF-8". If NULL, no encoding header is written and - * UTF-8 is assumed. + * commit, represented with a standard encoding name. + * E.g. "UTF-8". If NULL, no encoding header is written and + * UTF-8 is assumed. * * @param message Full message for this commit * * @param tree An instance of a `git_tree` object that will - * be used as the tree for the commit. This tree object must - * also be owned by the given `repo`. + * be used as the tree for the commit. This tree object must + * also be owned by the given `repo`. * * @param parent_count Number of parents for this commit * - * @param parents[] Array of `parent_count` pointers to `git_commit` - * objects that will be used as the parents for this commit. This - * array may be NULL if `parent_count` is 0 (root commit). All the - * given commits must be owned by the `repo`. + * @param parents Array of `parent_count` pointers to `git_commit` + * objects that will be used as the parents for this commit. This + * array may be NULL if `parent_count` is 0 (root commit). All the + * given commits must be owned by the `repo`. * * @return 0 or an error code * The created commit will be written to the Object Database and * the given reference will be updated to point to it */ GIT_EXTERN(int) git_commit_create( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]); + git_oid *id, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + const git_commit *parents[]); /** - * Create a new commit in the repository using a variable - * argument list. + * Create new commit in the repository using a variable argument list. * - * The message will be cleaned up from excess whitespace - * it will be made sure that the last line ends with a '\n'. + * The message will be cleaned up from excess whitespace and it will be made + * sure that the last line ends with a '\n'. * - * The parents for the commit are specified as a variable - * list of pointers to `const git_commit *`. Note that this - * is a convenience method which may not be safe to export - * for certain languages or compilers + * The parents for the commit are specified as a variable list of pointers + * to `const git_commit *`. Note that this is a convenience method which may + * not be safe to export for certain languages or compilers * - * All other parameters remain the same + * All other parameters remain the same at `git_commit_create()`. * * @see git_commit_create */ GIT_EXTERN(int) git_commit_create_v( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...); + git_oid *id, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + ...); /** @} */ GIT_END_DECL diff --git a/include/git2/common.h b/include/git2/common.h index 5318e66b7..b52e13918 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -103,10 +103,10 @@ GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev); /** * Combinations of these values describe the capabilities of libgit2. */ -enum { +typedef enum { GIT_CAP_THREADS = ( 1 << 0 ), GIT_CAP_HTTPS = ( 1 << 1 ) -}; +} git_cap_t; /** * Query compile time options for libgit2. @@ -114,69 +114,100 @@ enum { * @return A combination of GIT_CAP_* values. * * - GIT_CAP_THREADS - * Libgit2 was compiled with thread support. Note that thread support is still to be seen as a - * 'work in progress'. + * Libgit2 was compiled with thread support. Note that thread support is + * still to be seen as a 'work in progress' - basic object lookups are + * believed to be threadsafe, but other operations may not be. * * - GIT_CAP_HTTPS - * Libgit2 supports the https:// protocol. This requires the open ssl library to be - * found when compiling libgit2. + * Libgit2 supports the https:// protocol. This requires the openssl + * library to be found when compiling libgit2. */ GIT_EXTERN(int) git_libgit2_capabilities(void); -enum { +typedef enum { GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE, GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH, - GIT_OPT_GET_ODB_CACHE_SIZE, - GIT_OPT_SET_ODB_CACHE_SIZE, -}; + GIT_OPT_SET_CACHE_OBJECT_LIMIT, + GIT_OPT_SET_CACHE_MAX_SIZE, + GIT_OPT_ENABLE_CACHING, + GIT_OPT_GET_CACHED_MEMORY +} git_libgit2_opt_t; /** * Set or query a library global option * * Available options: * - * opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *): - * Get the maximum mmap window size + * * opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *): * - * opts(GIT_OPT_SET_MWINDOW_SIZE, size_t): - * Set the maximum mmap window size + * > Get the maximum mmap window size * - * opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *): - * Get the maximum memory that will be mapped in total by the library + * * opts(GIT_OPT_SET_MWINDOW_SIZE, size_t): * - * opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t): - * Set the maximum amount of memory that can be mapped at any time + * > Set the maximum mmap window size + * + * * opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *): + * + * > Get the maximum memory that will be mapped in total by the library + * + * * opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t): + * + * >Set the maximum amount of memory that can be mapped at any time * by the library * - * opts(GIT_OPT_GET_SEARCH_PATH, int level, char *out, size_t len) - * Get the search path for a given level of config data. "level" must - * be one of GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, or - * GIT_CONFIG_LEVEL_XDG. The search path is written to the `out` - * buffer up to size `len`. Returns GIT_EBUFS if buffer is too small. - * - * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path) - * Set the search path for a level of config data. The search path - * applied to shared attributes and ignore files, too. - * - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR. - * Pass NULL to reset to the default (generally based on environment - * variables). Use magic path `$PATH` to include the old value - * of the path (if you want to prepend or append, for instance). - * - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, - * or GIT_CONFIG_LEVEL_XDG. - * - * opts(GIT_OPT_GET_ODB_CACHE_SIZE): - * Get the size of the libgit2 odb cache. - * - * opts(GIT_OPT_SET_ODB_CACHE_SIZE): - * Set the size of the of the libgit2 odb cache. This needs - * to be done before git_repository_open is called, since - * git_repository_open initializes the odb layer. Defaults - * to 128. + * * opts(GIT_OPT_GET_SEARCH_PATH, int level, char *out, size_t len) + * + * > Get the search path for a given level of config data. "level" must + * > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, or + * > `GIT_CONFIG_LEVEL_XDG`. The search path is written to the `out` + * > buffer up to size `len`. Returns GIT_EBUFS if buffer is too small. + * + * * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path) + * + * > Set the search path for a level of config data. The search path + * > applied to shared attributes and ignore files, too. + * > + * > - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR. + * > Pass NULL to reset to the default (generally based on environment + * > variables). Use magic path `$PATH` to include the old value + * > of the path (if you want to prepend or append, for instance). + * > + * > - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, + * > or GIT_CONFIG_LEVEL_XDG. + * + * * opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size) + * + * > Set the maximum data size for the given type of object to be + * > considered eligible for caching in memory. Setting to value to + * > zero means that that type of object will not be cached. + * > Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache blobs) and 4k + * > for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG. + * + * * opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes) + * + * > Set the maximum total data size that will be cached in memory + * > across all repositories before libgit2 starts evicting objects + * > from the cache. This is a soft limit, in that the library might + * > briefly exceed it, but will start aggressively evicting objects + * > from cache when that happens. The default cache size is 256Mb. + * + * * opts(GIT_OPT_ENABLE_CACHING, int enabled) + * + * > Enable or disable caching completely. + * > + * > Because caches are repository-specific, disabling the cache + * > cannot immediately clear all cached objects, but each cache will + * > be cleared on the next attempt to update anything in it. + * + * * opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed) + * + * > Get the current bytes in cache and the maximum that would be + * > allowed in the cache. * * @param option Option key * @param ... value to set the option diff --git a/include/git2/config.h b/include/git2/config.h index 19d4cb78d..827d43544 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -27,45 +27,41 @@ GIT_BEGIN_DECL * git_config_open_default() and git_repository_config() honor those * priority levels as well. */ -enum { - GIT_CONFIG_LEVEL_SYSTEM = 1, /**< System-wide configuration file. */ - GIT_CONFIG_LEVEL_XDG = 2, /**< XDG compatible configuration file (.config/git/config). */ - GIT_CONFIG_LEVEL_GLOBAL = 3, /**< User-specific configuration file, also called Global configuration file. */ - GIT_CONFIG_LEVEL_LOCAL = 4, /**< Repository specific configuration file. */ - GIT_CONFIG_HIGHEST_LEVEL = -1, /**< Represents the highest level of a config file. */ -}; +typedef enum { + /** System-wide configuration file; /etc/gitconfig on Linux systems */ + GIT_CONFIG_LEVEL_SYSTEM = 1, + + /** XDG compatible configuration file; typically ~/.config/git/config */ + GIT_CONFIG_LEVEL_XDG = 2, + + /** User-specific configuration file (also called Global configuration + * file); typically ~/.gitconfig + */ + GIT_CONFIG_LEVEL_GLOBAL = 3, + + /** Repository specific configuration file; $WORK_DIR/.git/config on + * non-bare repos + */ + GIT_CONFIG_LEVEL_LOCAL = 4, + + /** Application specific configuration file; freely defined by applications + */ + GIT_CONFIG_LEVEL_APP = 5, + + /** Represents the highest level available config file (i.e. the most + * specific config file available that actually is loaded) + */ + GIT_CONFIG_HIGHEST_LEVEL = -1, +} git_config_level_t; typedef struct { const char *name; const char *value; - unsigned int level; + git_config_level_t 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_backend { - unsigned int version; - struct git_config *cfg; - - /* Open means open the file/database and parse if necessary */ - 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, GIT_CVAR_TRUE = 1, @@ -123,7 +119,7 @@ GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length); * If /etc/gitconfig doesn't exist, it will look for * %PROGRAMFILES%\Git\etc\gitconfig. - * @param global_config_path Buffer to store the path in + * @param out 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`. @@ -154,30 +150,6 @@ GIT_EXTERN(int) git_config_open_default(git_config **out); GIT_EXTERN(int) git_config_new(git_config **out); /** - * Add a generic config file instance to an existing config - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority level will be accessed first). - * - * @param cfg the configuration to add the file to - * @param file the configuration file (backend) to add - * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it - * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), or error code - */ -GIT_EXTERN(int) git_config_add_backend( - git_config *cfg, - git_config_backend *file, - unsigned int level, - int force); - -/** * Add an on-disk config file instance to an existing config * * The on-disk file pointed at by `path` will be opened and @@ -192,10 +164,9 @@ GIT_EXTERN(int) git_config_add_backend( * a higher priority level will be accessed first). * * @param cfg the configuration to add the file to - * @param path path to the configuration file (backend) to add + * @param path path to the configuration file to add * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it + * @param force replace config file at the given priority level * @return 0 on success, GIT_EEXISTS when adding more than one file * for a given priority level (and force_replace set to 0), * GIT_ENOTFOUND when the file doesn't exist or error code @@ -203,7 +174,7 @@ GIT_EXTERN(int) git_config_add_backend( GIT_EXTERN(int) git_config_add_file_ondisk( git_config *cfg, const char *path, - unsigned int level, + git_config_level_t level, int force); /** @@ -238,9 +209,24 @@ GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path); * multi-level parent config, or an error code */ GIT_EXTERN(int) git_config_open_level( - git_config **out, - const git_config *parent, - unsigned int level); + git_config **out, + const git_config *parent, + git_config_level_t level); + +/** + * Open the global/XDG configuration file according to git's rules + * + * Git allows you to store your global configuration at + * `$HOME/.config` or `$XDG_CONFIG_HOME/git/config`. For backwards + * compatability, the XDG file shouldn't be used unless the use has + * created it explicitly. With this function you'll open the correct + * one to write to. + * + * @param out pointer in which to store the config object + * @param config the config object in which to look + */ +GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config); + /** * Reload changed config files @@ -274,7 +260,7 @@ GIT_EXTERN(void) git_config_free(git_config *cfg); * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_entry( - const git_config_entry **out, + const git_config_entry **out, const git_config *cfg, const char *name); @@ -349,8 +335,8 @@ GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, c * @param name the variable's name * @param regexp regular expression to filter which variables we're * interested in. Use NULL to indicate all - * @param fn the function to be called on each value of the variable - * @param data opaque pointer to pass to the callback + * @param callback the function to be called on each value of the variable + * @param payload opaque pointer to pass to the callback */ GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); @@ -492,11 +478,11 @@ GIT_EXTERN(int) git_config_foreach_match( * @return 0 on success, error code otherwise */ GIT_EXTERN(int) git_config_get_mapped( - int *out, - const git_config *cfg, - const char *name, - const git_cvar_map *maps, - size_t map_n); + 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 diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h index e3eb91d6c..5d93cf4dd 100644 --- a/include/git2/cred_helpers.h +++ b/include/git2/cred_helpers.h @@ -30,11 +30,11 @@ typedef struct git_cred_userpass_payload { /** * Stock callback usable as a git_cred_acquire_cb. This calls * git_cred_userpass_plaintext_new unless the protocol has not specified - * GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type. + * `GIT_CREDTYPE_USERPASS_PLAINTEXT` as an allowed type. * * @param cred The newly created credential object. * @param url The resource for which we are demanding a credential. - * @param username_from_url The username that was embedded in a "user@host" + * @param user_from_url The username that was embedded in a "user@host" * remote url, or NULL if not included. * @param allowed_types A bitmask stating which cred types are OK to return. * @param payload The payload provided when specifying this callback. (This is diff --git a/include/git2/diff.h b/include/git2/diff.h index d9ceadf20..43029c49c 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -88,42 +88,69 @@ typedef enum { GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), /** Include unmodified files in the diff list */ GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), - /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked directory - * will be marked with only a single entry in the diff list; this flag - * adds all files under the directory as UNTRACKED entries, too. + + /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked + * directory will be marked with only a single entry in the diff list + * (a la what core Git does in `git status`); this flag adds *all* + * files under untracked directories as UNTRACKED entries, too. */ GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), + /** If the pathspec is set in the diff options, this flags means to * apply it as an exact match instead of as an fnmatch pattern. */ GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), + /** Use case insensitive filename comparisons */ GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12), - /** When generating patch text, include the content of untracked files */ + + /** When generating patch text, include the content of untracked + * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but + * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that + * flag if you want the content of every single UNTRACKED file. + */ GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13), + /** Disable updating of the `binary` flag in delta records. This is * useful when iterating over a diff if you don't need hunk and data * callbacks and want to avoid having to load file completely. */ GIT_DIFF_SKIP_BINARY_CHECK = (1 << 14), + /** Normally, a type change between files will be converted into a * DELETED record for the old and an ADDED record for the new; this * options enabled the generation of TYPECHANGE delta records. */ GIT_DIFF_INCLUDE_TYPECHANGE = (1 << 15), + /** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still * generally show as a DELETED blob. This flag tries to correctly * label blob->tree transitions as TYPECHANGE records with new_file's * mode set to tree. Note: the tree SHA will not be available. */ GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16), + /** Ignore file mode changes */ GIT_DIFF_IGNORE_FILEMODE = (1 << 17), + /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory * will be marked with only a single entry in the diff list; this flag * adds all files under the directory as IGNORED entries, too. */ GIT_DIFF_RECURSE_IGNORED_DIRS = (1 << 18), + + /** Core Git scans inside untracked directories, labeling them IGNORED + * if they are empty or only contain ignored files; a directory is + * consider UNTRACKED only if it has an actual untracked file in it. + * This scan is extra work for a case you often don't care about. This + * flag makes libgit2 immediately label an untracked directory as + * UNTRACKED without looking inside it (which differs from core Git). + * Of course, ignore rules are still checked for the directory itself. + */ + GIT_DIFF_FAST_UNTRACKED_DIRS = (1 << 19), + + /** Treat all files as binary, disabling text diffs */ + GIT_DIFF_FORCE_BINARY = (1 << 20), } git_diff_option_t; /** @@ -224,6 +251,19 @@ typedef struct { * `NOT_BINARY` flag set to avoid examining file contents if you do not pass * in hunk and/or line callbacks to the diff foreach iteration function. It * will just use the git attributes for those files. + * + * The similarity score is zero unless you call `git_diff_find_similar()` + * which does a similarity analysis of files in the diff. Use that + * function to do rename and copy detection, and to split heavily modified + * files in add/delete pairs. After that call, deltas with a status of + * GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score + * between 0 and 100 indicating how similar the old and new sides are. + * + * If you ask `git_diff_find_similar` to find heavily modified files to + * break, but to not *actually* break the records, then GIT_DELTA_MODIFIED + * records may have a non-zero similarity score if the self-similarity is + * below the split threshold. To display this value like core Git, invert + * the score (a la `printf("M%03d", 100 - delta->similarity)`). */ typedef struct { git_diff_file old_file; @@ -337,8 +377,10 @@ typedef enum { 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 */ + + GIT_DIFF_LINE_CONTEXT_EOFNL = '=', /**< Both files have no LF at end */ + GIT_DIFF_LINE_ADD_EOFNL = '>', /**< Old has no LF at end, new does */ + GIT_DIFF_LINE_DEL_EOFNL = '<', /**< Old has LF at end, new does not */ /* The following values will only be sent to a `git_diff_data_cb` when * the content of a diff is being formatted (eg. through @@ -387,18 +429,28 @@ typedef enum { /** 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), + /** mark large rewrites for split (`--break-rewrites=/M`) */ + GIT_DIFF_FIND_REWRITES = (1 << 4), + /** actually split large rewrites into delete/add pairs */ + GIT_DIFF_BREAK_REWRITES = (1 << 5), + /** mark rewrites for split and break into delete/add pairs */ + GIT_DIFF_FIND_AND_BREAK_REWRITES = + (GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES), + + /** find renames/copies for untracked items in working directory */ + GIT_DIFF_FIND_FOR_UNTRACKED = (1 << 6), /** turn on all finding features */ - GIT_DIFF_FIND_ALL = (0x1f), + GIT_DIFF_FIND_ALL = (0x0ff), /** measure similarity ignoring leading whitespace (default) */ GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0, /** measure similarity ignoring all whitespace */ - GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 6), + GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 12), /** measure similarity including all data */ - GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 7), + GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13), + /** measure similarity only by comparing SHAs (fast and cheap) */ + GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14), } git_diff_find_t; /** @@ -425,7 +477,10 @@ typedef struct { * - `copy_threshold` is the same as the -C option with a value * - `rename_from_rewrite_threshold` matches the top of the -B option * - `break_rewrite_threshold` matches the bottom of the -B option - * - `target_limit` matches the -l option + * - `rename_limit` is the maximum number of matches to consider for + * a particular file. This is a little different from the `-l` option + * to regular Git because we will still process up to this many matches + * before abandoning the search. * * The `metric` option allows you to plug in a custom similarity metric. * Set it to NULL for the default internal metric which is based on sampling @@ -437,21 +492,21 @@ typedef struct { unsigned int version; /** Combination of git_diff_find_t values (default FIND_RENAMES) */ - unsigned int flags; + uint32_t flags; /** Similarity to consider a file renamed (default 50) */ - unsigned int rename_threshold; + uint16_t rename_threshold; /** Similarity of modified to be eligible rename source (default 50) */ - unsigned int rename_from_rewrite_threshold; + uint16_t rename_from_rewrite_threshold; /** Similarity to consider a file a copy (default 50) */ - unsigned int copy_threshold; + uint16_t copy_threshold; /** Similarity to split modify into delete/add pair (default 60) */ - unsigned int break_rewrite_threshold; + uint16_t break_rewrite_threshold; - /** Maximum similarity sources to examine (a la diff's `-l` option or - * the `diff.renameLimit` config) (default 200) + /** Maximum similarity sources to examine for a file (somewhat like + * git-diff's `-l` option or `diff.renameLimit` config) (default 200) */ - unsigned int target_limit; + size_t rename_limit; /** Pluggable similarity metric; pass NULL to use internal metric */ git_diff_similarity_metric *metric; @@ -469,6 +524,8 @@ typedef struct { /** * Deallocate a diff list. + * + * @param diff The previously created diff list; cannot be used after free. */ GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); @@ -478,12 +535,14 @@ GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); * This is equivalent to `git diff <old-tree> <new-tree>` * * The first tree will be used for the "old_file" side of the delta and the - * second tree will be used for the "new_file" side of the delta. + * second tree will be used for the "new_file" side of the delta. You can + * pass NULL to indicate an empty tree, although it is an error to pass + * NULL for both the `old_tree` and `new_tree`. * * @param diff Output pointer to a git_diff_list pointer to be allocated. * @param repo The repository containing the trees. - * @param old_tree A git_tree object to diff from. - * @param new_tree A git_tree object to diff to. + * @param old_tree A git_tree object to diff from, or NULL for empty tree. + * @param new_tree A git_tree object to diff to, or NULL for empty tree. * @param opts Structure with options to influence diff or NULL for defaults. */ GIT_EXTERN(int) git_diff_tree_to_tree( @@ -504,7 +563,7 @@ GIT_EXTERN(int) git_diff_tree_to_tree( * * @param diff Output pointer to a git_diff_list pointer to be allocated. * @param repo The repository containing the tree and index. - * @param old_tree A git_tree object to diff from. + * @param old_tree A git_tree object to diff from, or NULL for empty tree. * @param index The index to diff with; repo index used if NULL. * @param opts Structure with options to influence diff or NULL for defaults. */ @@ -563,7 +622,7 @@ GIT_EXTERN(int) git_diff_index_to_workdir( * * @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 old_tree A git_tree object to diff from, or NULL for empty tree. * @param opts Structure with options to influence diff or NULL for defaults. */ GIT_EXTERN(int) git_diff_tree_to_workdir( @@ -664,6 +723,22 @@ GIT_EXTERN(int) git_diff_print_compact( void *payload); /** + * Iterate over a diff generating text output like "git diff --raw". + * + * Returning a non-zero value from the callbacks will terminate the + * iteration and cause this return `GIT_EUSER`. + * + * @param diff A git_diff_list generated by one of the above functions. + * @param print_cb Callback to make per line of diff text. + * @param payload Reference pointer that will be passed to your callback. + * @return 0 on success, GIT_EUSER on non-zero callback, or error code + */ +GIT_EXTERN(int) git_diff_print_raw( + git_diff_list *diff, + git_diff_data_cb print_cb, + void *payload); + +/** * Look up the single character abbreviation for a delta status code. * * When you call `git_diff_print_compact` it prints single letter codes into @@ -672,7 +747,7 @@ GIT_EXTERN(int) git_diff_print_compact( * letters for your own purposes. This function does just that. By the * way, unmodified will return a space (i.e. ' '). * - * @param delta_t The git_delta_t value to look up + * @param status The git_delta_t value to look up * @return The single character label for that code */ GIT_EXTERN(char) git_diff_status_char(git_delta_t status); @@ -785,7 +860,7 @@ GIT_EXTERN(size_t) git_diff_patch_num_hunks( * @param total_additions Count of addition lines in output, can be NULL. * @param total_deletions Count of deletion lines in output, can be NULL. * @param patch The git_diff_patch object - * @return Number of lines in hunk or -1 if invalid hunk index + * @return 0 on success, <0 on error */ GIT_EXTERN(int) git_diff_patch_line_stats( size_t *total_context, @@ -843,7 +918,7 @@ GIT_EXTERN(int) git_diff_patch_num_lines_in_hunk( * @param new_lineno Line number in new file or -1 if line is deleted * @param patch The patch to look in * @param hunk_idx The index of the hunk - * @param line_of_index The index of the line in the hunk + * @param line_of_hunk The index of the line in the hunk * @return 0 on success, <0 on failure */ GIT_EXTERN(int) git_diff_patch_get_line_in_hunk( @@ -907,11 +982,22 @@ GIT_EXTERN(int) git_diff_patch_to_str( * to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass * `GIT_DIFF_FORCE_TEXT` of course). * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code + * @param old_blob Blob for old side of diff, or NULL for empty blob + * @param old_as_path Treat old blob as if it had this filename; can be NULL + * @param new_blob Blob for new side of diff, or NULL for empty blob + * @param new_as_path Treat new blob as if it had this filename; can be NULL + * @param options Options for diff, or NULL for default options + * @param file_cb Callback for "file"; made once if there is a diff; can be NULL + * @param hunk_cb Callback for each hunk in diff; can be NULL + * @param line_cb Callback for each line in diff; can be NULL + * @param payload Payload passed to each callback function + * @return 0 on success, GIT_EUSER on non-zero callback return, or error code */ GIT_EXTERN(int) git_diff_blobs( const git_blob *old_blob, + const char *old_as_path, const git_blob *new_blob, + const char *new_as_path, const git_diff_options *options, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, @@ -919,6 +1005,30 @@ GIT_EXTERN(int) git_diff_blobs( void *payload); /** + * Directly generate a patch from the difference between two blobs. + * + * This is just like `git_diff_blobs()` except it generates a patch object + * for the difference instead of directly making callbacks. You can use the + * standard `git_diff_patch` accessor functions to read the patch data, and + * you must call `git_diff_patch_free()` on the patch when done. + * + * @param out The generated patch; NULL on error + * @param old_blob Blob for old side of diff, or NULL for empty blob + * @param old_as_path Treat old blob as if it had this filename; can be NULL + * @param new_blob Blob for new side of diff, or NULL for empty blob + * @param new_as_path Treat new blob as if it had this filename; can be NULL + * @param opts Options for diff, or NULL for default options + * @return 0 on success or error code < 0 + */ +GIT_EXTERN(int) git_diff_patch_from_blobs( + git_diff_patch **out, + const git_blob *old_blob, + const char *old_as_path, + const git_blob *new_blob, + const char *new_as_path, + const git_diff_options *opts); + +/** * Directly run a diff between a blob and a buffer. * * As with `git_diff_blobs`, comparing a blob and buffer lacks some context, @@ -930,18 +1040,57 @@ GIT_EXTERN(int) git_diff_blobs( * entire content of the buffer added). Passing NULL to the buffer will do * the reverse, with GIT_DELTA_REMOVED and blob content removed. * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code + * @param old_blob Blob for old side of diff, or NULL for empty blob + * @param old_as_path Treat old blob as if it had this filename; can be NULL + * @param buffer Raw data for new side of diff, or NULL for empty + * @param buffer_len Length of raw data for new side of diff + * @param buffer_as_path Treat buffer as if it had this filename; can be NULL + * @param options Options for diff, or NULL for default options + * @param file_cb Callback for "file"; made once if there is a diff; can be NULL + * @param hunk_cb Callback for each hunk in diff; can be NULL + * @param data_cb Callback for each line in diff; can be NULL + * @param payload Payload passed to each callback function + * @return 0 on success, GIT_EUSER on non-zero callback return, or error code */ GIT_EXTERN(int) git_diff_blob_to_buffer( const git_blob *old_blob, + const char *old_as_path, const char *buffer, size_t buffer_len, + const char *buffer_as_path, const git_diff_options *options, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, git_diff_data_cb data_cb, void *payload); +/** + * Directly generate a patch from the difference between a blob and a buffer. + * + * This is just like `git_diff_blob_to_buffer()` except it generates a patch + * object for the difference instead of directly making callbacks. You can + * use the standard `git_diff_patch` accessor functions to read the patch + * data, and you must call `git_diff_patch_free()` on the patch when done. + * + * @param out The generated patch; NULL on error + * @param old_blob Blob for old side of diff, or NULL for empty blob + * @param old_as_path Treat old blob as if it had this filename; can be NULL + * @param buffer Raw data for new side of diff, or NULL for empty + * @param buffer_len Length of raw data for new side of diff + * @param buffer_as_path Treat buffer as if it had this filename; can be NULL + * @param opts Options for diff, or NULL for default options + * @return 0 on success or error code < 0 + */ +GIT_EXTERN(int) git_diff_patch_from_blob_and_buffer( + git_diff_patch **out, + const git_blob *old_blob, + const char *old_as_path, + const char *buffer, + size_t buffer_len, + const char *buffer_as_path, + const git_diff_options *opts); + + GIT_END_DECL /** @} */ diff --git a/include/git2/errors.h b/include/git2/errors.h index 917f0699c..2032a436a 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -18,7 +18,7 @@ GIT_BEGIN_DECL /** Generic return codes */ -enum { +typedef enum { GIT_OK = 0, GIT_ERROR = -1, GIT_ENOTFOUND = -3, @@ -35,7 +35,7 @@ enum { GIT_PASSTHROUGH = -30, GIT_ITEROVER = -31, -}; +} git_error_code; typedef struct { char *message; @@ -100,7 +100,7 @@ GIT_EXTERN(void) giterr_clear(void); * * @param error_class One of the `git_error_t` enum above describing the * general subsystem that is responsible for the error. - * @param message The formatted error message to keep + * @param string The formatted error message to keep */ GIT_EXTERN(void) giterr_set_str(int error_class, const char *string); diff --git a/include/git2/index.h b/include/git2/index.h index 3d4bd15a8..51694aded 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -11,6 +11,7 @@ #include "indexer.h" #include "types.h" #include "oid.h" +#include "strarray.h" /** * @file git2/index.h @@ -21,50 +22,29 @@ */ GIT_BEGIN_DECL -#define GIT_IDXENTRY_NAMEMASK (0x0fff) -#define GIT_IDXENTRY_STAGEMASK (0x3000) -#define GIT_IDXENTRY_EXTENDED (0x4000) -#define GIT_IDXENTRY_VALID (0x8000) -#define GIT_IDXENTRY_STAGESHIFT 12 - -/* - * Flags are divided into two parts: in-memory flags and - * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS - * will get saved on-disk. - * - * 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_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_NEW_SKIP_WORKTREE (1 << 9) - -/* - * Extended on-disk flags: - */ -#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_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) - -/** Time used in a git index entry */ +/** Time structure used in a git index entry */ typedef struct { git_time_t seconds; /* nsec should not be stored as time_t compatible */ unsigned int nanoseconds; } git_index_time; -/** Memory representation of a file entry in the index. */ +/** + * In-memory representation of a file entry in the index. + * + * This is a public structure that represents a file entry in the index. + * The meaning of the fields corresponds to core Git's documentation (in + * "Documentation/technical/index-format.txt"). + * + * The `flags` field consists of a number of bit fields which can be + * accessed via the first set of `GIT_IDXENTRY_...` bitmasks below. These + * flags are all read from and persisted to disk. + * + * The `flags_extended` field also has a number of bit fields which can be + * accessed via the later `GIT_IDXENTRY_...` bitmasks below. Some of + * these flags are read from and written to disk, but some are set aside + * for in-memory only reference. + */ typedef struct git_index_entry { git_index_time ctime; git_index_time mtime; @@ -84,20 +64,79 @@ typedef struct git_index_entry { char *path; } git_index_entry; -/** 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_reuc_entry; +/** + * Bitmasks for on-disk fields of `git_index_entry`'s `flags` + * + * These bitmasks match the four fields in the `git_index_entry` `flags` + * value both in memory and on disk. You can use them to interpret the + * data in the `flags`. + */ +#define GIT_IDXENTRY_NAMEMASK (0x0fff) +#define GIT_IDXENTRY_STAGEMASK (0x3000) +#define GIT_IDXENTRY_EXTENDED (0x4000) +#define GIT_IDXENTRY_VALID (0x8000) +#define GIT_IDXENTRY_STAGESHIFT 12 + +#define GIT_IDXENTRY_STAGE(E) (((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT) + +/** + * Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended` + * + * In memory, the `flags_extended` fields are divided into two parts: the + * fields that are read from and written to disk, and other fields that + * in-memory only and used by libgit2. Only the flags in + * `GIT_IDXENTRY_EXTENDED_FLAGS` will get saved on-disk. + * + * These bitmasks match the three fields in the `git_index_entry` + * `flags_extended` value that belong on disk. You can use them to + * interpret the data in the `flags_extended`. + */ +#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) +#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) +/* GIT_IDXENTRY_EXTENDED2 is reserved for future extension */ +#define GIT_IDXENTRY_EXTENDED2 (1 << 15) + +#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) + +/** + * Bitmasks for in-memory only fields of `git_index_entry`'s `flags_extended` + * + * These bitmasks match the other fields in the `git_index_entry` + * `flags_extended` value that are only used in-memory by libgit2. You + * can use them to interpret the data in the `flags_extended`. + */ +#define GIT_IDXENTRY_UPDATE (1 << 0) +#define GIT_IDXENTRY_REMOVE (1 << 1) +#define GIT_IDXENTRY_UPTODATE (1 << 2) +#define GIT_IDXENTRY_ADDED (1 << 3) + +#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_NEW_SKIP_WORKTREE (1 << 9) /** Capabilities of system that affect index actions. */ -enum { +typedef enum { GIT_INDEXCAP_IGNORE_CASE = 1, GIT_INDEXCAP_NO_FILEMODE = 2, GIT_INDEXCAP_NO_SYMLINKS = 4, GIT_INDEXCAP_FROM_OWNER = ~0u -}; +} git_indexcap_t; + +/** Callback for APIs that add/remove/update files matching pathspec */ +typedef int (*git_index_matched_path_cb)( + const char *path, const char *matched_pathspec, void *payload); + +/** Flags for APIs that add files matching pathspec */ +typedef enum { + GIT_INDEX_ADD_DEFAULT = 0, + GIT_INDEX_ADD_FORCE = (1u << 0), + GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1), + GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2), +} git_index_add_option_t; /** @name Index File Functions * @@ -272,11 +311,9 @@ GIT_EXTERN(void) git_index_clear(git_index *index); /** * 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. + * The entry is not modifiable and should not be freed. Because the + * `git_index_entry` struct is a publicly defined struct, you should + * be able to make your own permanent copy of the data if necessary. * * @param index an existing index object * @param n the position of the entry @@ -288,11 +325,9 @@ GIT_EXTERN(const git_index_entry *) git_index_get_byindex( /** * 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. + * The entry is not modifiable and should not be freed. Because the + * `git_index_entry` struct is a publicly defined struct, you should + * be able to make your own permanent copy of the data if necessary. * * @param index an existing index object * @param path path to search @@ -342,8 +377,7 @@ GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_en /** * Return the stage number from a git index entry * - * This entry is calculated from the entry's flag - * attribute like this: + * This entry is calculated from the entry's flag attribute like this: * * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT * @@ -400,6 +434,108 @@ GIT_EXTERN(int) git_index_add_bypath(git_index *index, const char *path); GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path); /** + * Add or update index entries matching files in the working directory. + * + * This method will fail in bare index instances. + * + * The `pathspec` is a list of file names or shell glob patterns that will + * matched against files in the repository's working directory. Each file + * that matches will be added to the index (either updating an existing + * entry or adding a new entry). You can disable glob expansion and force + * exact matching with the `GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH` flag. + * + * Files that are ignored will be skipped (unlike `git_index_add_bypath`). + * If a file is already tracked in the index, then it *will* be updated + * even if it is ignored. Pass the `GIT_INDEX_ADD_FORCE` flag to + * skip the checking of ignore rules. + * + * To emulate `git add -A` and generate an error if the pathspec contains + * the exact path of an ignored file (when not using FORCE), add the + * `GIT_INDEX_ADD_CHECK_PATHSPEC` flag. This checks that each entry + * in the `pathspec` that is an exact match to a filename on disk is + * either not ignored or already in the index. If this check fails, the + * function will return GIT_EINVALIDSPEC. + * + * To emulate `git add -A` with the "dry-run" option, just use a callback + * function that always returns a positive value. See below for details. + * + * If any files are currently the result of a merge conflict, those files + * will no longer be marked as conflicting. The data about the conflicts + * will be moved to the "resolve undo" (REUC) section. + * + * If you provide a callback function, it will be invoked on each matching + * item in the working directory immediately *before* it is added to / + * updated in the index. Returning zero will add the item to the index, + * greater than zero will skip the item, and less than zero will abort the + * scan and cause GIT_EUSER to be returned. + * + * @param index an existing index object + * @param pathspec array of path patterns + * @param flags combination of git_index_add_option_t flags + * @param callback notification callback for each added/updated path (also + * gets index of matching pathspec entry); can be NULL; + * return 0 to add, >0 to skip, <0 to abort scan. + * @param payload payload passed through to callback function + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_add_all( + git_index *index, + const git_strarray *pathspec, + unsigned int flags, + git_index_matched_path_cb callback, + void *payload); + +/** + * Remove all matching index entries. + * + * If you provide a callback function, it will be invoked on each matching + * item in the index immediately *before* it is removed. Return 0 to + * remove the item, > 0 to skip the item, and < 0 to abort the scan. + * + * @param index An existing index object + * @param pathspec array of path patterns + * @param callback notification callback for each removed path (also + * gets index of matching pathspec entry); can be NULL; + * return 0 to add, >0 to skip, <0 to abort scan. + * @param payload payload passed through to callback function + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_remove_all( + git_index *index, + const git_strarray *pathspec, + git_index_matched_path_cb callback, + void *payload); + +/** + * Update all index entries to match the working directory + * + * This method will fail in bare index instances. + * + * This scans the existing index entries and synchronizes them with the + * working directory, deleting them if the corresponding working directory + * file no longer exists otherwise updating the information (including + * adding the latest version of file to the ODB if needed). + * + * If you provide a callback function, it will be invoked on each matching + * item in the index immediately *before* it is updated (either refreshed + * or removed depending on working directory state). Return 0 to proceed + * with updating the item, > 0 to skip the item, and < 0 to abort the scan. + * + * @param index An existing index object + * @param pathspec array of path patterns + * @param callback notification callback for each updated path (also + * gets index of matching pathspec entry); can be NULL; + * return 0 to add, >0 to skip, <0 to abort scan. + * @param payload payload passed through to callback function + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_update_all( + git_index *index, + const git_strarray *pathspec, + git_index_matched_path_cb callback, + void *payload); + +/** * Find the first position of any entries which point to given * path in the Git index. * @@ -434,7 +570,7 @@ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *pat * @return 0 or an error code */ GIT_EXTERN(int) git_index_conflict_add( - git_index *index, + git_index *index, const git_index_entry *ancestor_entry, const git_index_entry *our_entry, const git_index_entry *their_entry); @@ -442,9 +578,9 @@ GIT_EXTERN(int) git_index_conflict_add( /** * 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. + * The entries are not modifiable and should not be freed. Because the + * `git_index_entry` struct is a publicly defined struct, you should + * be able to make your own permanent copy of the data if necessary. * * @param ancestor_out Pointer to store the ancestor entry * @param our_out Pointer to store the our entry @@ -452,7 +588,12 @@ GIT_EXTERN(int) git_index_conflict_add( * @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); +GIT_EXTERN(int) git_index_conflict_get( + const git_index_entry **ancestor_out, + const git_index_entry **our_out, + const git_index_entry **their_out, + git_index *index, + const char *path); /** * Removes the index entries that represent a conflict of a single file. @@ -476,101 +617,39 @@ GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index); */ 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. + * Create an iterator for the conflicts in the index. You may not modify the + * index while iterating, the results are undefined. * - * @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 at_pos the address to which the position of the reuc entry is written (optional) - * @param index an existing index object - * @param path path to search - * @return 0 if found, < 0 otherwise (GIT_ENOTFOUND) - */ -GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path); - -/** - * Get a resolve undo entry from the index. - * - * The returned entry is read-only and should not be modified - * or freed by the caller. - * - * @param index an existing index object - * @param path path to search - * @return the resolve undo entry; NULL if not found - */ -GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path); - -/** - * Get a resolve undo entry from the index. - * - * The returned entry is read-only and should not be modified - * or freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the resolve undo entry; NULL if out of bounds - */ -GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n); - -/** - * Adds a resolve undo entry for a file based on the given parameters. - * - * The resolve undo entry contains the OIDs of files that were involved - * in a merge conflict after the conflict has been resolved. This allows - * conflicts to be re-resolved later. - * - * If there exists a resolve undo entry for the given path in the index, - * it will be removed. - * - * This method will fail in bare index instances. - * - * @param index an existing index object - * @param path filename to add - * @param ancestor_mode mode of the ancestor file - * @param ancestor_id oid of the ancestor file - * @param our_mode mode of our file - * @param our_id oid of our file - * @param their_mode mode of their file - * @param their_id oid of their file * @return 0 or an error code */ -GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path, - int ancestor_mode, git_oid *ancestor_id, - int our_mode, git_oid *our_id, - int their_mode, git_oid *their_id); +GIT_EXTERN(int) git_index_conflict_iterator_new( + git_index_conflict_iterator **iterator_out, + git_index *index); /** - * Remove an resolve undo entry from the index + * Returns the current conflict (ancestor, ours and theirs entry) and + * advance the iterator internally to the next value. * - * @param index an existing index object - * @param n position of the resolve undo entry to remove - * @return 0 or an error code + * @param ancestor_out Pointer to store the ancestor side of the conflict + * @param our_out Pointer to store our side of the conflict + * @param their_out Pointer to store their side of the conflict + * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code + * (negative value) */ -GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n); +GIT_EXTERN(int) git_index_conflict_next( + const git_index_entry **ancestor_out, + const git_index_entry **our_out, + const git_index_entry **their_out, + git_index_conflict_iterator *iterator); /** - * Remove all resolve undo entries from the index + * Frees a `git_index_conflict_iterator`. * - * @param index an existing index object - * @return 0 or an error code + * @param iterator pointer to the iterator */ -GIT_EXTERN(void) git_index_reuc_clear(git_index *index); +GIT_EXTERN(void) git_index_conflict_iterator_free( + git_index_conflict_iterator *iterator); /**@}*/ diff --git a/include/git2/indexer.h b/include/git2/indexer.h index dfe6ae5aa..4db072c9b 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -8,31 +8,11 @@ #define _INCLUDE_git_indexer_h__ #include "common.h" +#include "types.h" #include "oid.h" GIT_BEGIN_DECL -/** - * This is passed as the first argument to the callback to allow the - * user to see the progress. - */ -typedef struct git_transfer_progress { - unsigned int total_objects; - unsigned int indexed_objects; - unsigned int received_objects; - size_t received_bytes; -} git_transfer_progress; - - -/** - * Type for progress callbacks during indexing. Return a value less than zero - * to cancel the transfer. - * - * @param stats Structure containing information about the state of the transfer - * @param payload Payload provided by caller - */ -typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload); - typedef struct git_indexer_stream git_indexer_stream; /** @@ -41,7 +21,7 @@ typedef struct git_indexer_stream git_indexer_stream; * @param out where to store the indexer instance * @param path to the directory where the packfile should be stored * @param progress_cb function to call with progress information - * @param progress_payload payload for the progress callback + * @param progress_cb_payload payload for the progress callback */ GIT_EXTERN(int) git_indexer_stream_new( git_indexer_stream **out, diff --git a/include/git2/inttypes.h b/include/git2/inttypes.h index 716084219..17364c7f8 100644 --- a/include/git2/inttypes.h +++ b/include/git2/inttypes.h @@ -283,18 +283,18 @@ _inline #endif // STATIC_IMAXDIV ] imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) { - imaxdiv_t result; + imaxdiv_t result; - result.quot = numer / denom; - result.rem = numer % denom; + result.quot = numer / denom; + result.rem = numer % denom; - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } - return result; + return result; } // 7.8.2.3 The strtoimax and strtoumax functions diff --git a/include/git2/merge.h b/include/git2/merge.h index f4c5d9881..cef6f775b 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -7,20 +7,65 @@ #ifndef INCLUDE_git_merge_h__ #define INCLUDE_git_merge_h__ -#include "common.h" -#include "types.h" -#include "oid.h" +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" +#include "git2/checkout.h" +#include "git2/index.h" /** * @file git2/merge.h - * @brief Git merge-base routines - * @defgroup git_revwalk Git merge-base routines + * @brief Git merge routines + * @defgroup git_merge Git merge routines * @ingroup Git * @{ */ GIT_BEGIN_DECL /** + * Flags for `git_merge_tree` options. A combination of these flags can be + * passed in via the `flags` value in the `git_merge_tree_opts`. + */ +typedef enum { + /** Detect renames */ + GIT_MERGE_TREE_FIND_RENAMES = (1 << 0), +} git_merge_tree_flag_t; + +/** + * Automerge options for `git_merge_trees_opts`. + */ +typedef enum { + GIT_MERGE_AUTOMERGE_NORMAL = 0, + GIT_MERGE_AUTOMERGE_NONE = 1, + GIT_MERGE_AUTOMERGE_FAVOR_OURS = 2, + GIT_MERGE_AUTOMERGE_FAVOR_THEIRS = 3, +} git_merge_automerge_flags; + + +typedef struct { + unsigned int version; + git_merge_tree_flag_t flags; + + /** Similarity to consider a file renamed (default 50) */ + unsigned int rename_threshold; + + /** Maximum similarity sources to examine (overrides the + * `merge.renameLimit` config) (default 200) + */ + unsigned int target_limit; + + /** Pluggable similarity metric; pass NULL to use internal metric */ + git_diff_similarity_metric *metric; + + /** Flags for automerging content. */ + git_merge_automerge_flags automerge_flags; +} git_merge_tree_opts; + +#define GIT_MERGE_TREE_OPTS_VERSION 1 +#define GIT_MERGE_TREE_OPTS_INIT {GIT_MERGE_TREE_OPTS_VERSION} + + +/** * Find a merge base between two commits * * @param out the OID of a merge base between 'one' and 'two' @@ -50,6 +95,79 @@ GIT_EXTERN(int) git_merge_base_many( const git_oid input_array[], size_t length); +/** + * Creates a `git_merge_head` from the given reference + * + * @param out pointer to store the git_merge_head result in + * @param repo repository that contains the given reference + * @param ref reference to use as a merge input + * @return zero on success, -1 on failure. + */ +GIT_EXTERN(int) git_merge_head_from_ref( + git_merge_head **out, + git_repository *repo, + git_reference *ref); + +/** + * Creates a `git_merge_head` from the given fetch head data + * + * @param out pointer to store the git_merge_head result in + * @param repo repository that contains the given commit + * @param branch_name name of the (remote) branch + * @param remote_url url of the remote + * @param oid the commit object id to use as a merge input + * @return zero on success, -1 on failure. + */ +GIT_EXTERN(int) git_merge_head_from_fetchhead( + git_merge_head **out, + git_repository *repo, + const char *branch_name, + const char *remote_url, + const git_oid *oid); + +/** + * Creates a `git_merge_head` from the given commit id + * + * @param out pointer to store the git_merge_head result in + * @param repo repository that contains the given commit + * @param oid the commit object id to use as a merge input + * @return zero on success, -1 on failure. + */ +GIT_EXTERN(int) git_merge_head_from_oid( + git_merge_head **out, + git_repository *repo, + const git_oid *oid); + +/** + * Frees a `git_merge_head` + * + * @param head merge head to free + */ +GIT_EXTERN(void) git_merge_head_free( + git_merge_head *head); + +/** + * Merge two trees, producing a `git_index` that reflects the result of + * the merge. + * + * The returned index must be freed explicitly with `git_index_free`. + * + * @param out pointer to store the index result in + * @param repo repository that contains the given trees + * @param ancestor_tree the common ancestor between the trees (or null if none) + * @param our_tree the tree that reflects the destination tree + * @param their_tree the tree to merge in to `our_tree` + * @param opts the merge tree options (or null for defaults) + * @return zero on success, -1 on failure. + */ +GIT_EXTERN(int) git_merge_trees( + git_index **out, + git_repository *repo, + const git_tree *ancestor_tree, + const git_tree *our_tree, + const git_tree *their_tree, + const git_merge_tree_opts *opts); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/odb.h b/include/git2/odb.h index 8fd1a95be..b64436c4d 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -10,8 +10,6 @@ #include "common.h" #include "types.h" #include "oid.h" -#include "odb_backend.h" -#include "indexer.h" /** * @file git2/odb.h @@ -23,6 +21,11 @@ GIT_BEGIN_DECL /** + * Function type for callbacks from git_odb_foreach. + */ +typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); + +/** * Create a new object database with no backends. * * Before the ODB can be used for read/writing, a custom database @@ -53,42 +56,6 @@ GIT_EXTERN(int) git_odb_new(git_odb **out); GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); /** - * Add a custom backend to an existing Object DB - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Read <odb_backends.h> for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Add a custom backend to an existing Object DB; this - * backend will work as an alternate. - * - * Alternate backends are always checked for objects *after* - * all the main backends have been exhausted. - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Writing is disabled on alternate backends. - * - * Read <odb_backends.h> for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); - -/** * Add an on-disk alternate to an existing Object DB. * * Note that the added path must point to an `objects`, not @@ -406,6 +373,60 @@ GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object); */ GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object); +/** + * Add a custom backend to an existing Object DB + * + * The backends are checked in relative ordering, based on the + * value of the `priority` parameter. + * + * Read <odb_backends.h> for more information. + * + * @param odb database to add the backend to + * @param backend pointer to a git_odb_backend instance + * @param priority Value for ordering the backends queue + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); + +/** + * Add a custom backend to an existing Object DB; this + * backend will work as an alternate. + * + * Alternate backends are always checked for objects *after* + * all the main backends have been exhausted. + * + * The backends are checked in relative ordering, based on the + * value of the `priority` parameter. + * + * Writing is disabled on alternate backends. + * + * Read <odb_backends.h> for more information. + * + * @param odb database to add the backend to + * @param backend pointer to a git_odb_backend instance + * @param priority Value for ordering the backends queue + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); + +/** + * Get the number of ODB backend objects + * + * @param odb object database + * @return number of backends in the ODB + */ +GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb); + +/** + * Lookup an ODB backend object by index + * + * @param out output pointer to ODB backend at pos + * @param odb object database + * @param pos index into object database backend list + * @return 0 on success; GIT_ENOTFOUND if pos is invalid; other errors < 0 + */ +GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index dbc3981f6..af1e3e5b9 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -7,143 +7,84 @@ #ifndef INCLUDE_git_odb_backend_h__ #define INCLUDE_git_odb_backend_h__ -#include "common.h" -#include "types.h" -#include "oid.h" -#include "indexer.h" +#include "git2/common.h" +#include "git2/types.h" /** * @file git2/backend.h * @brief Git custom backend functions - * @defgroup git_backend Git custom backend API + * @defgroup git_odb Git object database routines * @ingroup Git * @{ */ GIT_BEGIN_DECL -struct git_odb_stream; -struct git_odb_writepack; +/* + * Constructors for in-box ODB backends. + */ /** - * Function type for callbacks from git_odb_foreach. + * Create a backend for the packfiles. + * + * @param out location to store the odb backend pointer + * @param objects_dir the Git repository's objects directory + * + * @return 0 or an error code */ -typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); +GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); /** - * An instance for a custom backend + * Create a backend for loose objects + * + * @param out location to store the odb backend pointer + * @param objects_dir the Git repository's objects directory + * @param compression_level zlib compression level to use + * @param do_fsync whether to do an fsync() after writing (currently ignored) + * + * @return 0 or an error code */ -struct git_odb_backend { - unsigned int version; - git_odb *odb; - - /* read and read_prefix each return to libgit2 a buffer which - * will be freed later. The buffer should be allocated using - * the function git_odb_backend_malloc to ensure that it can - * be safely freed later. */ - int (* read)( - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* To find a unique object given a prefix - * of its oid. - * The oid given must be so that the - * remaining (GIT_OID_HEXSZ - len)*4 bits - * are 0s. - */ - int (* read_prefix)( - git_oid *, - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *, - size_t); - - int (* read_header)( - size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* The writer may assume that the object - * has already been hashed and is passed - * in the first parameter. - */ - int (* write)( - git_oid *, - struct git_odb_backend *, - const void *, - size_t, - git_otype); - - int (* writestream)( - struct git_odb_stream **, - struct git_odb_backend *, - size_t, - git_otype); - - int (* readstream)( - struct git_odb_stream **, - struct git_odb_backend *, - const git_oid *); - - int (* exists)( - struct git_odb_backend *, - const git_oid *); - - int (* refresh)(struct git_odb_backend *); - - int (* foreach)( - struct git_odb_backend *, - git_odb_foreach_cb cb, - void *payload); - - int (* writepack)( - struct git_odb_writepack **, - struct git_odb_backend *, - git_transfer_progress_callback progress_cb, - void *progress_payload); - - void (* free)(struct git_odb_backend *); -}; +GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync); -#define GIT_ODB_BACKEND_VERSION 1 -#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} +/** + * Create a backend out of a single packfile + * + * This can be useful for inspecting the contents of a single + * packfile. + * + * @param out location to store the odb backend pointer + * @param index_file path to the packfile's .idx file + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); /** Streaming mode */ -enum { +typedef enum { GIT_STREAM_RDONLY = (1 << 1), GIT_STREAM_WRONLY = (1 << 2), GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), -}; +} git_odb_stream_t; /** A stream to read/write from a backend */ struct git_odb_stream { - struct git_odb_backend *backend; + git_odb_backend *backend; 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); - int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream); - void (*free)(struct git_odb_stream *stream); + int (*read)(git_odb_stream *stream, char *buffer, size_t len); + int (*write)(git_odb_stream *stream, const char *buffer, size_t len); + int (*finalize_write)(git_oid *oid_p, git_odb_stream *stream); + void (*free)(git_odb_stream *stream); }; /** A stream to write a pack file to the ODB */ struct git_odb_writepack { - struct git_odb_backend *backend; + 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); + int (*add)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats); + int (*commit)(git_odb_writepack *writepack, git_transfer_progress *stats); + void (*free)(git_odb_writepack *writepack); }; -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/include/git2/oid.h b/include/git2/oid.h index 862f4b202..662338d93 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -85,11 +85,22 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw); * 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. + * @param id oid structure to format. */ GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id); /** + * Format a git_oid into a partial hex string. + * + * @param out output hex string; you say how many bytes to write. + * If the number of bytes is > GIT_OID_HEXSZ, extra bytes + * will be zeroed; if not, a '\0' terminator is NOT added. + * @param n number of characters to write into out string + * @param id oid structure to format. + */ +GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id); + +/** * Format a git_oid into a loose-object path string. * * The resulting string is "aa/...", where "aa" is the first two @@ -107,7 +118,7 @@ GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id); /** * Format a git_oid into a newly allocated c-string. * - * @param oid the oid structure to format + * @param id the oid structure to format * @return the c-string; NULL if memory is exhausted. Caller must * deallocate the string with git__free(). */ @@ -117,10 +128,12 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id); * Format a git_oid into a buffer as a hex format c-string. * * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting - * oid c-string will be truncated to n-1 characters. If there are - * any input parameter errors (out == NULL, n == 0, oid == NULL), - * then a pointer to an empty string is returned, so that the return - * value can always be printed. + * oid c-string will be truncated to n-1 characters (but will still be + * NUL-byte terminated). + * + * If there are any input parameter errors (out == NULL, n == 0, oid == + * NULL), then a pointer to an empty string is returned, so that the + * return value can always be printed. * * @param out the buffer into which the oid string is output. * @param n the size of the out buffer. @@ -145,19 +158,7 @@ GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src); * @param b second oid structure. * @return <0, 0, >0 if a < b, a == b, a > b. */ -GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b) -{ - const unsigned char *sha1 = a->id; - const unsigned char *sha2 = b->id; - int i; - - for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) { - if (*sha1 != *sha2) - return *sha1 - *sha2; - } - - return 0; -} +GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b); /** * Compare two oid structures for equality @@ -193,6 +194,16 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len); GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str); /** + * Compare an oid to an hex formatted object id. + * + * @param id oid structure. + * @param str input hex string of an object id. + * @return -1 if str is not valid, <0 if id sorts before str, + * 0 if id matches str, >0 if id sorts after str. + */ +GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str); + +/** * Check is an oid is all zeros. * * @return 1 if all zeros, 0 otherwise. diff --git a/include/git2/pack.h b/include/git2/pack.h index 2f033bef6..cc1f48add 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -95,14 +95,32 @@ GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, c GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id); /** - * Write the new pack and the corresponding index to path + * Insert a commit object + * + * This will add a commit as well as the completed referenced tree. + * + * @param pb The packbuilder + * @param id The oid of the commit + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id); + +/** + * Write the new pack and corresponding index file to path. * * @param pb The packbuilder - * @param path Directory to store the new pack and index + * @param path to the directory where the packfile and index should be stored + * @param progress_cb function to call with progress information from the indexer (optional) + * @param progress_cb_payload payload for the progress callback (optional) * * @return 0 or an error code */ -GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file); +GIT_EXTERN(int) git_packbuilder_write( + git_packbuilder *pb, + const char *path, + git_transfer_progress_callback progress_cb, + void *progress_cb_payload); typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload); /** diff --git a/include/git2/refdb.h b/include/git2/refdb.h index 0586b119e..a315876ae 100644 --- a/include/git2/refdb.h +++ b/include/git2/refdb.h @@ -22,22 +22,6 @@ GIT_BEGIN_DECL /** - * Create a new reference. Either an oid or a symbolic target must be - * specified. - * - * @param refdb the reference database to associate with this reference - * @param name the reference name - * @param oid the object id for a direct reference - * @param symbolic the target for a symbolic reference - * @return the created git_reference or NULL on error - */ -GIT_EXTERN(git_reference *) git_reference__alloc( - git_refdb *refdb, - const char *name, - const git_oid *oid, - const char *symbolic); - -/** * Create a new reference database with no backends. * * Before the Ref DB can be used for read/writing, a custom database @@ -78,20 +62,6 @@ GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb); */ GIT_EXTERN(void) git_refdb_free(git_refdb *refdb); -/** - * Sets the custom backend to an existing reference DB - * - * Read <refdb_backends.h> for more information. - * - * @param refdb database to add the backend to - * @param backend pointer to a git_refdb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_refdb_set_backend( - git_refdb *refdb, - git_refdb_backend *backend); - /** @} */ GIT_END_DECL diff --git a/include/git2/refdb_backend.h b/include/git2/refdb_backend.h deleted file mode 100644 index bf33817d6..000000000 --- a/include/git2/refdb_backend.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_refdb_backend_h__ -#define INCLUDE_git_refdb_backend_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/refdb_backend.h - * @brief Git custom refs backend functions - * @defgroup git_refdb_backend Git custom refs backend API - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** An instance for a custom backend */ -struct git_refdb_backend { - unsigned int version; - - /** - * Queries the refdb backend to determine if the given ref_name - * exists. A refdb implementation must provide this function. - */ - int (*exists)( - int *exists, - struct git_refdb_backend *backend, - const char *ref_name); - - /** - * Queries the refdb backend for a given reference. A refdb - * implementation must provide this function. - */ - int (*lookup)( - git_reference **out, - struct git_refdb_backend *backend, - const char *ref_name); - - /** - * Enumerates each reference in the refdb. A refdb implementation must - * provide this function. - */ - int (*foreach)( - struct git_refdb_backend *backend, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); - - /** - * Enumerates each reference in the refdb that matches the given - * glob string. A refdb implementation may provide this function; - * if it is not provided, foreach will be used and the results filtered - * against the glob. - */ - int (*foreach_glob)( - struct git_refdb_backend *backend, - const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); - - /** - * Writes the given reference to the refdb. A refdb implementation - * must provide this function. - */ - int (*write)(struct git_refdb_backend *backend, const git_reference *ref); - - /** - * Deletes the given reference from the refdb. A refdb implementation - * must provide this function. - */ - int (*delete)(struct git_refdb_backend *backend, const git_reference *ref); - - /** - * Suggests that the given refdb compress or optimize its references. - * This mechanism is implementation specific. (For on-disk reference - * databases, this may pack all loose references.) A refdb - * implementation may provide this function; if it is not provided, - * nothing will be done. - */ - int (*compress)(struct git_refdb_backend *backend); - - /** - * Frees any resources held by the refdb. A refdb implementation may - * provide this function; if it is not provided, nothing will be done. - */ - void (*free)(struct git_refdb_backend *backend); -}; - -#define GIT_ODB_BACKEND_VERSION 1 -#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} - -/** - * Constructors for default refdb backends. - */ -GIT_EXTERN(int) git_refdb_backend_fs( - struct git_refdb_backend **backend_out, - git_repository *repo, - git_refdb *refdb); - -GIT_END_DECL - -#endif diff --git a/include/git2/refs.h b/include/git2/refs.h index e0451ba82..795f7ab27 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -48,13 +48,26 @@ GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, * * @param out Pointer to oid to be filled in * @param repo The repository in which to look up the reference - * @param name The long name for the reference + * @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_name_to_id( git_oid *out, git_repository *repo, const char *name); /** + * Lookup a reference by DWIMing its short name + * + * Apply the git precendence rules to the given shorthand to determine + * which reference the user is refering to. + * + * @param out pointer in which to store the reference + * @param repo the repository in which to look + * @param shorthand the short name for the reference + * @return 0 or an error code + */ +GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, const char *shorthand); + +/** * Create a new symbolic reference. * * A symbolic reference is a reference name that refers to another @@ -133,6 +146,17 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref); /** + * Return the peeled OID target of this reference. + * + * This peeled OID only applies to direct references that point to + * a hard Tag object: it is the result of peeling such Tag. + * + * @param ref The reference + * @return a pointer to the oid if available, NULL otherwise + */ +GIT_EXTERN(const git_oid *) git_reference_target_peel(const git_reference *ref); + +/** * Get full name to the reference pointed to by a symbolic reference. * * Only available if the reference is symbolic. @@ -174,7 +198,7 @@ GIT_EXTERN(const char *) git_reference_name(const git_reference *ref); * 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 out Pointer to the peeled reference * @param ref The reference * @return 0 or an error code */ @@ -233,11 +257,6 @@ GIT_EXTERN(int) git_reference_set_target( * The new name will be checked for validity. * See `git_reference_create_symbolic()` for rules about valid names. * - * On success, the given git_reference will be deleted from disk and a - * new `git_reference` will be returned. - * - * The reference will be immediately renamed in-memory and on disk. - * * If the `force` flag is not enabled, and there's already * a reference with the given name, the renaming will fail. * @@ -247,13 +266,13 @@ GIT_EXTERN(int) git_reference_set_target( * the reflog if it exists. * * @param ref The reference to rename - * @param name The new name for the reference + * @param new_name The new name for the reference * @param force Overwrite an existing reference * @return 0 on success, EINVALIDSPEC, EEXISTS or an error code * */ GIT_EXTERN(int) git_reference_rename( - git_reference **out, + git_reference **new_ref, git_reference *ref, const char *new_name, int force); @@ -273,12 +292,6 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref); /** * Fill a list with all the references that can be found in a repository. * - * 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()`. @@ -286,39 +299,36 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref); * @param array Pointer to a git_strarray structure where * the reference names will be stored * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference listing * @return 0 or an error code */ -GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags); +GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo); -typedef int (*git_reference_foreach_cb)(const char *refname, void *payload); +typedef int (*git_reference_foreach_cb)(git_reference *reference, void *payload); +typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload); /** * Perform a callback on each reference in the repository. * - * 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 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 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, git_reference_foreach_cb callback, void *payload); +GIT_EXTERN(int) git_reference_foreach_name( + git_repository *repo, + git_reference_foreach_name_cb callback, + void *payload); + /** * Free the given reference. * @@ -336,6 +346,49 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref); GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); /** + * Create an iterator for the repo's references + * + * @param out pointer in which to store the iterator + * @param repo the repository + * @return 0 or an error code + */ +GIT_EXTERN(int) git_reference_iterator_new( + git_reference_iterator **out, + git_repository *repo); + +/** + * Create an iterator for the repo's references that match the + * specified glob + * + * @param out pointer in which to store the iterator + * @param repo the repository + * @param glob the glob to match against the reference names + * @return 0 or an error code + */ +GIT_EXTERN(int) git_reference_iterator_glob_new( + git_reference_iterator **out, + git_repository *repo, + const char *glob); + +/** + * Get the next reference + * + * @param out pointer in which to store the reference + * @param iter the iterator + * @return 0, GIT_ITEROVER if there are no more; or an error code + */ +GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter); + +GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter); + +/** + * Free the iterator and its associated resources + * + * @param iter the iterator to free + */ +GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter); + +/** * Perform a callback on each reference in the repository whose name * matches the given pattern. * @@ -349,7 +402,6 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); * * @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 @@ -357,8 +409,7 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); GIT_EXTERN(int) git_reference_foreach_glob( git_repository *repo, const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, + git_reference_foreach_name_cb callback, void *payload); /** @@ -411,6 +462,13 @@ typedef enum { * (e.g., foo/<star>/bar but not foo/bar<star>). */ GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1), + + /** + * Interpret the name as part of a refspec in shorthand form + * so the `ONELEVEL` naming rules aren't enforced and 'master' + * becomes a valid name. + */ + GIT_REF_FORMAT_REFSPEC_SHORTHAND = (1 << 2), } git_reference_normalize_t; /** @@ -448,9 +506,9 @@ GIT_EXTERN(int) git_reference_normalize_name( * If you pass `GIT_OBJ_ANY` as the target type, then the object * will be peeled until a non-tag object is met. * - * @param peeled Pointer to the peeled git_object + * @param out Pointer to the peeled git_object * @param ref The reference to be processed - * @param target_type The type of the requested object (GIT_OBJ_COMMIT, + * @param 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 */ @@ -475,6 +533,21 @@ GIT_EXTERN(int) git_reference_peel( */ GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); +/** + * Get the reference's short name + * + * This will transform the reference name into a name "human-readable" + * version. If no shortname is appropriate, it will return the full + * name. + * + * The memory is owned by the reference and must not be freed. + * + * @param ref a reference + * @return the human-readable version of the name + */ +GIT_EXTERN(const char *) git_reference_shorthand(git_reference *ref); + + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/refspec.h b/include/git2/refspec.h index ec7830b7c..d96b83ce2 100644 --- a/include/git2/refspec.h +++ b/include/git2/refspec.h @@ -9,6 +9,7 @@ #include "common.h" #include "types.h" +#include "net.h" /** * @file git2/refspec.h @@ -36,6 +37,14 @@ GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec); GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec); /** + * Get the refspec's string + * + * @param refspec the refspec + * @returns the refspec's original string + */ +GIT_EXTERN(const char *) git_refspec_string(const git_refspec *refspec); + +/** * Get the force update setting * * @param refspec the refspec @@ -44,6 +53,14 @@ GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec); GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec); /** + * Get the refspec's direction. + * + * @param spec refspec + * @return GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH + */ +GIT_EXTERN(git_direction) git_refspec_direction(const git_refspec *spec); + +/** * Check if a refspec's source descriptor matches a reference * * @param refspec the refspec diff --git a/include/git2/remote.h b/include/git2/remote.h index 6f36a3999..45d15d0a3 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -142,39 +142,79 @@ GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url); GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url); /** - * Set the remote's fetch refspec + * Add a fetch refspec to the remote * * @param remote the remote - * @apram spec the new fetch refspec + * @apram refspec the new fetch refspec * @return 0 or an error value */ -GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec); +GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec); /** - * Get the fetch refspec + * Get the remote's list of fetch refspecs * - * @param remote the remote - * @return a pointer to the fetch refspec or NULL if it doesn't exist + * The memory is owned by the user and should be freed with + * `git_strarray_free`. + * + * @param array pointer to the array in which to store the strings + * @param remote the remote to query */ -GIT_EXTERN(const git_refspec *) git_remote_fetchspec(const git_remote *remote); +GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote); /** - * Set the remote's push refspec + * Add a push refspec to the remote * * @param remote the remote - * @param spec the new push refspec + * @param refspec the new push refspec * @return 0 or an error value */ -GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec); +GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec); + +/** + * Get the remote's list of push refspecs + * + * The memory is owned by the user and should be freed with + * `git_strarray_free`. + * + * @param array pointer to the array in which to store the strings + * @param remote the remote to query + */ +GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *remote); + +/** + * Clear the refspecs + * + * Remove all configured fetch and push refspecs from the remote. + * + * @param remote the remote + */ +GIT_EXTERN(void) git_remote_clear_refspecs(git_remote *remote); /** - * Get the push refspec + * Get the number of refspecs for a remote * * @param remote the remote - * @return a pointer to the push refspec or NULL if it doesn't exist + * @return the amount of refspecs configured in this remote + */ +GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote); + +/** + * Get a refspec from the remote + * + * @param remote the remote to query + * @param n the refspec to get + * @return the nth refspec */ +GIT_EXTERN(const git_refspec *)git_remote_get_refspec(git_remote *remote, size_t n); -GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote); +/** + * Remove a refspec from the remote + * + * @param remote the remote to query + * @param n the refspec to remove + * @return 0 or GIT_ENOTFOUND + */ +GIT_EXTERN(int) git_remote_remove_refspec(git_remote *remote, size_t n); /** * Open a connection to a remote @@ -184,7 +224,8 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote); * starts up a specific binary which can only do the one or the other. * * @param remote the remote to connect to - * @param direction whether you want to receive or send data + * @param direction GIT_DIRECTION_FETCH if you want to fetch or + * GIT_DIRECTION_PUSH if you want to push * @return 0 or an error code */ GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction); @@ -218,7 +259,7 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void * @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 + * @param payload payload for the progress callback * @return 0 or an error code */ GIT_EXTERN(int) git_remote_download( @@ -279,7 +320,7 @@ GIT_EXTERN(int) git_remote_update_tips(git_remote *remote); * Return whether a string is a valid remote URL * * @param url the url to check - * @param 1 if the url is valid, 0 otherwise + * @return 1 if the url is valid, 0 otherwise */ GIT_EXTERN(int) git_remote_valid_url(const char *url); @@ -385,10 +426,9 @@ GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callback GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote); typedef enum { - GIT_REMOTE_DOWNLOAD_TAGS_UNSET, - GIT_REMOTE_DOWNLOAD_TAGS_NONE, - GIT_REMOTE_DOWNLOAD_TAGS_AUTO, - GIT_REMOTE_DOWNLOAD_TAGS_ALL + GIT_REMOTE_DOWNLOAD_TAGS_AUTO = 0, + GIT_REMOTE_DOWNLOAD_TAGS_NONE = 1, + GIT_REMOTE_DOWNLOAD_TAGS_ALL = 2 } git_remote_autotag_option_t; /** diff --git a/include/git2/repository.h b/include/git2/repository.h index e75c8b136..2164cfac1 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -124,6 +124,19 @@ GIT_EXTERN(int) git_repository_open_ext( const char *ceiling_dirs); /** + * Open a bare repository on the serverside. + * + * This is a fast open for bare repositories that will come in handy + * if you're e.g. hosting git repositories and need to access them + * efficiently + * + * @param out Pointer to the repo which will be opened. + * @param bare_path Direct path to the bare repository + * @return 0 on success, or an error code + */ +GIT_EXTERN(int) git_repository_open_bare(git_repository **out, const char *bare_path); + +/** * Free a previously allocated repository * * Note that after a repository is free'd, all the objects it has spawned @@ -388,21 +401,6 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo); GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo); /** - * Set the configuration file for this repository - * - * This configuration file will be used for all configuration - * queries involving this repository. - * - * The repository will keep a reference to the config file; - * the user must still free the config after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param config A Config object - */ -GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); - -/** * Get the Object Database for this repository. * * If a custom ODB has not been set, the default @@ -419,21 +417,6 @@ GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *con GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo); /** - * Set the Object Database for this repository - * - * The ODB will be used for all object-related operations - * involving this repository. - * - * The repository will keep a reference to the ODB; the user - * must still free the ODB object after setting it to the - * repository, or it will leak. - * - * @param repo A repository object - * @param odb An ODB object - */ -GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); - -/** * Get the Reference Database Backend for this repository. * * If a custom refsdb has not been set, the default database for @@ -450,23 +433,6 @@ GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo); /** - * Set the Reference Database Backend for this repository - * - * The refdb will be used for all reference related operations - * involving this repository. - * - * The repository will keep a reference to the refdb; the user - * must still free the refdb object after setting it to the - * repository, or it will leak. - * - * @param repo A repository object - * @param refdb An refdb object - */ -GIT_EXTERN(void) git_repository_set_refdb( - git_repository *repo, - git_refdb *refdb); - -/** * Get the Index file for this repository. * * If a custom index has not been set, the default @@ -483,21 +449,6 @@ GIT_EXTERN(void) git_repository_set_refdb( GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo); /** - * Set the index file for this repository - * - * This index will be used for all index-related operations - * involving this repository. - * - * The repository will keep a reference to the index file; - * the user must still free the index after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param index An index object - */ -GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); - -/** * Retrieve git's prepared message * * Operations such as git revert/cherry-pick/merge with the -n option @@ -509,10 +460,19 @@ 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. * + * If the repository message exists and there are no errors reading it, this + * returns the bytes needed to store the message in memory (i.e. message + * file size plus one terminating NUL byte). That value is returned even if + * `out` is NULL or `len` is shorter than the necessary size. + * + * The `out` buffer will *always* be NUL terminated, even if truncation + * occurs. + * * @param out Buffer to write data into or NULL to just read required size - * @param len Length of buffer in bytes + * @param len Length of `out` 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 + * @return GIT_ENOUTFOUND if no message exists, other value < 0 for other + * errors, or total bytes in message (may be > `len`) on success */ GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo); @@ -559,7 +519,7 @@ typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid, * * @param repo A repository object * @param callback Callback function - * @param apyload Pointer to callback data (optional) + * @param payload 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, @@ -585,11 +545,11 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo, * applied when calculating the hash. */ GIT_EXTERN(int) git_repository_hashfile( - git_oid *out, - git_repository *repo, - const char *path, - git_otype type, - const char *as_path); + git_oid *out, + git_repository *repo, + const char *path, + git_otype type, + const char *as_path); /** * Make the repository HEAD point to the specified reference. @@ -675,6 +635,37 @@ typedef enum { */ GIT_EXTERN(int) git_repository_state(git_repository *repo); +/** + * Sets the active namespace for this Git Repository + * + * This namespace affects all reference operations for the repo. + * See `man gitnamespaces` + * + * @param repo The repo + * @param nmspace The namespace. This should not include the refs + * folder, e.g. to namespace all references under `refs/namespaces/foo/`, + * use `foo` as the namespace. + * @return 0 on success, -1 on error + */ +GIT_EXTERN(int) git_repository_set_namespace(git_repository *repo, const char *nmspace); + +/** + * Get the currently active namespace for this repository + * + * @param repo The repo + * @return the active namespace, or NULL if there isn't one + */ +GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo); + + +/** + * Determine if the repository was a shallow clone + * + * @param repo The repository + * @return 1 if shallow, zero if not + */ +GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/reset.h b/include/git2/reset.h index c7c951942..c36781722 100644 --- a/include/git2/reset.h +++ b/include/git2/reset.h @@ -72,9 +72,9 @@ GIT_EXTERN(int) git_reset( * @return 0 on success or an error code < 0 */ GIT_EXTERN(int) git_reset_default( - git_repository *repo, - git_object *target, - git_strarray* pathspecs); + git_repository *repo, + git_object *target, + git_strarray* pathspecs); /** @} */ GIT_END_DECL diff --git a/include/git2/revparse.h b/include/git2/revparse.h index e155c7012..786a9da57 100644 --- a/include/git2/revparse.h +++ b/include/git2/revparse.h @@ -32,6 +32,28 @@ GIT_BEGIN_DECL */ GIT_EXTERN(int) git_revparse_single(git_object **out, git_repository *repo, const char *spec); +/** + * Find a single object, as specified by a revision string. + * See `man gitrevisions`, + * or http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for + * information on the syntax accepted. + * + * In some cases (`@{<-n>}` or `<branchname>@{upstream}`), the expression may + * point to an intermediate reference. When such expressions are being passed + * in, `reference_out` will be valued as well. + * + * @param object_out pointer to output object + * @param reference_out pointer to output reference or NULL + * @param repo the repository to search in + * @param spec the textual specification for an object + * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC + * or an error code + */ +GIT_EXTERN(int) git_revparse_ext( + git_object **object_out, + git_reference **reference_out, + git_repository *repo, + const char *spec); /** * Revparse flags. These indicate the intended behavior of the spec passed to diff --git a/include/git2/stash.h b/include/git2/stash.h index cf8bc9d4c..68d1b5413 100644 --- a/include/git2/stash.h +++ b/include/git2/stash.h @@ -89,7 +89,7 @@ typedef int (*git_stash_cb)( * * @param repo Repository where to find the stash. * - * @param callabck Callback to invoke per found stashed state. The most recent + * @param callback Callback to invoke per found stashed state. The most recent * stash state will be enumerated first. * * @param payload Extra parameter to callback function. diff --git a/include/git2/status.h b/include/git2/status.h index 38b6fa5bd..63aea2f3b 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -42,6 +42,7 @@ typedef enum { GIT_STATUS_WT_MODIFIED = (1u << 8), GIT_STATUS_WT_DELETED = (1u << 9), GIT_STATUS_WT_TYPECHANGE = (1u << 10), + GIT_STATUS_WT_RENAMED = (1u << 11), GIT_STATUS_IGNORED = (1u << 14), } git_status_t; @@ -59,43 +60,19 @@ 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 (a combination of - * the `git_status_t` values above) and the `payload` data pointer passed - * into this function. - * - * If the callback returns a non-zero value, this function will stop looping - * and return GIT_EUSER. - * - * @param repo A repository object - * @param callback The function to call on each file - * @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, - git_status_cb callback, - void *payload); - -/** * 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 - * will receive a callback indicating its status in the index and - * in the workdir. - * - GIT_STATUS_SHOW_INDEX_ONLY will only make callbacks for index - * side of status. The status of the index contents relative to - * the HEAD will be given. - * - GIT_STATUS_SHOW_WORKDIR_ONLY will only make callbacks for the - * workdir side of status, reporting the status of workdir content - * relative to the index. - * - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR behaves like index-only - * followed by workdir-only, causing two callbacks to be issued - * per file (first index then workdir). This is slightly more - * efficient than making separate calls. This makes it easier to - * emulate the output of a plain `git status`. + * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This roughly + * matches `git status --porcelain` where each file gets a callback + * indicating its status in the index and in the working directory. + * - GIT_STATUS_SHOW_INDEX_ONLY only gives status based on HEAD to index + * comparison, not looking at working directory changes. + * - GIT_STATUS_SHOW_WORKDIR_ONLY only gives status based on index to + * working directory comparison, not comparing the index to the HEAD. + * - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR runs index-only then workdir-only, + * issuing (up to) two callbacks per file (first index, then workdir). + * This is slightly more efficient than separate calls and can make it + * easier to emulate plain `git status` text output. */ typedef enum { GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0, @@ -110,26 +87,36 @@ typedef enum { * - 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_IGNORED says that ignored files get callbacks. + * Again, these callbacks will only be made if the workdir files are + * included in the status "show" option. * - GIT_STATUS_OPT_INCLUDE_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_EXCLUDE_SUBMODULES indicates that submodules should be + * skipped. This only applies if there are no pending typechanges to + * the submodule (either from or to another type). + * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that all files in + * untracked directories should be included. Normally if an entire + * directory is new, then just the top-level directory is included (with + * a trailing slash on the entry name). This flag says to include all + * of the individual files in the directory instead. * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path - * will be treated as a literal path, and not as a pathspec. + * should be treated as a literal path, and not as a pathspec pattern. * - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS indicates that the contents of * ignored directories should be included in the status. This is like * doing `git ls-files -o -i --exclude-standard` with core git. + * - GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX indicates that rename detection + * should be processed between the head and the index and enables + * the GIT_STATUS_INDEX_RENAMED as a possible status flag. + * - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates tha rename + * detection should be run between the index and the working directory + * and enabled GIT_STATUS_WT_RENAMED as a possible status flag. + * - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case + * sensitivity for the file system and forces the output to be in + * case-sensitive order + * - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case + * sensitivity for the file system and forces the output to be in + * case-insensitive order * * Calling `git_status_foreach()` is like calling the extended version * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED, @@ -137,13 +124,17 @@ typedef enum { * together as `GIT_STATUS_OPT_DEFAULTS` if you want them as a baseline. */ typedef enum { - GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0), - GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1), - GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2), - GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3), - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4), - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5), - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6), + GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0), + GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1), + GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2), + GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3), + GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4), + GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5), + GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6), + GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX = (1u << 7), + GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8), + GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9), + GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10), } git_status_opt_t; #define GIT_STATUS_OPT_DEFAULTS \ @@ -178,6 +169,47 @@ typedef struct { #define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION} /** + * A status entry, providing the differences between the file as it exists + * in HEAD and the index, and providing the differences between the index + * and the working directory. + * + * The `status` value provides the status flags for this file. + * + * The `head_to_index` value provides detailed information about the + * differences between the file in HEAD and the file in the index. + * + * The `index_to_workdir` value provides detailed information about the + * differences between the file in the index and the file in the + * working directory. + */ +typedef struct { + git_status_t status; + git_diff_delta *head_to_index; + git_diff_delta *index_to_workdir; +} git_status_entry; + + +/** + * Gather file statuses and run a callback for each one. + * + * The callback is passed the path of the file, the status (a combination of + * the `git_status_t` values above) and the `payload` data pointer passed + * into this function. + * + * If the callback returns a non-zero value, this function will stop looping + * and return 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, + git_status_cb callback, + void *payload); + +/** * Gather file status information and run callbacks as requested. * * This is an extended version of the `git_status_foreach()` API that @@ -216,6 +248,49 @@ GIT_EXTERN(int) git_status_file( const char *path); /** + * Gather file status information and populate the `git_status_list`. + * + * @param out Pointer to store the status results in + * @param repo Repository object + * @param opts Status options structure + * @return 0 on success or error code + */ +GIT_EXTERN(int) git_status_list_new( + git_status_list **out, + git_repository *repo, + const git_status_options *opts); + +/** + * Gets the count of status entries in this list. + * + * @param statuslist Existing status list object + * @return the number of status entries + */ +GIT_EXTERN(size_t) git_status_list_entrycount( + git_status_list *statuslist); + +/** + * Get a pointer to one of the entries in the status list. + * + * The entry is not modifiable and should not be freed. + * + * @param statuslist Existing status list object + * @param idx Position of the entry + * @return Pointer to the entry; NULL if out of bounds + */ +GIT_EXTERN(const git_status_entry *) git_status_byindex( + git_status_list *statuslist, + size_t idx); + +/** + * Free an existing status list + * + * @param statuslist Existing status list object + */ +GIT_EXTERN(void) git_status_list_free( + git_status_list *statuslist); + +/** * Test if the ignore rules apply to a given file. * * This function checks the ignore rules to see if they would apply to the diff --git a/include/git2/strarray.h b/include/git2/strarray.h index d338eb7ad..86fa25f3f 100644 --- a/include/git2/strarray.h +++ b/include/git2/strarray.h @@ -20,8 +20,8 @@ GIT_BEGIN_DECL /** Array of strings */ typedef struct git_strarray { - char **strings; - size_t count; + char **strings; + size_t count; } git_strarray; /** diff --git a/include/git2/submodule.h b/include/git2/submodule.h index 40934b3ed..91b5300ae 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -103,20 +103,20 @@ typedef enum { * * WD_UNTRACKED - wd contains untracked files */ typedef enum { - GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0), - GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1), - GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2), - GIT_SUBMODULE_STATUS_IN_WD = (1u << 3), - GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4), - GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5), - GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6), - GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7), - GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8), - GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9), - GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10), - GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11), - GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12), - GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13), + GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0), + GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1), + GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2), + GIT_SUBMODULE_STATUS_IN_WD = (1u << 3), + GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4), + GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5), + GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6), + GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7), + GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8), + GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9), + GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10), + GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11), + GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12), + GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13), } git_submodule_status_t; #define GIT_SUBMODULE_STATUS__IN_FLAGS \ @@ -481,7 +481,7 @@ GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule); * function will return distinct `git_repository` objects. This will only * work if the submodule is checked out into the working directory. * - * @param subrepo Pointer to the submodule repo which was opened + * @param repo Pointer to the submodule repo which was opened * @param submodule Submodule to be opened * @return 0 on success, <0 if submodule repo could not be opened. */ @@ -531,7 +531,7 @@ GIT_EXTERN(int) git_submodule_status( * This can be useful if you want to know if the submodule is present in the * working directory at this point in time, etc. * - * @param status Combination of first four `GIT_SUBMODULE_STATUS` flags + * @param location_status Combination of first four `GIT_SUBMODULE_STATUS` flags * @param submodule Submodule for which to get status * @return 0 on success, <0 on error */ diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h new file mode 100644 index 000000000..34a12fb15 --- /dev/null +++ b/include/git2/sys/commit.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_commit_h__ +#define INCLUDE_sys_git_commit_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" + +/** + * @file git2/sys/commit.h + * @brief Low-level Git commit creation + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create new commit in the repository from a list of `git_oid` values + * + * See documentation for `git_commit_create()` for information about the + * parameters, as the meaning is identical excepting that `tree` and + * `parents` now take `git_oid`. This is a dangerous API in that nor + * the `tree`, neither the `parents` list of `git_oid`s are checked for + * validity. + */ +GIT_EXTERN(int) git_commit_create_from_oids( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_oid *tree, + int parent_count, + const git_oid *parents[]); + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h new file mode 100644 index 000000000..11e59cf03 --- /dev/null +++ b/include/git2/sys/config.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_config_backend_h__ +#define INCLUDE_sys_git_config_backend_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/config.h" + +/** + * @file git2/sys/config.h + * @brief Git config backend routines + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Generic backend that implements the interface to + * access a configuration 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_backend *, git_config_level_t level); + int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); + int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); + int (*set)(struct git_config_backend *, const char *key, const char *value); + int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); + int (*del)(struct git_config_backend *, const char *key); + int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); + int (*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} + +/** + * Add a generic config file instance to an existing config + * + * Note that the configuration object will free the file + * automatically. + * + * Further queries on this config object will access each + * of the config file instances in order (instances with + * a higher priority level will be accessed first). + * + * @param cfg the configuration to add the file to + * @param file the configuration file (backend) to add + * @param level the priority level of the backend + * @param force if a config file already exists for the given + * priority level, replace it + * @return 0 on success, GIT_EEXISTS when adding more than one file + * for a given priority level (and force_replace set to 0), or error code + */ +GIT_EXTERN(int) git_config_add_backend( + git_config *cfg, + git_config_backend *file, + git_config_level_t level, + int force); + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/sys/index.h b/include/git2/sys/index.h new file mode 100644 index 000000000..a32e07036 --- /dev/null +++ b/include/git2/sys/index.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_index_h__ +#define INCLUDE_sys_git_index_h__ + +/** + * @file git2/sys/index.h + * @brief Low-level Git index manipulation routines + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** Representation of a rename conflict entry in the index. */ +typedef struct git_index_name_entry { + char *ancestor; + char *ours; + char *theirs; +} git_index_name_entry; + +/** Representation of a resolve undo entry in the index. */ +typedef struct git_index_reuc_entry { + unsigned int mode[3]; + git_oid oid[3]; + char *path; +} git_index_reuc_entry; + +/** @name Conflict Name entry functions + * + * These functions work on rename conflict entries. + */ +/**@{*/ + +/** + * Get the count of filename conflict entries currently in the index. + * + * @param index an existing index object + * @return integer of count of current filename conflict entries + */ +GIT_EXTERN(unsigned int) git_index_name_entrycount(git_index *index); + +/** + * Get a filename conflict entry from the index. + * + * The returned entry is read-only and should not be modified + * or freed by the caller. + * + * @param index an existing index object + * @param n the position of the entry + * @return a pointer to the filename conflict entry; NULL if out of bounds + */ +GIT_EXTERN(const git_index_name_entry *) git_index_name_get_byindex( + git_index *index, size_t n); + +/** + * Record the filenames involved in a rename conflict. + * + * @param index an existing index object + * @param ancestor the path of the file as it existed in the ancestor + * @param ours the path of the file as it existed in our tree + * @param theirs the path of the file as it existed in their tree + */ +GIT_EXTERN(int) git_index_name_add(git_index *index, + const char *ancestor, const char *ours, const char *theirs); + +/** + * Remove all filename conflict entries. + * + * @param index an existing index object + * @return 0 or an error code + */ +GIT_EXTERN(void) git_index_name_clear(git_index *index); + +/**@}*/ + +/** @name Resolve Undo (REUC) index entry manipulation. + * + * These functions work on the Resolve Undo index extension and contains + * data about the original files that led to a merge conflict. + */ +/**@{*/ + +/** + * Get the count of resolve undo entries currently in the index. + * + * @param index an existing index object + * @return integer of count of current resolve undo entries + */ +GIT_EXTERN(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 at_pos the address to which the position of the reuc entry is written (optional) + * @param index an existing index object + * @param path path to search + * @return 0 if found, < 0 otherwise (GIT_ENOTFOUND) + */ +GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path); + +/** + * Get a resolve undo entry from the index. + * + * The returned entry is read-only and should not be modified + * or freed by the caller. + * + * @param index an existing index object + * @param path path to search + * @return the resolve undo entry; NULL if not found + */ +GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path); + +/** + * Get a resolve undo entry from the index. + * + * The returned entry is read-only and should not be modified + * or freed by the caller. + * + * @param index an existing index object + * @param n the position of the entry + * @return a pointer to the resolve undo entry; NULL if out of bounds + */ +GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n); + +/** + * Adds a resolve undo entry for a file based on the given parameters. + * + * The resolve undo entry contains the OIDs of files that were involved + * in a merge conflict after the conflict has been resolved. This allows + * conflicts to be re-resolved later. + * + * If there exists a resolve undo entry for the given path in the index, + * it will be removed. + * + * This method will fail in bare index instances. + * + * @param index an existing index object + * @param path filename to add + * @param ancestor_mode mode of the ancestor file + * @param ancestor_id oid of the ancestor file + * @param our_mode mode of our file + * @param our_id oid of our file + * @param their_mode mode of their file + * @param their_id oid of their file + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path, + int ancestor_mode, const git_oid *ancestor_id, + int our_mode, const git_oid *our_id, + int their_mode, const git_oid *their_id); + +/** + * Remove an resolve undo entry from the index + * + * @param index an existing index object + * @param n position of the resolve undo entry to remove + * @return 0 or an error code + */ +GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n); + +/** + * Remove all resolve undo entries from the index + * + * @param index an existing index object + * @return 0 or an error code + */ +GIT_EXTERN(void) git_index_reuc_clear(git_index *index); + +/**@}*/ + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h new file mode 100644 index 000000000..3cd2734c0 --- /dev/null +++ b/include/git2/sys/odb_backend.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_odb_backend_h__ +#define INCLUDE_sys_git_odb_backend_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" +#include "git2/odb.h" + +/** + * @file git2/sys/backend.h + * @brief Git custom backend implementors functions + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * An instance for a custom backend + */ +struct git_odb_backend { + unsigned int version; + git_odb *odb; + + /* read and read_prefix each return to libgit2 a buffer which + * will be freed later. The buffer should be allocated using + * the function git_odb_backend_malloc to ensure that it can + * be safely freed later. */ + int (* read)( + void **, size_t *, git_otype *, git_odb_backend *, const git_oid *); + + /* To find a unique object given a prefix + * of its oid. + * The oid given must be so that the + * remaining (GIT_OID_HEXSZ - len)*4 bits + * are 0s. + */ + int (* read_prefix)( + git_oid *, void **, size_t *, git_otype *, + git_odb_backend *, const git_oid *, size_t); + + int (* read_header)( + size_t *, git_otype *, git_odb_backend *, const git_oid *); + + /* The writer may assume that the object + * has already been hashed and is passed + * in the first parameter. + */ + int (* write)( + git_oid *, git_odb_backend *, const void *, size_t, git_otype); + + int (* writestream)( + git_odb_stream **, git_odb_backend *, size_t, git_otype); + + int (* readstream)( + git_odb_stream **, git_odb_backend *, const git_oid *); + + int (* exists)( + git_odb_backend *, const git_oid *); + + int (* refresh)(git_odb_backend *); + + int (* foreach)( + git_odb_backend *, git_odb_foreach_cb cb, void *payload); + + int (* writepack)( + git_odb_writepack **, git_odb_backend *, + git_transfer_progress_callback progress_cb, void *progress_payload); + + void (* free)(git_odb_backend *); +}; + +#define GIT_ODB_BACKEND_VERSION 1 +#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} + +GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); + +GIT_END_DECL + +#endif diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h new file mode 100644 index 000000000..9b457b074 --- /dev/null +++ b/include/git2/sys/refdb_backend.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_refdb_backend_h__ +#define INCLUDE_sys_git_refdb_backend_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" + +/** + * @file git2/refdb_backend.h + * @brief Git custom refs backend functions + * @defgroup git_refdb_backend Git custom refs backend API + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + + +/** + * Every backend's iterator must have a pointer to itself as the first + * element, so the API can talk to it. You'd define your iterator as + * + * struct my_iterator { + * git_reference_iterator parent; + * ... + * } + * + * and assign `iter->parent.backend` to your `git_refdb_backend`. + */ +struct git_reference_iterator { + git_refdb *db; + + /** + * Return the current reference and advance the iterator. + */ + int (*next)( + git_reference **ref, + git_reference_iterator *iter); + + /** + * Return the name of the current reference and advance the iterator + */ + int (*next_name)( + const char **ref_name, + git_reference_iterator *iter); + + /** + * Free the iterator + */ + void (*free)( + git_reference_iterator *iter); +}; + +/** An instance for a custom backend */ +struct git_refdb_backend { + unsigned int version; + + /** + * Queries the refdb backend to determine if the given ref_name + * exists. A refdb implementation must provide this function. + */ + int (*exists)( + int *exists, + git_refdb_backend *backend, + const char *ref_name); + + /** + * Queries the refdb backend for a given reference. A refdb + * implementation must provide this function. + */ + int (*lookup)( + git_reference **out, + git_refdb_backend *backend, + const char *ref_name); + + /** + * Allocate an iterator object for the backend. + * + * A refdb implementation must provide this function. + */ + int (*iterator)( + git_reference_iterator **iter, + struct git_refdb_backend *backend, + const char *glob); + + /* + * Writes the given reference to the refdb. A refdb implementation + * must provide this function. + */ + int (*write)(git_refdb_backend *backend, + const git_reference *ref, int force); + + int (*rename)( + git_reference **out, git_refdb_backend *backend, + const char *old_name, const char *new_name, int force); + + /** + * Deletes the given reference from the refdb. A refdb implementation + * must provide this function. + */ + int (*delete)(git_refdb_backend *backend, const char *ref_name); + + /** + * Suggests that the given refdb compress or optimize its references. + * This mechanism is implementation specific. (For on-disk reference + * databases, this may pack all loose references.) A refdb + * implementation may provide this function; if it is not provided, + * nothing will be done. + */ + int (*compress)(git_refdb_backend *backend); + + /** + * Frees any resources held by the refdb. A refdb implementation may + * provide this function; if it is not provided, nothing will be done. + */ + void (*free)(git_refdb_backend *backend); +}; + +#define GIT_ODB_BACKEND_VERSION 1 +#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} + +/** + * Constructors for default filesystem-based refdb backend + * + * Under normal usage, this is called for you when the repository is + * opened / created, but you can use this to explicitly construct a + * filesystem refdb backend for a repository. + * + * @param backend_out Output pointer to the git_refdb_backend object + * @param repo Git repository to access + * @return 0 on success, <0 error code on failure + */ +GIT_EXTERN(int) git_refdb_backend_fs( + git_refdb_backend **backend_out, + git_repository *repo); + +/** + * Sets the custom backend to an existing reference DB + * + * The `git_refdb` will take ownership of the `git_refdb_backend` so you + * should NOT free it after calling this function. + * + * @param refdb database to add the backend to + * @param backend pointer to a git_refdb_backend instance + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_refdb_set_backend( + git_refdb *refdb, + git_refdb_backend *backend); + +GIT_END_DECL + +#endif diff --git a/include/git2/sys/refs.h b/include/git2/sys/refs.h new file mode 100644 index 000000000..85963258c --- /dev/null +++ b/include/git2/sys/refs.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_refdb_h__ +#define INCLUDE_sys_git_refdb_h__ + +#include "git2/common.h" +#include "git2/types.h" +#include "git2/oid.h" + +/** + * Create a new direct reference from an OID. + * + * @param name the reference name + * @param oid the object id for a direct reference + * @param symbolic the target for a symbolic reference + * @return the created git_reference or NULL on error + */ +GIT_EXTERN(git_reference *) git_reference__alloc( + const char *name, + const git_oid *oid, + const git_oid *peel); + +/** + * Create a new symbolic reference. + * + * @param name the reference name + * @param symbolic the target for a symbolic reference + * @return the created git_reference or NULL on error + */ +GIT_EXTERN(git_reference *) git_reference__alloc_symbolic( + const char *name, + const char *target); + +#endif diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h new file mode 100644 index 000000000..ba3d65ae5 --- /dev/null +++ b/include/git2/sys/repository.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_sys_git_repository_h__ +#define INCLUDE_sys_git_repository_h__ + +/** + * @file git2/sys/repository.h + * @brief Git repository custom implementation routines + * @defgroup git_backend Git custom backend APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a new repository with neither backends nor config object + * + * Note that this is only useful if you wish to associate the repository + * with a non-filesystem-backed object database and config store. + * + * @param out The blank repository + * @return 0 on success, or an error code + */ +GIT_EXTERN(int) git_repository_new(git_repository **out); + + +/** + * Reset all the internal state in a repository. + * + * This will free all the mapped memory and internal objects + * of the repository and leave it in a "blank" state. + * + * There's no need to call this function directly unless you're + * trying to aggressively cleanup the repo before its + * deallocation. `git_repository_free` already performs this operation + * before deallocation the repo. + */ +GIT_EXTERN(void) git_repository__cleanup(git_repository *repo); + +/** + * Set the configuration file for this repository + * + * This configuration file will be used for all configuration + * queries involving this repository. + * + * The repository will keep a reference to the config file; + * the user must still free the config after setting it + * to the repository, or it will leak. + * + * @param repo A repository object + * @param config A Config object + */ +GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); + +/** + * Set the Object Database for this repository + * + * The ODB will be used for all object-related operations + * involving this repository. + * + * The repository will keep a reference to the ODB; the user + * must still free the ODB object after setting it to the + * repository, or it will leak. + * + * @param repo A repository object + * @param odb An ODB object + */ +GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); + +/** + * Set the Reference Database Backend for this repository + * + * The refdb will be used for all reference related operations + * involving this repository. + * + * The repository will keep a reference to the refdb; the user + * must still free the refdb object after setting it to the + * repository, or it will leak. + * + * @param repo A repository object + * @param refdb An refdb object + */ +GIT_EXTERN(void) git_repository_set_refdb(git_repository *repo, git_refdb *refdb); + +/** + * Set the index file for this repository + * + * This index will be used for all index-related operations + * involving this repository. + * + * The repository will keep a reference to the index file; + * the user must still free the index after setting it + * to the repository, or it will leak. + * + * @param repo A repository object + * @param index An index object + */ +GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/tag.h b/include/git2/tag.h index 84c954c27..c822cee7c 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -30,12 +30,8 @@ GIT_BEGIN_DECL * @param id identity of the tag to locate. * @return 0 or an error code */ -GIT_INLINE(int) git_tag_lookup( - git_tag **out, git_repository *repo, const git_oid *id) -{ - return git_object_lookup( - (git_object **)out, repo, id, (git_otype)GIT_OBJ_TAG); -} +GIT_EXTERN(int) git_tag_lookup( + git_tag **out, git_repository *repo, const git_oid *id); /** * Lookup a tag object from the repository, @@ -49,12 +45,8 @@ GIT_INLINE(int) git_tag_lookup( * @param len the length of the short identifier * @return 0 or an error code */ -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 **)out, repo, id, len, (git_otype)GIT_OBJ_TAG); -} +GIT_EXTERN(int) git_tag_lookup_prefix( + git_tag **out, git_repository *repo, const git_oid *id, size_t len); /** * Close an open tag @@ -66,12 +58,7 @@ GIT_INLINE(int) git_tag_lookup_prefix( * * @param tag the tag to close */ - -GIT_INLINE(void) git_tag_free(git_tag *tag) -{ - git_object_free((git_object *)tag); -} - +GIT_EXTERN(void) git_tag_free(git_tag *tag); /** * Get the id of a tag. @@ -82,6 +69,14 @@ GIT_INLINE(void) git_tag_free(git_tag *tag) GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag); /** + * Get the repository that contains the tag. + * + * @param tag A previously loaded tag. + * @return Repository that contains this tag. + */ +GIT_EXTERN(git_repository *) git_tag_owner(const git_tag *tag); + +/** * Get the tagged object of a tag * * This method performs a repository lookup for the @@ -183,6 +178,37 @@ GIT_EXTERN(int) git_tag_create( int force); /** + * Create a new tag in the object database pointing to a git_object + * + * The message will not be cleaned up. This can be achieved + * through `git_message_prettify()`. + * + * @param oid Pointer where to store the OID of the + * newly created tag + * + * @param repo Repository where to store the tag + * + * @param tag_name Name for the tag + * + * @param target Object to which this tag points. This object + * must belong to the given `repo`. + * + * @param tagger Signature of the tagger for this tag, and + * of the tagging time + * + * @param message Full message for this tag + * + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_tag_annotation_create( + git_oid *oid, + git_repository *repo, + const char *tag_name, + const git_object *target, + const git_signature *tagger, + const char *message); + +/** * Create a new tag in the repository from a buffer * * @param oid Pointer where to store the OID of the newly created tag diff --git a/include/git2/trace.h b/include/git2/trace.h index 7409b032d..f9b4d6ff6 100644 --- a/include/git2/trace.h +++ b/include/git2/trace.h @@ -32,7 +32,7 @@ typedef enum { /** Errors that do not impact the program's execution */ GIT_TRACE_ERROR = 2, - + /** Warnings that suggest abnormal data */ GIT_TRACE_WARN = 3, @@ -65,4 +65,3 @@ GIT_EXTERN(int) git_trace_set(git_trace_level_t level, git_trace_callback cb); /** @} */ GIT_END_DECL #endif - diff --git a/include/git2/transport.h b/include/git2/transport.h index 5e9968363..81bb3abe1 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -11,6 +11,10 @@ #include "net.h" #include "types.h" +#ifdef GIT_SSH +#include <libssh2.h> +#endif + /** * @file git2/transport.h * @brief Git transport interfaces and functions @@ -27,6 +31,8 @@ GIT_BEGIN_DECL typedef enum { /* git_cred_userpass_plaintext */ GIT_CREDTYPE_USERPASS_PLAINTEXT = 1, + GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = 2, + GIT_CREDTYPE_SSH_PUBLICKEY = 3, } git_credtype_t; /* The base structure for all credential types */ @@ -43,6 +49,27 @@ typedef struct git_cred_userpass_plaintext { char *password; } git_cred_userpass_plaintext; +#ifdef GIT_SSH +typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback)); + +/* A ssh key file and passphrase */ +typedef struct git_cred_ssh_keyfile_passphrase { + git_cred parent; + char *publickey; + char *privatekey; + char *passphrase; +} git_cred_ssh_keyfile_passphrase; + +/* A ssh public key and authentication callback */ +typedef struct git_cred_ssh_publickey { + git_cred parent; + char *publickey; + size_t publickey_len; + void *sign_callback; + void *sign_data; +} git_cred_ssh_publickey; +#endif + /** * Creates a new plain-text username and password credential object. * The supplied credential parameter will be internally duplicated. @@ -57,6 +84,42 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( const char *username, const char *password); +#ifdef GIT_SSH +/** + * Creates a new ssh key file and passphrase credential object. + * The supplied credential parameter will be internally duplicated. + * + * @param out The newly created credential object. + * @param publickey The path to the public key of the credential. + * @param privatekey The path to the private key of the credential. + * @param passphrase The passphrase of the credential. + * @return 0 for success or an error code for failure + */ +GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new( + git_cred **out, + const char *publickey, + const char *privatekey, + const char *passphrase); + +/** + * Creates a new ssh public key credential object. + * The supplied credential parameter will be internally duplicated. + * + * @param out The newly created credential object. + * @param publickey The bytes of the public key. + * @param publickey_len The length of the public key in bytes. + * @param sign_callback The callback method for authenticating. + * @param sign_data The abstract data sent to the sign_callback method. + * @return 0 for success or an error code for failure + */ +GIT_EXTERN(int) git_cred_ssh_publickey_new( + git_cred **out, + const char *publickey, + size_t publickey_len, + git_cred_sign_callback, + void *sign_data); +#endif + /** * Signature of a function which acquires a credential object. * @@ -319,6 +382,17 @@ GIT_EXTERN(int) git_smart_subtransport_git( git_smart_subtransport **out, git_transport* owner); +/** + * Create an instance of the ssh subtransport. + * + * @param out The newly created subtransport + * @param owner The smart transport to own this subtransport + * @return 0 or an error code + */ +GIT_EXTERN(int) git_smart_subtransport_ssh( + git_smart_subtransport **out, + git_transport* owner); + /* *** End interface for subtransports for the smart transport *** */ diff --git a/include/git2/tree.h b/include/git2/tree.h index 73bfc86f4..65d8cc16e 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -29,11 +29,8 @@ GIT_BEGIN_DECL * @param id Identity of the tree to locate. * @return 0 or an error code */ -GIT_INLINE(int) git_tree_lookup( - git_tree **out, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE); -} +GIT_EXTERN(int) git_tree_lookup( + git_tree **out, git_repository *repo, const git_oid *id); /** * Lookup a tree object from the repository, @@ -41,21 +38,17 @@ GIT_INLINE(int) git_tree_lookup( * * @see git_object_lookup_prefix * - * @param tree pointer to the looked up tree + * @param out pointer to the looked up tree * @param repo the repo to use when locating the tree. * @param id identity of the tree to locate. * @param len the length of the short identifier * @return 0 or an error code */ -GIT_INLINE(int) git_tree_lookup_prefix( +GIT_EXTERN(int) git_tree_lookup_prefix( git_tree **out, git_repository *repo, const git_oid *id, - size_t len) -{ - return git_object_lookup_prefix( - (git_object **)out, repo, id, len, GIT_OBJ_TREE); -} + size_t len); /** * Close an open tree @@ -67,10 +60,7 @@ GIT_INLINE(int) git_tree_lookup_prefix( * * @param tree The tree to close */ -GIT_INLINE(void) git_tree_free(git_tree *tree) -{ - git_object_free((git_object *)tree); -} +GIT_EXTERN(void) git_tree_free(git_tree *tree); /** * Get the id of a tree. @@ -107,7 +97,7 @@ GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree); * @return the tree entry; NULL if not found */ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname( - git_tree *tree, const char *filename); + const git_tree *tree, const char *filename); /** * Lookup a tree entry by its position in the tree @@ -120,7 +110,7 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname( * @return the tree entry; NULL if not found */ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex( - git_tree *tree, size_t idx); + const git_tree *tree, size_t idx); /** * Lookup a tree entry by SHA value. @@ -146,12 +136,12 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid( * * @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 + * @param path Path to the contained entry * @return 0 on success; GIT_ENOTFOUND if the path does not exist */ GIT_EXTERN(int) git_tree_entry_bypath( git_tree_entry **out, - git_tree *root, + const git_tree *root, const char *path); /** @@ -222,7 +212,7 @@ GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entr * * You must call `git_object_free()` on the object when you are done with it. * - * @param object pointer to the converted object + * @param object_out pointer to the converted object * @param repo repository where to lookup the pointed object * @param entry a tree entry * @return 0 or an error code @@ -261,7 +251,7 @@ GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld); /** * Get the number of entries listed in a treebuilder * - * @param tree a previously loaded treebuilder. + * @param bld a previously loaded treebuilder. * @return the number of entries in the treebuilder */ GIT_EXTERN(unsigned int) git_treebuilder_entrycount(git_treebuilder *bld); diff --git a/include/git2/types.h b/include/git2/types.h index bc15050ce..dc344075c 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -131,6 +131,9 @@ typedef struct git_treebuilder git_treebuilder; /** Memory representation of an index file. */ typedef struct git_index git_index; +/** An interator for conflicts in the index. */ +typedef struct git_index_conflict_iterator git_index_conflict_iterator; + /** Memory representation of a set of config files */ typedef struct git_config git_config; @@ -165,6 +168,16 @@ typedef struct git_signature { /** In-memory representation of a reference. */ typedef struct git_reference git_reference; +/** Iterator for references */ +typedef struct git_reference_iterator git_reference_iterator; + +/** Merge heads, the input to merge */ +typedef struct git_merge_head git_merge_head; + +/** Representation of a status collection */ +typedef struct git_status_list git_status_list; + + /** Basic type of any Git reference. */ typedef enum { GIT_REF_INVALID = 0, /** Invalid reference */ @@ -196,6 +209,26 @@ typedef struct git_push git_push; typedef struct git_remote_head git_remote_head; typedef struct git_remote_callbacks git_remote_callbacks; +/** + * This is passed as the first argument to the callback to allow the + * user to see the progress. + */ +typedef struct git_transfer_progress { + unsigned int total_objects; + unsigned int indexed_objects; + unsigned int received_objects; + size_t received_bytes; +} git_transfer_progress; + +/** + * Type for progress callbacks during indexing. Return a value less than zero + * to cancel the transfer. + * + * @param stats Structure containing information about the state of the transfer + * @param payload Payload provided by caller + */ +typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload); + /** @} */ GIT_END_DECL diff --git a/include/git2/version.h b/include/git2/version.h index 630d51526..d8a915fac 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,9 +7,9 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ -#define LIBGIT2_VERSION "0.18.0" +#define LIBGIT2_VERSION "0.19.0" #define LIBGIT2_VER_MAJOR 0 -#define LIBGIT2_VER_MINOR 18 +#define LIBGIT2_VER_MINOR 19 #define LIBGIT2_VER_REVISION 0 #endif |