From b90500f03d3ae60f1f79d7adb36d95632a29d7e5 Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Thu, 1 Nov 2012 14:08:30 -0700 Subject: [PATCH] Improve docs, examples, warnings This improves docs in some of the public header files, cleans up and improves some of the example code, and fixes a couple of pedantic warnings in places. --- examples/Makefile | 2 +- examples/diff.c | 24 ++-- examples/showindex.c | 69 +++++---- include/git2/refs.h | 278 ++++++++++++++++++++----------------- include/git2/status.h | 125 +++++++++++------ src/refs.c | 4 +- src/status.c | 2 +- tests-clar/network/fetch.c | 5 +- 8 files changed, 294 insertions(+), 215 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index fe99c75cb..da4df5240 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,7 +1,7 @@ .PHONY: all CC = gcc -CFLAGS = -g -I../include -I../src +CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes LFLAGS = -L../build -lgit2 -lz APPS = general showindex diff diff --git a/examples/diff.c b/examples/diff.c index b72a75e1c..31ebf6bfb 100644 --- a/examples/diff.c +++ b/examples/diff.c @@ -3,7 +3,7 @@ #include #include -void check(int error, const char *message) +static void check(int error, const char *message) { if (error) { fprintf(stderr, "%s (%d)\n", message, error); @@ -11,7 +11,8 @@ void check(int error, const char *message) } } -int resolve_to_tree(git_repository *repo, const char *identifier, git_tree **tree) +static int resolve_to_tree( + git_repository *repo, const char *identifier, git_tree **tree) { int err = 0; size_t len = strlen(identifier); @@ -61,16 +62,18 @@ char *colors[] = { "\033[36m" /* cyan */ }; -int printer( +static int printer( void *data, - git_diff_delta *delta, - git_diff_range *range, + const git_diff_delta *delta, + const git_diff_range *range, char usage, const char *line, size_t line_len) { int *last_color = data, color = 0; + (void)delta; (void)range; (void)line_len; + if (*last_color >= 0) { switch (usage) { case GIT_DIFF_LINE_ADDITION: color = 3; break; @@ -93,7 +96,7 @@ int printer( return 0; } -int check_uint16_param(const char *arg, const char *pattern, uint16_t *val) +static int check_uint16_param(const char *arg, const char *pattern, uint16_t *val) { size_t len = strlen(pattern); uint16_t strval; @@ -107,7 +110,7 @@ int check_uint16_param(const char *arg, const char *pattern, uint16_t *val) return 1; } -int check_str_param(const char *arg, const char *pattern, char **val) +static int check_str_param(const char *arg, const char *pattern, char **val) { size_t len = strlen(pattern); if (strncmp(arg, pattern, len)) @@ -116,7 +119,7 @@ int check_str_param(const char *arg, const char *pattern, char **val) return 1; } -void usage(const char *message, const char *arg) +static void usage(const char *message, const char *arg) { if (message && arg) fprintf(stderr, "%s: %s\n", message, arg); @@ -128,14 +131,15 @@ void usage(const char *message, const char *arg) int main(int argc, char *argv[]) { - char path[GIT_PATH_MAX]; git_repository *repo = NULL; git_tree *t1 = NULL, *t2 = NULL; - git_diff_options opts = {0}; + git_diff_options opts; git_diff_list *diff; int i, color = -1, compact = 0, cached = 0; char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL; + memset(&opts, 0, sizeof(opts)); + /* parse arguments as copied from git-diff */ for (i = 1; i < argc; ++i) { diff --git a/examples/showindex.c b/examples/showindex.c index d26fbaebd..4b50ffd0f 100644 --- a/examples/showindex.c +++ b/examples/showindex.c @@ -3,42 +3,53 @@ int main (int argc, char** argv) { - git_repository *repo; - git_index *index; - unsigned int i, e, ecount; - git_index_entry **entries; - git_oid oid; + git_repository *repo; + git_index *index; + unsigned int i, ecount; + char *dir = "."; + char out[41]; + out[40] = '\0'; - char out[41]; - out[40] = '\0'; + if (argc > 1) + dir = argv[1]; + if (argc > 2) { + fprintf(stderr, "usage: showindex []\n"); + return 1; + } - git_repository_open(&repo, "/opt/libgit2-test/.git"); + if (git_repository_open_ext(&repo, dir, 0, NULL) < 0) { + fprintf(stderr, "could not open repository: %s\n", dir); + return 1; + } - git_repository_index(&index, repo); - git_index_read(index); + git_repository_index(&index, repo); + git_index_read(index); - ecount = git_index_entrycount(index); - for (i = 0; i < ecount; ++i) { - git_index_entry *e = git_index_get_byindex(index, i); + ecount = git_index_entrycount(index); + if (!ecount) + printf("Empty index\n"); - oid = e->oid; - git_oid_fmt(out, &oid); + for (i = 0; i < ecount; ++i) { + const git_index_entry *e = git_index_get_byindex(index, i); - printf("File Path: %s\n", e->path); - printf(" Stage: %d\n", git_index_entry_stage(e)); - printf(" Blob SHA: %s\n", out); - printf("File Size: %d\n", (int)e->file_size); - printf(" Device: %d\n", (int)e->dev); - printf(" Inode: %d\n", (int)e->ino); - printf(" UID: %d\n", (int)e->uid); - printf(" GID: %d\n", (int)e->gid); - printf(" ctime: %d\n", (int)e->ctime.seconds); - printf(" mtime: %d\n", (int)e->mtime.seconds); - printf("\n"); - } + git_oid_fmt(out, &e->oid); - git_index_free(index); + printf("File Path: %s\n", e->path); + printf(" Stage: %d\n", git_index_entry_stage(e)); + printf(" Blob SHA: %s\n", out); + printf("File Size: %d\n", (int)e->file_size); + printf(" Device: %d\n", (int)e->dev); + printf(" Inode: %d\n", (int)e->ino); + printf(" UID: %d\n", (int)e->uid); + printf(" GID: %d\n", (int)e->gid); + printf(" ctime: %d\n", (int)e->ctime.seconds); + printf(" mtime: %d\n", (int)e->mtime.seconds); + printf("\n"); + } - git_repository_free(repo); + git_index_free(index); + git_repository_free(repo); + + return 0; } diff --git a/include/git2/refs.h b/include/git2/refs.h index 001c2bcc7..bc3f44482 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -22,13 +22,16 @@ GIT_BEGIN_DECL /** - * Lookup a reference by its name in a repository. + * Lookup a reference by name in a repository. * - * The generated reference must be freed by the user. + * The returned reference must be freed by the user. + * + * See `git_reference_create_symbolic()` for documentation about valid + * reference names. * * @param reference_out pointer to the looked-up reference * @param repo the repository to look up the reference - * @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...) + * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...) * @return 0 or an error code */ GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name); @@ -36,6 +39,10 @@ GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_reposito /** * Lookup a reference by name and resolve immediately to OID. * + * This function provides a quick way to resolve a reference name straight + * through to the object id that it refers to. This avoids having to + * allocate or free any `git_reference` objects for simple situations. + * * @param oid 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 @@ -47,13 +54,24 @@ GIT_EXTERN(int) git_reference_name_to_oid( /** * Create a new symbolic reference. * - * The reference will be created in the repository and written - * to the disk. + * A symbolic reference is a reference name that refers to another + * reference name. If the other name moves, the symbolic name will move, + * too. As a simple example, the "HEAD" reference might refer to + * "refs/heads/master" while on the "master" branch of a repository. * - * The generated reference must be freed by the user. + * The symbolic reference will be created in the repository and written to + * the disk. The generated reference object must be freed by the user. * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. + * Valid reference names must follow one of two patterns: + * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * This function will return an error if a reference already exists with the + * given name unless `force` is true, in which case it will be overwritten. * * @param ref_out Pointer to the newly created reference * @param repo Repository where that reference will live @@ -65,15 +83,27 @@ GIT_EXTERN(int) git_reference_name_to_oid( GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force); /** - * Create a new object id reference. + * Create a new direct reference. * - * The reference will be created in the repository and written - * to the disk. + * A direct reference (also called an object id reference) refers directly + * to a specific object id (a.k.a. OID or SHA) in the repository. The id + * permanently refers to the object (although the reference itself can be + * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0" + * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977. * - * The generated reference must be freed by the user. + * The direct reference will be created in the repository and written to + * the disk. The generated reference object must be freed by the user. * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. + * Valid reference names must follow one of two patterns: + * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * This function will return an error if a reference already exists with the + * given name unless `force` is true, in which case it will be overwritten. * * @param ref_out Pointer to the newly created reference * @param repo Repository where that reference will live @@ -85,9 +115,14 @@ GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repos GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force); /** - * Get the OID pointed to by a reference. + * Get the OID pointed to by a direct reference. * - * Only available if the reference is direct (i.e. not symbolic) + * Only available if the reference is direct (i.e. an object id reference, + * not a symbolic one). + * + * To find the OID of a symbolic ref, call `git_reference_resolve()` and + * then this function (or maybe use `git_reference_name_to_oid()` to + * directly resolve a reference name all the way through to an OID). * * @param ref The reference * @return a pointer to the oid if available, NULL otherwise @@ -95,9 +130,9 @@ GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref); /** - * Get full name to the reference pointed by this reference + * Get full name to the reference pointed to by a symbolic reference. * - * Only available if the reference is symbolic + * Only available if the reference is symbolic. * * @param ref The reference * @return a pointer to the name if available, NULL otherwise @@ -105,7 +140,7 @@ GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref); GIT_EXTERN(const char *) git_reference_target(git_reference *ref); /** - * Get the type of a reference + * Get the type of a reference. * * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC) * @@ -115,7 +150,9 @@ GIT_EXTERN(const char *) git_reference_target(git_reference *ref); GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref); /** - * Get the full name of a reference + * Get the full name of a reference. + * + * See `git_reference_create_symbolic()` for rules about valid names. * * @param ref The reference * @return the full name for the ref @@ -123,18 +160,16 @@ GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref); GIT_EXTERN(const char *) git_reference_name(git_reference *ref); /** - * Resolve a symbolic reference + * Resolve a symbolic reference to a direct reference. * - * This method iteratively peels a symbolic reference - * until it resolves to a direct reference to an OID. + * This method iteratively peels a symbolic reference until it resolves to + * a direct reference to an OID. * - * The peeled reference is returned in the `resolved_ref` - * argument, and must be freed manually once it's no longer - * needed. + * The peeled reference is returned in the `resolved_ref` argument, and + * must be freed manually once it's no longer needed. * - * If a direct reference is passed as an argument, - * a copy of that reference is returned. This copy must - * be manually freed too. + * If a direct reference is passed as an argument, a copy of that + * reference is returned. This copy must be manually freed too. * * @param resolved_ref Pointer to the peeled reference * @param ref The reference @@ -143,7 +178,7 @@ GIT_EXTERN(const char *) git_reference_name(git_reference *ref); GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref); /** - * Get the repository where a reference resides + * Get the repository where a reference resides. * * @param ref The reference * @return a pointer to the repo @@ -153,11 +188,9 @@ GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref); /** * Set the symbolic target of a reference. * - * The reference must be a symbolic reference, otherwise - * this method will fail. + * The reference must be a symbolic reference, otherwise this will fail. * - * The reference will be automatically updated in - * memory and on disk. + * The reference will be automatically updated in memory and on disk. * * @param ref The reference * @param target The new target for the reference @@ -168,11 +201,9 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target) /** * Set the OID target of a reference. * - * The reference must be a direct reference, otherwise - * this method will fail. + * The reference must be a direct reference, otherwise this will fail. * - * The reference will be automatically updated in - * memory and on disk. + * The reference will be automatically updated in memory and on disk. * * @param ref The reference * @param id The new target OID for the reference @@ -181,7 +212,7 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target) GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); /** - * Rename an existing reference + * Rename an existing reference. * * This method works for both direct and symbolic references. * The new name will be checked for validity and may be @@ -189,8 +220,7 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); * * The given git_reference will be updated in place. * - * The reference will be immediately renamed in-memory - * and on disk. + * The reference will be immediately renamed in-memory and on disk. * * If the `force` flag is not enabled, and there's already * a reference with the given name, the renaming will fail. @@ -209,12 +239,12 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force); /** - * Delete an existing reference + * Delete an existing reference. * * This method works for both direct and symbolic references. * - * The reference will be immediately removed on disk and from - * memory. The given reference pointer will no longer be valid. + * The reference will be immediately removed on disk and from memory + * (i.e. freed). The given reference pointer will no longer be valid. * * @param ref The reference to remove * @return 0 or an error code @@ -222,7 +252,7 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i GIT_EXTERN(int) git_reference_delete(git_reference *ref); /** - * Pack all the loose references in the repository + * Pack all the loose references in the repository. * * This method will load into the cache all the loose * references on the repository and update the @@ -237,44 +267,42 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref); GIT_EXTERN(int) git_reference_packall(git_repository *repo); /** - * Fill a list with all the references that can be found - * in a repository. + * Fill a list with all the references that can be found in a repository. * - * The listed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * Using the `list_flags` parameter, the listed references may be filtered + * by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of + * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. + * For convenience, use the value `GIT_REF_LISTALL` to obtain all + * references, including packed ones. * - * The string array will be filled with the names of all - * references; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. + * The string array will be filled with the names of all references; these + * values are owned by the user and should be free'd manually when no + * longer needed, using `git_strarray_free()`. * * @param array Pointer to a git_strarray structure where * the reference names will be stored * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. + * @param list_flags Filtering flags for the reference listing * @return 0 or an error code */ GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags); /** - * Perform an operation on each reference in the repository + * Perform a callback on each reference in the repository. * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * Using the `list_flags` parameter, the references may be filtered by + * type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of + * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. + * For convenience, use the value `GIT_REF_LISTALL` to obtain all + * references, including packed ones. * - * The `callback` function will be called for each of the references - * in the repository, and will receive the name of the reference and - * the `payload` value passed to this method. Returning a non-zero - * value from the callback will terminate the iteration. + * The `callback` function will be called for each reference in the + * repository, receiving the name of the reference and the `payload` value + * passed to this method. Returning a non-zero value from the callback + * will terminate the iteration. * * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. + * @param list_flags Filtering flags for the reference listing. * @param callback Function which will be called for every listed ref * @param payload Additional data to pass to the callback * @return 0 on success, GIT_EUSER on non-zero callback, or error code @@ -282,7 +310,7 @@ GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, un GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload); /** - * Check if a reference has been loaded from a packfile + * Check if a reference has been loaded from a packfile. * * @param ref A git reference * @return 0 in case it's not packed; 1 otherwise @@ -290,19 +318,17 @@ GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_fl GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); /** - * Reload a reference from disk + * Reload a reference from disk. * - * Reference pointers may become outdated if the Git - * repository is accessed simultaneously by other clients - * while the library is open. + * Reference pointers can become outdated if the Git repository is + * accessed simultaneously by other clients while the library is open. * - * This method forces a reload of the reference from disk, - * to ensure that the provided information is still - * reliable. + * This method forces a reload of the reference from disk, to ensure that + * the provided information is still reliable. * - * If the reload fails (e.g. the reference no longer exists - * on disk, or has become corrupted), an error code will be - * returned and the reference pointer will be invalidated. + * If the reload fails (e.g. the reference no longer exists on disk, or + * has become corrupted), an error code will be returned and the reference + * pointer will be invalidated and freed. * * @param ref The reference to reload * @return 0 on success, or an error code @@ -310,7 +336,7 @@ GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); GIT_EXTERN(int) git_reference_reload(git_reference *ref); /** - * Free the given reference + * Free the given reference. * * @param ref git_reference */ @@ -326,36 +352,30 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref); GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); /** - * Loop over all the references and issue a callback for each one - * which name matches the given glob pattern. + * Perform a callback on each reference in the repository whose name + * matches the given pattern. * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. + * This function acts like `git_reference_foreach()` with an additional + * pattern match being applied to the reference name before issuing the + * callback function. See that function for more information. * - * @param repo Repository where to find the references. + * The pattern is matched using fnmatch or "glob" style where a '*' matches + * any sequence of letters, a '?' matches any letter, and square brackets + * can be used to define character ranges (such as "[0-9]" for digits). * - * @param glob Glob pattern references should match. - * - * @param list_flags Filtering flags for the reference - * listing. - * - * @param callback Callback to invoke per found reference. - * - * @param payload Extra parameter to callback function. - * - * @return 0 or an error code. + * @param repo Repository where to find the refs + * @param glob Pattern to match (fnmatch-style) against reference name. + * @param list_flags Filtering flags for the reference listing. + * @param callback Function which will be called for every listed ref + * @param payload Additional data to pass to the callback + * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_reference_foreach_glob( - git_repository *repo, - const char *glob, - unsigned int list_flags, - int (*callback)( - const char *reference_name, - void *payload), - void *payload -); + git_repository *repo, + const char *glob, + unsigned int list_flags, + int (*callback)(const char *reference_name, void *payload), + void *payload); /** * Check if a reflog exists for the specified reference. @@ -387,7 +407,8 @@ GIT_EXTERN(int) git_reference_is_branch(git_reference *ref); */ GIT_EXTERN(int) git_reference_is_remote(git_reference *ref); -enum { + +typedef enum { GIT_REF_FORMAT_NORMAL = 0, /** @@ -406,27 +427,25 @@ enum { * (e.g., foo//bar but not foo/bar). */ GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1), -}; +} git_reference_normalize_t; /** - * Normalize the reference name by removing any leading - * slash (/) characters and collapsing runs of adjacent slashes - * between name components into a single slash. + * Normalize reference name and check validity. * - * Once normalized, if the reference name is valid, it will be - * returned in the user allocated buffer. + * This will normalize the reference name by removing any leading slash + * '/' characters and collapsing runs of adjacent slashes between name + * components into a single slash. * - * @param buffer_out The user allocated buffer where the - * normalized name will be stored. + * Once normalized, if the reference name is valid, it will be returned in + * the user allocated buffer. * - * @param buffer_size buffer_out size - * - * @param name name to be checked. - * - * @param flags Flags to determine the options to be applied while - * checking the validatity of the name. - * - * @return 0 or an error code. + * @param buffer_out User allocated buffer to store normalized name + * @param buffer_size Size of buffer_out + * @param name Reference name to be checked. + * @param flags Flags to constrain name validation rules - see the + * GIT_REF_FORMAT constants above. + * @return 0 on success or error code (GIT_EBUFS if buffer is too small, -1 + * if reference is invalid) */ GIT_EXTERN(int) git_reference_normalize_name( char *buffer_out, @@ -435,8 +454,7 @@ GIT_EXTERN(int) git_reference_normalize_name( unsigned int flags); /** - * Recursively peel an reference until an object of the - * specified type is met. + * Recursively peel reference until object of the specified type is found. * * The retrieved `peeled` object is owned by the repository * and should be closed with the `git_object_free` method. @@ -457,12 +475,18 @@ GIT_EXTERN(int) git_reference_peel( /** * Ensure the reference name is well-formed. * - * @param refname name to be checked. + * Valid reference names must follow one of two patterns: * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * @param refname name to be checked. * @return 1 if the reference name is acceptable; 0 if it isn't */ -GIT_EXTERN(int) git_reference_is_valid_name( - const char *refname); +GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); /** @} */ GIT_END_DECL diff --git a/include/git2/status.h b/include/git2/status.h index 979e6e4ff..8c59d768d 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -19,6 +19,16 @@ */ GIT_BEGIN_DECL +/** + * Status flags for a single file. + * + * A combination of these values will be returned to indicate the status of + * a file. Status compares the working directory, the index, and the + * current HEAD of the repository. The `GIT_STATUS_INDEX` set of flags + * represents the status of file in the index relative to the HEAD, and the + * `GIT_STATUS_WT` set of flags represent the status of the file in the + * working directory relative to the index. + */ typedef enum { GIT_STATUS_CURRENT = 0, @@ -39,12 +49,16 @@ typedef enum { /** * Gather file statuses and run a callback for each one. * - * The callback is passed the path of the file, the status and the data - * pointer passed to this function. If the callback returns something other - * than 0, this function will stop looping and return GIT_EUSER. + * The callback is passed the path of the file, the status (a combination of + * the `git_status_t` values above) and the `payload` data pointer passed + * into this function. * - * @param repo a repository object - * @param callback the function to call on each file + * If the callback returns a non-zero value, this function will stop looping + * and return GIT_EUSER. + * + * @param repo A repository object + * @param callback The function to call on each file + * @param payload Pointer to pass through to callback function * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_status_foreach( @@ -53,7 +67,7 @@ GIT_EXTERN(int) git_status_foreach( void *payload); /** - * Select the files on which to report status. + * For extended status, select the files on which to report status. * * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the * rough equivalent of `git status --porcelain` where each file @@ -81,40 +95,55 @@ typedef enum { /** * Flags to control status callbacks * - * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should - * be made on untracked files. These will only be made if the - * workdir files are included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should - * get callbacks. Again, these callbacks will only be made if - * the workdir files are included in the status "show" option. - * Right now, there is no option to include all files in - * directories that are ignored completely. - * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback - * should be made even on unmodified files. - * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories - * which appear to be submodules should just be skipped over. - * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the - * contents of untracked directories should be included in the - * status. Normally if an entire directory is new, then just - * the top-level directory will be included (with a trailing - * slash on the entry name). Given this flag, the directory - * itself will not be included, but all the files in it will. - * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given - * path will be treated as a literal path, and not as a pathspec. + * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made + * on untracked files. These will only be made if the workdir files are + * included in the status "show" option. + * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should get + * callbacks. Again, these callbacks will only be made if the workdir + * files are included in the status "show" option. Right now, there is + * no option to include all files in directories that are ignored + * completely. + * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be + * made even on unmodified files. + * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories which + * appear to be submodules should just be skipped over. + * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the contents of + * untracked directories should be included in the status. Normally if + * an entire directory is new, then just the top-level directory will be + * included (with a trailing slash on the entry name). Given this flag, + * the directory itself will not be included, but all the files in it + * will. + * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path + * will be treated as a literal path, and not as a pathspec. + * + * Calling `git_status_foreach()` is like calling the extended version + * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED, + * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. */ - -enum { +typedef enum { GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0), GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1), GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5), -}; +} git_status_opt_t; /** - * Options to control how callbacks will be made by - * `git_status_foreach_ext()`. + * Options to control how `git_status_foreach_ext()` will issue callbacks. + * + * This structure is set so that zeroing it out will give you relatively + * sane defaults. + * + * The `show` value is one of the `git_status_show_t` constants that + * control which files to scan and in what order. + * + * The `flags` value is an OR'ed combination of the `git_status_opt_t` + * values above. + * + * The `pathspec` is an array of path patterns to match (using + * fnmatch-style matching), or just an array of paths to match exactly if + * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags. */ typedef struct { git_status_show_t show; @@ -124,6 +153,17 @@ typedef struct { /** * Gather file status information and run callbacks as requested. + * + * This is an extended version of the `git_status_foreach()` API that + * allows for more granular control over which paths will be processed and + * in what order. See the `git_status_options` structure for details + * about the additional controls that this makes available. + * + * @param repo Repository object + * @param opts Status options structure + * @param callback The function to call on each file + * @param payload Pointer to pass through to callback function + * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_status_foreach_ext( git_repository *repo, @@ -132,14 +172,17 @@ GIT_EXTERN(int) git_status_foreach_ext( void *payload); /** - * Get file status for a single file + * Get file status for a single file. * - * @param status_flags the status value - * @param repo a repository object - * @param path the file to retrieve status for, rooted at the repo's workdir - * @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when - * the file doesn't exist in any of HEAD, the index or the worktree, - * 0 otherwise + * This is not quite the same as calling `git_status_foreach_ext()` with + * the pathspec set to the specified path. + * + * @param status_flags The status value for the file + * @param repo A repository object + * @param path The file to retrieve status for, rooted at the repo's workdir + * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD, + * index, and work tree, GIT_EINVALIDPATH if `path` points at a folder, + * GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error. */ GIT_EXTERN(int) git_status_file( unsigned int *status_flags, @@ -156,9 +199,9 @@ GIT_EXTERN(int) git_status_file( * One way to think of this is if you were to do "git add ." on the * directory containing the file, would it be added or not? * - * @param ignored boolean returning 0 if the file is not ignored, 1 if it is - * @param repo a repository object - * @param path the file to check ignores for, rooted at the repo's workdir. + * @param ignored Boolean returning 0 if the file is not ignored, 1 if it is + * @param repo A repository object + * @param path The file to check ignores for, rooted at the repo's workdir. * @return 0 if ignore rules could be processed for the file (regardless * of whether it exists or not), or an error < 0 if they could not. */ diff --git a/src/refs.c b/src/refs.c index 779d6080f..bbf30ed9e 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1949,10 +1949,10 @@ int git_reference_peel( peel_error(error, ref, "Cannot retrieve reference target"); goto cleanup; } - + if (target_type == GIT_OBJ_ANY && git_object_type(target) != GIT_OBJ_TAG) error = git_object__dup(peeled, target); - else + else error = git_object_peel(peeled, target, target_type); cleanup: diff --git a/src/status.c b/src/status.c index f57100d11..2d022bfda 100644 --- a/src/status.c +++ b/src/status.c @@ -217,7 +217,7 @@ static int get_one_status(const char *path, unsigned int status, void *data) sfi->count++; sfi->status = status; - if (sfi->count > 1 || + if (sfi->count > 1 || (strcmp(sfi->expected, path) != 0 && p_fnmatch(sfi->expected, path, 0) != 0)) { giterr_set(GITERR_INVALID, diff --git a/tests-clar/network/fetch.c b/tests-clar/network/fetch.c index be1a21c54..d2140b5f4 100644 --- a/tests-clar/network/fetch.c +++ b/tests-clar/network/fetch.c @@ -18,10 +18,7 @@ void test_network_fetch__cleanup(void) static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data) { - refname = refname; - a = a; - b = b; - data = data; + GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b); GIT_UNUSED(data); ++counter;