diff options
89 files changed, 812 insertions, 377 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a228e342..402ff2226 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,9 @@ ENDIF() IF (ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS}) LINK_LIBRARIES(${ZLIB_LIBRARIES}) -ELSE() + # Fake the message CMake would have shown + MESSAGE("-- Found zlib: ${ZLIB_LIBRARY}") +ELSEIF (NOT ZLIB_LIBRARY) MESSAGE( "zlib was not found; using bundled 3rd-party sources." ) INCLUDE_DIRECTORIES(deps/zlib) ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP) diff --git a/examples/general.c b/examples/general.c index adc7ed8d2..d7a58479c 100644 --- a/examples/general.c +++ b/examples/general.c @@ -453,7 +453,7 @@ int main (int argc, char** argv) // Here we will implement something like `git for-each-ref` simply listing // out all available references and the object SHA they resolve to. git_strarray ref_list; - git_reference_list(&ref_list, repo, GIT_REF_LISTALL); + git_reference_list(&ref_list, repo); const char *refname; git_reference *ref; diff --git a/include/git2/refs.h b/include/git2/refs.h index e1d425352..754bda785 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -55,6 +55,19 @@ 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 shrothand 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 @@ -284,12 +297,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()`. @@ -297,36 +304,27 @@ 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); /** * 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); @@ -347,6 +345,31 @@ 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); + +/** + * Get the next reference name + * + * @param out pointer in which to store the string + * @param iter the iterator + * @param 0, GIT_ITEROVER if there are no more; or an error code + */ +GIT_EXTERN(int) git_reference_next(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. * @@ -360,7 +383,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 @@ -368,7 +390,6 @@ 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, void *payload); diff --git a/include/git2/repository.h b/include/git2/repository.h index cd238e17c..e0464c63f 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -460,10 +460,19 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo); * Use this function to get the contents of this file. Don't forget to * remove the file after you create the commit. * + * If the repository message exists and there are no errors reading it, this + * returns the bytes needed to store the message in memory (i.e. message + * file size plus one terminating NUL byte). That value is returned even if + * `out` is NULL or `len` is shorter than the necessary size. + * + * The `out` buffer will *always* be NUL terminated, even if truncation + * occurs. + * * @param out Buffer to write data into or NULL to just read required size - * @param len Length of 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); diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h index d5f599fec..8dbf38ca9 100644 --- a/include/git2/sys/refdb_backend.h +++ b/include/git2/sys/refdb_backend.h @@ -20,6 +20,23 @@ */ 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_backend *backend; + char *glob; +}; + /** An instance for a custom backend */ struct git_refdb_backend { unsigned int version; @@ -43,29 +60,42 @@ struct git_refdb_backend { const char *ref_name); /** - * Enumerates each reference in the refdb. A refdb implementation must - * provide this function. + * Allocate an iterator object for the backend. + * + * A refdb implementation must provide this function. */ - int (*foreach)( - git_refdb_backend *backend, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); + int (*iterator)( + git_reference_iterator **iter, + struct git_refdb_backend *backend); /** - * 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. + * Allocate a glob-filtering iterator object for the backend. + * + * A refdb implementation may provide this function. If it's + * not available, the glob matching will be done by the frontend. */ - int (*foreach_glob)( - git_refdb_backend *backend, - const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); + int (*iterator_glob)( + git_reference_iterator **iter, + struct git_refdb_backend *backend, + const char *glob); + + /** + * Return the current value and advance the iterator. + * + * A refdb implementation must provide this function. + */ + int (*next)( + const char **name, + git_reference_iterator *iter); /** + * Free the iterator + * + * A refdb implementation must provide this function. + */ + void (*iterator_free)( + git_reference_iterator *iter); + /* * Writes the given reference to the refdb. A refdb implementation * must provide this function. */ diff --git a/include/git2/types.h b/include/git2/types.h index aca9ed927..43751d3b0 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -165,6 +165,10 @@ 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; + + /** Basic type of any Git reference. */ typedef enum { GIT_REF_INVALID = 0, /** Invalid reference */ diff --git a/src/branch.c b/src/branch.c index 830294941..dd6dc68f4 100644 --- a/src/branch.c +++ b/src/branch.c @@ -124,40 +124,43 @@ on_error: return error; } -typedef struct { - git_branch_foreach_cb branch_cb; - void *callback_payload; - unsigned int branch_type; -} branch_foreach_filter; - -static int branch_foreach_cb(const char *branch_name, void *payload) -{ - branch_foreach_filter *filter = (branch_foreach_filter *)payload; - - if (filter->branch_type & GIT_BRANCH_LOCAL && - git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0) - return filter->branch_cb(branch_name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, filter->callback_payload); - - if (filter->branch_type & GIT_BRANCH_REMOTE && - git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0) - return filter->branch_cb(branch_name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, filter->callback_payload); - - return 0; -} - int git_branch_foreach( git_repository *repo, unsigned int list_flags, - git_branch_foreach_cb branch_cb, + git_branch_foreach_cb callback, void *payload) { - branch_foreach_filter filter; + git_reference_iterator *iter; + const char *name; + int error; + + if (git_reference_iterator_new(&iter, repo) < 0) + return -1; + + while ((error = git_reference_next(&name, iter)) == 0) { + if (list_flags & GIT_BRANCH_LOCAL && + git__prefixcmp(name, GIT_REFS_HEADS_DIR) == 0) { + if (callback(name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, payload)) { + error = GIT_EUSER; + break; + } + } + + if (list_flags & GIT_BRANCH_REMOTE && + git__prefixcmp(name, GIT_REFS_REMOTES_DIR) == 0) { + if (callback(name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, payload)) { + error = GIT_EUSER; + break; + } + } + } - filter.branch_cb = branch_cb; - filter.branch_type = list_flags; - filter.callback_payload = payload; + if (error == GIT_ITEROVER) + error = 0; + + git_reference_iterator_free(iter); + return error; - return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter); } int git_branch_move( diff --git a/src/clone.c b/src/clone.c index 38c0d409e..499195dcc 100644 --- a/src/clone.c +++ b/src/clone.c @@ -243,7 +243,6 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) /* Not master. Check all the other refs. */ if (git_reference_foreach( repo, - GIT_REF_LISTALL, reference_matches_remote_head, &head_info) < 0) goto cleanup; @@ -355,7 +354,7 @@ static int setup_remotes_and_fetch( const git_clone_options *options) { int retcode = GIT_ERROR; - git_remote *origin; + git_remote *origin = NULL; /* Construct an origin remote */ if ((retcode = create_and_configure_origin(&origin, repo, url, options)) < 0) diff --git a/src/commit.c b/src/commit.c index 3dc647c9b..be6e32c76 100644 --- a/src/commit.c +++ b/src/commit.c @@ -292,7 +292,7 @@ int git_commit_nth_gen_ancestor( const git_commit *commit, unsigned int n) { - git_commit *current, *parent; + git_commit *current, *parent = NULL; int error; assert(ancestor && commit); diff --git a/src/config_file.c b/src/config_file.c index a9a40c366..e57cd1e53 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -296,7 +296,7 @@ cleanup: static int config_set(git_config_backend *cfg, const char *name, const char *value) { - cvar_t *var = NULL, *old_var; + cvar_t *var = NULL, *old_var = NULL; diskfile_backend *b = (diskfile_backend *)cfg; char *key, *esc_value = NULL; khiter_t pos; diff --git a/src/diff.c b/src/diff.c index e0dff9c95..f466546bb 100644 --- a/src/diff.c +++ b/src/diff.c @@ -535,7 +535,7 @@ cleanup: static bool diff_time_eq( const git_index_time *a, const git_index_time *b, bool use_nanos) { - return a->seconds == a->seconds && + return a->seconds == b->seconds && (!use_nanos || a->nanoseconds == b->nanoseconds); } diff --git a/src/diff_output.c b/src/diff_output.c index 2214ae1b5..07fcf47a7 100644 --- a/src/diff_output.c +++ b/src/diff_output.c @@ -593,6 +593,8 @@ static int diff_patch_load( delta->new_file.flags |= GIT_DIFF_FLAG__NO_DATA; break; case GIT_DELTA_MODIFIED: + case GIT_DELTA_COPIED: + case GIT_DELTA_RENAMED: break; case GIT_DELTA_UNTRACKED: delta->old_file.flags |= GIT_DIFF_FLAG__NO_DATA; diff --git a/src/object.c b/src/object.c index a6807f26b..9b8ccdd3e 100644 --- a/src/object.c +++ b/src/object.c @@ -117,7 +117,7 @@ int git_object_lookup_prefix( { git_object *object = NULL; git_odb *odb = NULL; - git_odb_object *odb_obj; + git_odb_object *odb_obj = NULL; int error = 0; assert(repo && object_out && id); diff --git a/src/push.c b/src/push.c index 0499d8648..452d71789 100644 --- a/src/push.c +++ b/src/push.c @@ -180,7 +180,7 @@ int git_push_update_tips(git_push *push) git_buf remote_ref_name = GIT_BUF_INIT; size_t i, j; git_refspec *fetch_spec; - push_spec *push_spec; + push_spec *push_spec = NULL; git_reference *remote_ref; push_status *status; int error = 0; diff --git a/src/refdb.c b/src/refdb.c index 33a1934d1..9f9037ce7 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -124,60 +124,70 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name) return error; } -int git_refdb_foreach( - git_refdb *db, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload) +int git_refdb_iterator(git_reference_iterator **out, git_refdb *db) { - assert(db && db->backend); + if (!db->backend || !db->backend->iterator) { + giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators"); + return -1; + } - return db->backend->foreach(db->backend, list_flags, callback, payload); -} + if (db->backend->iterator(out, db->backend) < 0) + return -1; -struct glob_cb_data { - const char *glob; - git_reference_foreach_cb callback; - void *payload; -}; + return 0; +} -static int fromglob_cb(const char *reference_name, void *payload) +int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob) { - struct glob_cb_data *data = (struct glob_cb_data *)payload; + if (!db->backend) { + giterr_set(GITERR_REFERENCE, "There are no backends loaded"); + return -1; + } - if (!p_fnmatch(data->glob, reference_name, 0)) - return data->callback(reference_name, data->payload); + if (db->backend->iterator_glob) + return db->backend->iterator_glob(out, db->backend, glob); + + /* If the backend doesn't support glob-filtering themselves, we have to do it */ + if (db->backend->iterator(out, db->backend) < 0) + return -1; + + (*out)->glob = git__strdup(glob); + if (!(*out)->glob) { + db->backend->iterator_free(*out); + return -1; + } return 0; } -int git_refdb_foreach_glob( - git_refdb *db, - const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload) +int git_refdb_next(const char **out, git_reference_iterator *iter) { int error; - struct glob_cb_data data; - assert(db && db->backend && glob && callback); + if (!iter->glob) + return iter->backend->next(out, iter); - if(db->backend->foreach_glob != NULL) - error = db->backend->foreach_glob(db->backend, - glob, list_flags, callback, payload); - else { - data.glob = glob; - data.callback = callback; - data.payload = payload; - - error = db->backend->foreach(db->backend, - list_flags, fromglob_cb, &data); + /* If the iterator has a glob, we need to filter */ + while ((error = iter->backend->next(out, iter)) == 0) { + if (!p_fnmatch(iter->glob, *out, 0)) + break; } return error; } +void git_refdb_iterator_free(git_reference_iterator *iter) +{ + git__free(iter->glob); + iter->backend->iterator_free(iter); +} + +struct glob_cb_data { + const char *glob; + git_reference_foreach_cb callback; + void *payload; +}; + int git_refdb_write(git_refdb *db, const git_reference *ref) { assert(db && db->backend); diff --git a/src/refdb.h b/src/refdb.h index 047113ac8..2edd05d18 100644 --- a/src/refdb.h +++ b/src/refdb.h @@ -26,18 +26,10 @@ int git_refdb_lookup( git_refdb *refdb, const char *ref_name); -int git_refdb_foreach( - git_refdb *refdb, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); - -int git_refdb_foreach_glob( - git_refdb *refdb, - const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); +int git_refdb_iterator(git_reference_iterator **out, git_refdb *db); +int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob); +int git_refdb_next(const char **out, git_reference_iterator *iter); +void git_refdb_iterator_free(git_reference_iterator *iter); int git_refdb_write(git_refdb *refdb, const git_reference *ref); diff --git a/src/refdb_fs.c b/src/refdb_fs.c index c0a32bae7..c462a4251 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -13,6 +13,7 @@ #include "reflog.h" #include "refdb.h" #include "refdb_fs.h" +#include "iterator.h" #include <git2/tag.h> #include <git2/object.h> @@ -106,7 +107,7 @@ static int packed_parse_oid( refname_len = refname_end - refname_begin; - ref = git__malloc(sizeof(struct packref) + refname_len + 1); + ref = git__calloc(1, sizeof(struct packref) + refname_len + 1); GITERR_CHECK_ALLOC(ref); memcpy(ref->name, refname_begin, refname_len); @@ -180,6 +181,9 @@ static int packed_load(refdb_fs_backend *backend) GITERR_CHECK_ALLOC(ref_cache->packfile); } + if (backend->path == NULL) + return 0; + result = reference_read(&packfile, &ref_cache->packfile_time, backend->path, GIT_PACKEDREFS_FILE, &updated); @@ -316,7 +320,7 @@ static int loose_lookup_to_packfile( git_buf_rtrim(&ref_file); name_len = strlen(name); - ref = git__malloc(sizeof(struct packref) + name_len + 1); + ref = git__calloc(1, sizeof(struct packref) + name_len + 1); GITERR_CHECK_ALLOC(ref); memcpy(ref->name, name, name_len); @@ -558,98 +562,129 @@ struct dirent_list_data { int callback_error; }; -static git_ref_t loose_guess_rtype(const git_buf *full_path) +typedef struct { + git_reference_iterator parent; + unsigned int loose; + /* packed */ + git_strmap *h; + khiter_t k; + /* loose */ + git_iterator *fsiter; + git_buf buf; +} refdb_fs_iter; + +static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend) { - git_buf ref_file = GIT_BUF_INIT; - git_ref_t type; + refdb_fs_iter *iter; + refdb_fs_backend *backend; - type = GIT_REF_INVALID; + assert(_backend); + backend = (refdb_fs_backend *)_backend; - if (git_futils_readbuffer(&ref_file, full_path->ptr) == 0) { - if (git__prefixcmp((const char *)(ref_file.ptr), GIT_SYMREF) == 0) - type = GIT_REF_SYMBOLIC; - else - type = GIT_REF_OID; - } + if (packed_load(backend) < 0) + return -1; - git_buf_free(&ref_file); - return type; + iter = git__calloc(1, sizeof(refdb_fs_iter)); + GITERR_CHECK_ALLOC(iter); + + iter->parent.backend = _backend; + iter->h = backend->refcache.packfile; + iter->k = kh_begin(backend->refcache.packfile); + + *out = (git_reference_iterator *)iter; + + return 0; } -static int _dirent_loose_listall(void *_data, git_buf *full_path) +static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) { - struct dirent_list_data *data = (struct dirent_list_data *)_data; - const char *file_path = full_path->ptr + data->repo_path_len; - - if (git_path_isdir(full_path->ptr) == true) - return git_path_direach(full_path, _dirent_loose_listall, _data); + refdb_fs_iter *iter = (refdb_fs_iter *) _iter; - /* do not add twice a reference that exists already in the packfile */ - if (git_strmap_exists(data->backend->refcache.packfile, file_path)) - return 0; + git_buf_free(&iter->buf); + git_iterator_free(iter->fsiter); + git__free(iter); +} - if (data->list_type != GIT_REF_LISTALL) { - if ((data->list_type & loose_guess_rtype(full_path)) == 0) - return 0; /* we are filtering out this reference */ +static int iter_packed(const char **out, refdb_fs_iter *iter) +{ + /* Move forward to the next entry */ + while (!kh_exist(iter->h, iter->k)) { + iter->k++; + if (iter->k == kh_end(iter->h)) + return GIT_ITEROVER; } - /* Locked references aren't returned */ - if (!git__suffixcmp(file_path, GIT_FILELOCK_EXTENSION)) - return 0; + *out = kh_key(iter->h, iter->k); + iter->k++; - if (data->callback(file_path, data->callback_payload)) - data->callback_error = GIT_EUSER; - - return data->callback_error; + return 0; } -static int refdb_fs_backend__foreach( - git_refdb_backend *_backend, - unsigned int list_type, - git_reference_foreach_cb callback, - void *payload) +static int iter_loose(const char **out, refdb_fs_iter *iter) { - refdb_fs_backend *backend; - int result; - struct dirent_list_data data; - git_buf refs_path = GIT_BUF_INIT; - const char *ref_name; - void *ref = NULL; + const git_index_entry *entry; + int retry; + git_strmap *packfile_refs; + refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend; - GIT_UNUSED(ref); + packfile_refs = backend->refcache.packfile; - assert(_backend); - backend = (refdb_fs_backend *)_backend; + do { + khiter_t pos; + if (git_iterator_current(&entry, iter->fsiter) < 0) + return -1; - if (packed_load(backend) < 0) - return -1; + git_buf_clear(&iter->buf); + if (!entry) + return GIT_ITEROVER; - /* list all the packed references first */ - if (list_type & GIT_REF_OID) { - git_strmap_foreach(backend->refcache.packfile, ref_name, ref, { - if (callback(ref_name, payload)) - return GIT_EUSER; - }); - } + if (git_buf_printf(&iter->buf, "refs/%s", entry->path) < 0) + return -1; - /* now list the loose references, trying not to - * duplicate the ref names already in the packed-refs file */ + git_iterator_advance(NULL, iter->fsiter); - data.repo_path_len = strlen(backend->path); - data.list_type = list_type; - data.backend = backend; - data.callback = callback; - data.callback_payload = payload; - data.callback_error = 0; + /* Skip this one if we already listed it in packed */ + pos = git_strmap_lookup_index(packfile_refs, git_buf_cstr(&iter->buf)); + retry = 0; + if (git_strmap_valid_index(packfile_refs, pos) || + !git_reference_is_valid_name(git_buf_cstr(&iter->buf))) + retry = 1; - if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0) + *out = git_buf_cstr(&iter->buf); + } while (retry); + + return 0; +} + +static int iter_loose_setup(refdb_fs_iter *iter) +{ + refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend; + + git_buf_clear(&iter->buf); + if (git_buf_printf(&iter->buf, "%s/refs", backend->path) < 0) return -1; - result = git_path_direach(&refs_path, _dirent_loose_listall, &data); + return git_iterator_for_filesystem(&iter->fsiter, git_buf_cstr(&iter->buf), 0, NULL, NULL); +} - git_buf_free(&refs_path); +static int refdb_fs_backend__next(const char **out, git_reference_iterator *_iter) +{ + refdb_fs_iter *iter = (refdb_fs_iter *)_iter; + + if (iter->loose) + return iter_loose(out, iter); - return data.callback_error ? GIT_EUSER : result; + if (iter->k != kh_end(iter->h)) { + int error = iter_packed(out, iter); + if (error != GIT_ITEROVER) + return error; + } + + if (iter_loose_setup(iter) < 0) + return -1; + iter->loose = 1; + + return iter_loose(out, iter); } static int loose_write(refdb_fs_backend *backend, const git_reference *ref) @@ -1027,6 +1062,10 @@ static int setup_namespace(git_buf *path, git_repository *repo) { char *parts, *start, *end; + /* Not all repositories have a path */ + if (repo->path_repository == NULL) + return 0; + /* Load the path to the repo first */ git_buf_puts(path, repo->path_repository); @@ -1081,7 +1120,9 @@ int git_refdb_backend_fs( backend->parent.exists = &refdb_fs_backend__exists; backend->parent.lookup = &refdb_fs_backend__lookup; - backend->parent.foreach = &refdb_fs_backend__foreach; + backend->parent.iterator = &refdb_fs_backend__iterator; + backend->parent.next = &refdb_fs_backend__next; + backend->parent.iterator_free = &refdb_fs_backend__iterator_free; backend->parent.write = &refdb_fs_backend__write; backend->parent.delete = &refdb_fs_backend__delete; backend->parent.compress = &refdb_fs_backend__compress; diff --git a/src/refs.c b/src/refs.c index 8bba3941e..9c6c5c623 100644 --- a/src/refs.c +++ b/src/refs.c @@ -139,7 +139,7 @@ static int reference_path_available( data.available = 1; error = git_reference_foreach( - repo, GIT_REF_LISTALL, _reference_available_cb, (void *)&data); + repo, _reference_available_cb, (void *)&data); if (error < 0) return error; @@ -290,6 +290,67 @@ int git_reference_lookup_resolved( return 0; } +int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname) +{ + int error = 0, i; + bool fallbackmode = true, foundvalid = false; + git_reference *ref; + git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; + + static const char* formatters[] = { + "%s", + GIT_REFS_DIR "%s", + GIT_REFS_TAGS_DIR "%s", + GIT_REFS_HEADS_DIR "%s", + GIT_REFS_REMOTES_DIR "%s", + GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE, + NULL + }; + + if (*refname) + git_buf_puts(&name, refname); + else { + git_buf_puts(&name, GIT_HEAD_FILE); + fallbackmode = false; + } + + for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) { + + git_buf_clear(&refnamebuf); + + if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0) + goto cleanup; + + if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) { + error = GIT_EINVALIDSPEC; + continue; + } + foundvalid = true; + + error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1); + + if (!error) { + *out = ref; + error = 0; + goto cleanup; + } + + if (error != GIT_ENOTFOUND) + goto cleanup; + } + +cleanup: + if (error && !foundvalid) { + /* never found a valid reference name */ + giterr_set(GITERR_REFERENCE, + "Could not use '%s' as valid reference name", git_buf_cstr(&name)); + } + + git_buf_free(&name); + git_buf_free(&refnamebuf); + return error; +} + /** * Getters */ @@ -558,14 +619,59 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref) int git_reference_foreach( git_repository *repo, - unsigned int list_flags, git_reference_foreach_cb callback, void *payload) { + git_reference_iterator *iter; + const char *name; + int error; + + if (git_reference_iterator_new(&iter, repo) < 0) + return -1; + + while ((error = git_reference_next(&name, iter)) == 0) { + if (callback(name, payload)) { + error = GIT_EUSER; + goto out; + } + } + + if (error == GIT_ITEROVER) + error = 0; + +out: + git_reference_iterator_free(iter); + return error; +} + +int git_reference_iterator_new(git_reference_iterator **out, git_repository *repo) +{ + git_refdb *refdb; + + if (git_repository_refdb__weakptr(&refdb, repo) < 0) + return -1; + + return git_refdb_iterator(out, refdb); +} + +int git_reference_iterator_glob_new(git_reference_iterator **out, git_repository *repo, const char *glob) +{ git_refdb *refdb; - git_repository_refdb__weakptr(&refdb, repo); - return git_refdb_foreach(refdb, list_flags, callback, payload); + if (git_repository_refdb__weakptr(&refdb, repo) < 0) + return -1; + + return git_refdb_iterator_glob(out, refdb, glob); +} + +int git_reference_next(const char **out, git_reference_iterator *iter) +{ + return git_refdb_next(out, iter); +} + +void git_reference_iterator_free(git_reference_iterator *iter) +{ + git_refdb_iterator_free(iter); } static int cb__reflist_add(const char *ref, void *data) @@ -575,8 +681,7 @@ static int cb__reflist_add(const char *ref, void *data) int git_reference_list( git_strarray *array, - git_repository *repo, - unsigned int list_flags) + git_repository *repo) { git_vector ref_list; @@ -589,7 +694,7 @@ int git_reference_list( return -1; if (git_reference_foreach( - repo, list_flags, &cb__reflist_add, (void *)&ref_list) < 0) { + repo, &cb__reflist_add, (void *)&ref_list) < 0) { git_vector_free(&ref_list); return -1; } @@ -889,19 +994,29 @@ int git_reference__update_terminal( int git_reference_foreach_glob( git_repository *repo, const char *glob, - unsigned int list_flags, - int (*callback)( - const char *reference_name, - void *payload), + git_reference_foreach_cb callback, void *payload) { - git_refdb *refdb; + git_reference_iterator *iter; + const char *name; + int error; - assert(repo && glob && callback); + if (git_reference_iterator_glob_new(&iter, repo, glob) < 0) + return -1; - git_repository_refdb__weakptr(&refdb, repo); + while ((error = git_reference_next(&name, iter)) == 0) { + if (callback(name, payload)) { + error = GIT_EUSER; + goto out; + } + } + + if (error == GIT_ITEROVER) + error = 0; - return git_refdb_foreach_glob(refdb, glob, list_flags, callback, payload); +out: + git_reference_iterator_free(iter); + return error; } int git_reference_has_log( diff --git a/src/remote.c b/src/remote.c index 692537636..e5a7df75e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -292,7 +292,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name) git_buf_clear(&buf); git_buf_printf(&buf, "remote.%s.pushurl", name); - if ((error = get_optional_config(config, &buf, NULL, &val)) < 0) + if ((error = get_optional_config(config, &buf, NULL, (void *)&val)) < 0) goto cleanup; if (val) { @@ -1251,14 +1251,6 @@ static int update_branch_remote_config_entry( update_config_entries_cb, &data); } -static int rename_cb(const char *ref, void *data) -{ - if (git__prefixcmp(ref, GIT_REFS_REMOTES_DIR)) - return 0; - - return git_vector_insert((git_vector *)data, git__strdup(ref)); -} - static int rename_one_remote_reference( git_repository *repo, const char *reference_name, @@ -1298,16 +1290,29 @@ static int rename_remote_references( int error = -1; unsigned int i; char *name; + const char *refname; + git_reference_iterator *iter; if (git_vector_init(&refnames, 8, NULL) < 0) + return -1; + + if (git_reference_iterator_new(&iter, repo) < 0) goto cleanup; - if (git_reference_foreach( - repo, - GIT_REF_LISTALL, - rename_cb, - &refnames) < 0) - goto cleanup; + while ((error = git_reference_next(&refname, iter)) == 0) { + if (git__prefixcmp(refname, GIT_REFS_REMOTES_DIR)) + continue; + + if ((error = git_vector_insert(&refnames, git__strdup(refname))) < 0) + break; + + } + + git_reference_iterator_free(iter); + if (error == GIT_ITEROVER) + error = 0; + else + goto cleanup; git_vector_foreach(&refnames, i, name) { if ((error = rename_one_remote_reference(repo, name, old_name, new_name)) < 0) diff --git a/src/repository.c b/src/repository.c index e2cedc0f7..4ab3921bb 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1473,7 +1473,7 @@ static int at_least_one_cb(const char *refname, void *payload) static int repo_contains_no_reference(git_repository *repo) { - int error = git_reference_foreach(repo, GIT_REF_LISTALL, at_least_one_cb, NULL); + int error = git_reference_foreach(repo, at_least_one_cb, NULL); if (error == GIT_EUSER) return 0; @@ -1596,6 +1596,9 @@ int git_repository_message(char *buffer, size_t len, git_repository *repo) struct stat st; int error; + if (buffer != NULL) + *buffer = '\0'; + if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0) return -1; diff --git a/src/revparse.c b/src/revparse.c index e8cc32aff..05231e3fc 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -14,67 +14,6 @@ #include "git2.h" -static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname) -{ - int error = 0, i; - bool fallbackmode = true, foundvalid = false; - git_reference *ref; - git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; - - static const char* formatters[] = { - "%s", - GIT_REFS_DIR "%s", - GIT_REFS_TAGS_DIR "%s", - GIT_REFS_HEADS_DIR "%s", - GIT_REFS_REMOTES_DIR "%s", - GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE, - NULL - }; - - if (*refname) - git_buf_puts(&name, refname); - else { - git_buf_puts(&name, GIT_HEAD_FILE); - fallbackmode = false; - } - - for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) { - - git_buf_clear(&refnamebuf); - - if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0) - goto cleanup; - - if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) { - error = GIT_EINVALIDSPEC; - continue; - } - foundvalid = true; - - error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1); - - if (!error) { - *out = ref; - error = 0; - goto cleanup; - } - - if (error != GIT_ENOTFOUND) - goto cleanup; - } - -cleanup: - if (error && !foundvalid) { - /* never found a valid reference name */ - giterr_set(GITERR_REFERENCE, - "Could not use '%s' as valid reference name", git_buf_cstr(&name)); - } - - git_buf_free(&name); - git_buf_free(&refnamebuf); - return error; -} - static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen) { git_oid oid; @@ -157,7 +96,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const if (error < 0 && error != GIT_ENOTFOUND) return error; - error = disambiguate_refname(&ref, repo, spec); + error = git_reference_dwim(&ref, repo, spec); if (!error) { error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY); git_reference_free(ref); @@ -242,7 +181,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out, git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so); - if ((error = disambiguate_refname(base_ref, repo, git_buf_cstr(&buf))) == 0) + if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0) goto cleanup; if (error < 0 && error != GIT_ENOTFOUND) @@ -323,7 +262,7 @@ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base int error = -1; if (*base_ref == NULL) { - if ((error = disambiguate_refname(&ref, repo, identifier)) < 0) + if ((error = git_reference_dwim(&ref, repo, identifier)) < 0) return error; } else { ref = *base_ref; @@ -351,7 +290,7 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch int error = -1; if (*base_ref == NULL) { - if ((error = disambiguate_refname(&ref, repo, identifier)) < 0) + if ((error = git_reference_dwim(&ref, repo, identifier)) < 0) return error; } else { ref = *base_ref; diff --git a/src/revwalk.c b/src/revwalk.c index 16f06624d..528d02b20 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -186,7 +186,7 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide) data.hide = hide; if (git_reference_foreach_glob( - walk->repo, git_buf_cstr(&buf), GIT_REF_LISTALL, push_glob_cb, &data) < 0) + walk->repo, git_buf_cstr(&buf), push_glob_cb, &data) < 0) goto on_error; regfree(&preg); diff --git a/src/status.c b/src/status.c index 73472ab14..89f3eedb5 100644 --- a/src/status.c +++ b/src/status.c @@ -266,6 +266,7 @@ int git_status_file( opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED | + GIT_STATUS_OPT_RECURSE_IGNORED_DIRS | GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS | GIT_STATUS_OPT_INCLUDE_UNMODIFIED; @@ -281,22 +282,9 @@ int git_status_file( } if (!error && !sfi.count) { - git_buf full = GIT_BUF_INIT; - - /* if the file actually exists and we still did not get a callback - * for it, then it must be contained inside an ignored directory, so - * mark it as such instead of generating an error. - */ - if (!git_buf_joinpath(&full, git_repository_workdir(repo), path) && - git_path_exists(full.ptr)) - sfi.status = GIT_STATUS_IGNORED; - else { - giterr_set(GITERR_INVALID, - "Attempt to get status of nonexistent file '%s'", path); - error = GIT_ENOTFOUND; - } - - git_buf_free(&full); + giterr_set(GITERR_INVALID, + "Attempt to get status of nonexistent file '%s'", path); + error = GIT_ENOTFOUND; } *status_flags = sfi.status; @@ -427,7 +427,7 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) data.cb_data = cb_data; data.repo = repo; - return git_reference_foreach(repo, GIT_REF_OID, &tags_cb, &data); + return git_reference_foreach(repo, &tags_cb, &data); } typedef struct { diff --git a/src/transports/local.c b/src/transports/local.c index 8b4d50c14..bd3bf93bf 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -124,7 +124,7 @@ static int store_refs(transport_local *t) assert(t); - if (git_reference_list(&ref_names, t->repo, GIT_REF_LISTALL) < 0 || + if (git_reference_list(&ref_names, t->repo) < 0 || git_vector_init(&t->refs, ref_names.count, NULL) < 0) goto on_error; diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 765b914b7..67d309523 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -21,8 +21,8 @@ int git_smart__store_refs(transport_smart *t, int flushes) gitno_buffer *buf = &t->buffer; git_vector *refs = &t->refs; int error, flush = 0, recvd; - const char *line_end; - git_pkt *pkt; + const char *line_end = NULL; + git_pkt *pkt = NULL; git_pkt_ref *ref; size_t i; @@ -135,7 +135,7 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps) static int recv_pkt(git_pkt **out, gitno_buffer *buf) { const char *ptr = buf->data, *line_end = ptr; - git_pkt *pkt; + git_pkt *pkt = NULL; int pkt_type, error = 0, ret; do { @@ -193,7 +193,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo) unsigned int i; git_reference *ref; - if (git_reference_list(&refs, repo, GIT_REF_LISTALL) < 0) + if (git_reference_list(&refs, repo) < 0) return -1; if (git_revwalk_new(&walk, repo) < 0) @@ -640,8 +640,8 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt) static int parse_report(gitno_buffer *buf, git_push *push) { - git_pkt *pkt; - const char *line_end; + git_pkt *pkt = NULL; + const char *line_end = NULL; int error, recvd; for (;;) { diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index e502001cb..d803c812c 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -893,7 +893,7 @@ static int winhttp_connect( wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")"; wchar_t host[GIT_WIN_PATH]; int32_t port; - const char *default_port; + const char *default_port = "80"; int ret; if (!git__prefixcmp(url, prefix_http)) { diff --git a/tests-clar/clar_libgit2.c b/tests-clar/clar_libgit2.c index 68d17162b..de0e41bf7 100644 --- a/tests-clar/clar_libgit2.c +++ b/tests-clar/clar_libgit2.c @@ -190,6 +190,18 @@ git_repository *cl_git_sandbox_init(const char *sandbox) return _cl_repo; } +git_repository *cl_git_sandbox_reopen(void) +{ + if (_cl_repo) { + git_repository_free(_cl_repo); + _cl_repo = NULL; + + cl_git_pass(git_repository_open(&_cl_repo, _cl_sandbox)); + } + + return _cl_repo; +} + void cl_git_sandbox_cleanup(void) { if (_cl_repo) { diff --git a/tests-clar/clar_libgit2.h b/tests-clar/clar_libgit2.h index 93909d8a5..3fcf45a37 100644 --- a/tests-clar/clar_libgit2.h +++ b/tests-clar/clar_libgit2.h @@ -60,6 +60,7 @@ int cl_rename(const char *source, const char *dest); git_repository *cl_git_sandbox_init(const char *sandbox); void cl_git_sandbox_cleanup(void); +git_repository *cl_git_sandbox_reopen(void); /* Local-repo url helpers */ const char* cl_git_fixture_url(const char *fixturename); diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c index 8b17fd998..8aae1fb52 100644 --- a/tests-clar/clone/nonetwork.c +++ b/tests-clar/clone/nonetwork.c @@ -185,6 +185,7 @@ void test_clone_nonetwork__custom_autotag(void) cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_NONE, origin->download_tags); git_strarray_free(&tags); + git_remote_free(origin); } void test_clone_nonetwork__custom_autotag_tags_all(void) @@ -199,6 +200,7 @@ void test_clone_nonetwork__custom_autotag_tags_all(void) cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_ALL, origin->download_tags); git_strarray_free(&tags); + git_remote_free(origin); } void test_clone_nonetwork__cope_with_already_existing_directory(void) diff --git a/tests-clar/diff/rename.c b/tests-clar/diff/rename.c index 5a8af93bb..8134cb6b7 100644 --- a/tests-clar/diff/rename.c +++ b/tests-clar/diff/rename.c @@ -364,7 +364,7 @@ void test_diff_rename__handles_small_files(void) cl_git_pass(git_repository_index(&index, g_repo)); tree = resolve_commit_oid_to_tree(g_repo, tree_sha); - + cl_git_rewritefile("renames/songof7cities.txt", "single line\n"); cl_git_pass(git_index_add_bypath(index, "songof7cities.txt")); @@ -391,3 +391,56 @@ void test_diff_rename__working_directory_changes(void) /* and with / without CRLF changes */ } + +void test_diff_rename__patch(void) +{ + const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a"; + const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084"; + git_tree *old_tree, *new_tree; + git_diff_list *diff; + git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; + git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT; + git_diff_patch *patch; + const git_diff_delta *delta; + char *text; + const char *expected = "diff --git a/sixserving.txt b/ikeepsix.txt\nindex ad0a8e5..36020db 100644\n--- a/sixserving.txt\n+++ b/ikeepsix.txt\n@@ -1,3 +1,6 @@\n+I Keep Six Honest Serving-Men\n+=============================\n+\n I KEEP six honest serving-men\n (They taught me all I knew);\n Their names are What and Why and When\n@@ -21,4 +24,4 @@\n One million Hows, two million Wheres,\n And seven million Whys!\n \n- -- Rudyard Kipling\n+ -- Rudyard Kipling\n"; + + old_tree = resolve_commit_oid_to_tree(g_repo, sha0); + new_tree = resolve_commit_oid_to_tree(g_repo, sha1); + + diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED; + cl_git_pass(git_diff_tree_to_tree( + &diff, g_repo, old_tree, new_tree, &diffopts)); + + opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES; + cl_git_pass(git_diff_find_similar(diff, &opts)); + + /* == Changes ===================================================== + * sixserving.txt -> ikeepsix.txt (copy, add title, >80% match) + * sevencities.txt (no change) + * sixserving.txt -> sixserving.txt (indentation change) + * songofseven.txt -> songofseven.txt (major rewrite, <20% match - split) + */ + + cl_assert_equal_i(4, (int)git_diff_num_deltas(diff)); + + cl_git_pass(git_diff_get_patch(&patch, &delta, diff, 0)); + cl_assert_equal_i(GIT_DELTA_COPIED, (int)delta->status); + + cl_git_pass(git_diff_patch_to_str(&text, patch)); + cl_assert_equal_s(expected, text); + git__free(text); + + git_diff_patch_free(patch); + + cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 1)); + cl_assert_equal_i(GIT_DELTA_UNMODIFIED, (int)delta->status); + + cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 2)); + cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status); + + cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 3)); + cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status); + + git_diff_list_free(diff); +} diff --git a/tests-clar/merge/trees/trivial.c b/tests-clar/merge/trees/trivial.c index 7d8d2cbf5..e6096e2dc 100644 --- a/tests-clar/merge/trees/trivial.c +++ b/tests-clar/merge/trees/trivial.c @@ -67,7 +67,7 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs static int merge_trivial_conflict_entrycount(git_index *index) { const git_index_entry *entry; - size_t count = 0; + int count = 0; size_t i; for (i = 0; i < git_index_entrycount(index); i++) { diff --git a/tests-clar/network/fetchlocal.c b/tests-clar/network/fetchlocal.c index bcf298cde..09335b3df 100644 --- a/tests-clar/network/fetchlocal.c +++ b/tests-clar/network/fetchlocal.c @@ -34,7 +34,7 @@ void test_network_fetchlocal__complete(void) cl_git_pass(git_remote_download(origin, transfer_cb, &callcount)); cl_git_pass(git_remote_update_tips(origin)); - cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); cl_assert(callcount > 0); @@ -58,7 +58,7 @@ void test_network_fetchlocal__partial(void) const char *url; cl_set_cleanup(&cleanup_sandbox, NULL); - cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(1, (int)refnames.count); url = cl_git_fixture_url("testrepo.git"); @@ -69,7 +69,7 @@ void test_network_fetchlocal__partial(void) git_strarray_free(&refnames); - cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */ cl_assert(callcount > 0); diff --git a/tests-clar/network/remote/remotes.c b/tests-clar/network/remote/remotes.c index 4c24db8eb..21f27bcc6 100644 --- a/tests-clar/network/remote/remotes.c +++ b/tests-clar/network/remote/remotes.c @@ -118,13 +118,13 @@ void test_network_remote_remotes__add_fetchspec(void) cl_git_pass(git_remote_add_fetch(_remote, "refs/*:refs/*")); size++; - cl_assert_equal_i(size, git_remote_refspec_count(_remote)); + cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote)); _refspec = git_remote_get_refspec(_remote, size - 1); cl_assert_equal_s(git_refspec_src(_refspec), "refs/*"); cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*"); cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*"); - cl_assert_equal_i(_refspec->push, false); + cl_assert_equal_b(_refspec->push, false); } void test_network_remote_remotes__add_pushspec(void) @@ -135,14 +135,14 @@ void test_network_remote_remotes__add_pushspec(void) cl_git_pass(git_remote_add_push(_remote, "refs/*:refs/*")); size++; - cl_assert_equal_i(size, git_remote_refspec_count(_remote)); + cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote)); _refspec = git_remote_get_refspec(_remote, size - 1); cl_assert_equal_s(git_refspec_src(_refspec), "refs/*"); cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*"); cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*"); - cl_assert_equal_i(_refspec->push, true); + cl_assert_equal_b(_refspec->push, true); } void test_network_remote_remotes__save(void) @@ -169,12 +169,12 @@ void test_network_remote_remotes__save(void) cl_git_pass(git_remote_load(&_remote, _repo, "upstream")); cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote)); - cl_assert_equal_i(1, array.count); + cl_assert_equal_i(1, (int)array.count); cl_assert_equal_s(fetch_refspec, array.strings[0]); git_strarray_free(&array); cl_git_pass(git_remote_get_push_refspecs(&array, _remote)); - cl_assert_equal_i(1, array.count); + cl_assert_equal_i(1, (int)array.count); cl_assert_equal_s(push_refspec, array.strings[0]); cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2"); cl_assert_equal_s(git_remote_pushurl(_remote), "git://github.com/libgit2/libgit2_push"); diff --git a/tests-clar/object/cache.c b/tests-clar/object/cache.c index e06760e2a..b927b2514 100644 --- a/tests-clar/object/cache.c +++ b/tests-clar/object/cache.c @@ -80,7 +80,7 @@ void test_object_cache__cache_everything(void) cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects)); } - cl_assert_equal_i(i, git_cache_size(&g_repo->objects) - start); + cl_assert_equal_i(i, (int)git_cache_size(&g_repo->objects) - start); git_odb_free(odb); @@ -135,7 +135,7 @@ void test_object_cache__cache_no_blobs(void) } } - cl_assert_equal_i(nonblobs, git_cache_size(&g_repo->objects) - start); + cl_assert_equal_i(nonblobs, (int)git_cache_size(&g_repo->objects) - start); git_odb_free(odb); } diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c index 243b5bb37..d2594cd6d 100644 --- a/tests-clar/refdb/inmemory.c +++ b/tests-clar/refdb/inmemory.c @@ -163,7 +163,7 @@ void test_refdb_inmemory__foreach(void) cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, foreach_test, &i)); + cl_git_pass(git_reference_foreach(repo,foreach_test, &i)); cl_assert_equal_i(3, (int)i); git_reference_free(write1); @@ -210,7 +210,7 @@ void test_refdb_inmemory__delete(void) git_reference_delete(write3); git_reference_free(write3); - cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, delete_test, &i)); + cl_git_pass(git_reference_foreach(repo, delete_test, &i)); cl_assert_equal_i(1, (int)i); git_reference_free(write2); diff --git a/tests-clar/refdb/testdb.c b/tests-clar/refdb/testdb.c index 627254e44..961e18d44 100644 --- a/tests-clar/refdb/testdb.c +++ b/tests-clar/refdb/testdb.c @@ -112,33 +112,49 @@ static int refdb_test_backend__lookup( return GIT_ENOTFOUND; } -static int refdb_test_backend__foreach( - git_refdb_backend *_backend, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload) -{ - refdb_test_backend *backend; - refdb_test_entry *entry; +typedef struct { + git_reference_iterator parent; size_t i; +} refdb_test_iter; - assert(_backend); - backend = (refdb_test_backend *)_backend; +static int refdb_test_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend) +{ + refdb_test_iter *iter; - git_vector_foreach(&backend->refs, i, entry) { - if (entry->type == GIT_REF_OID && (list_flags & GIT_REF_OID) == 0) - continue; + GIT_UNUSED(_backend); - if (entry->type == GIT_REF_SYMBOLIC && (list_flags & GIT_REF_SYMBOLIC) == 0) - continue; + iter = git__calloc(1, sizeof(refdb_test_iter)); + GITERR_CHECK_ALLOC(iter); - if (callback(entry->name, payload) != 0) - return GIT_EUSER; - } + iter->parent.backend = _backend; + iter->i = 0; + + *out = (git_reference_iterator *) iter; return 0; } +static int refdb_test_backend__next(const char **name, git_reference_iterator *_iter) +{ + refdb_test_entry *entry; + refdb_test_backend *backend = (refdb_test_backend *) _iter->backend; + refdb_test_iter *iter = (refdb_test_iter *) _iter; + + entry = git_vector_get(&backend->refs, iter->i); + if (!entry) + return GIT_ITEROVER; + + *name = entry->name; + iter->i++; + + return 0; +} + +static void refdb_test_backend__iterator_free(git_reference_iterator *iter) +{ + git__free(iter); +} + static void refdb_test_entry_free(refdb_test_entry *entry) { if (entry->type == GIT_REF_SYMBOLIC) @@ -200,7 +216,9 @@ int refdb_backend_test( backend->parent.exists = &refdb_test_backend__exists; backend->parent.lookup = &refdb_test_backend__lookup; - backend->parent.foreach = &refdb_test_backend__foreach; + backend->parent.iterator = &refdb_test_backend__iterator; + backend->parent.next = &refdb_test_backend__next; + backend->parent.iterator_free = &refdb_test_backend__iterator_free; backend->parent.write = &refdb_test_backend__write; backend->parent.delete = &refdb_test_backend__delete; backend->parent.free = &refdb_test_backend__free; diff --git a/tests-clar/refs/branches/foreach.c b/tests-clar/refs/branches/foreach.c index 96a5bc2b9..57f9c0e39 100644 --- a/tests-clar/refs/branches/foreach.c +++ b/tests-clar/refs/branches/foreach.c @@ -24,6 +24,8 @@ void test_refs_branches_foreach__cleanup(void) repo = NULL; cl_fixture_cleanup("testrepo.git"); + + cl_git_sandbox_cleanup(); } static int count_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload) @@ -72,14 +74,11 @@ static void assert_branch_has_been_found(struct expectations *findings, const ch { int pos = 0; - while (findings[pos].branch_name) - { + for (pos = 0; findings[pos].branch_name; ++pos) { if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) { cl_assert_equal_i(1, findings[pos].encounters); return; } - - pos++; } cl_fail("expected branch not found in list."); @@ -94,12 +93,9 @@ static int contains_branch_list_cb(const char *branch_name, git_branch_t branch_ exp = (struct expectations *)payload; - while (exp[pos].branch_name) - { + for (pos = 0; exp[pos].branch_name; ++pos) { if (strcmp(branch_name, exp[pos].branch_name) == 0) exp[pos].encounters++; - - pos++; } return 0; @@ -153,3 +149,25 @@ void test_refs_branches_foreach__can_cancel(void) cl_assert_equal_i(5, count); } + +void test_refs_branches_foreach__mix_of_packed_and_loose(void) +{ + struct expectations exp[] = { + { "master", 0 }, + { "origin/HEAD", 0 }, + { "origin/master", 0 }, + { "origin/packed", 0 }, + { NULL, 0 } + }; + git_repository *r2; + + r2 = cl_git_sandbox_init("testrepo2"); + + cl_git_pass(git_branch_foreach(r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, + contains_branch_list_cb, &exp)); + + assert_branch_has_been_found(exp, "master"); + assert_branch_has_been_found(exp, "origin/HEAD"); + assert_branch_has_been_found(exp, "origin/master"); + assert_branch_has_been_found(exp, "origin/packed"); +} diff --git a/tests-clar/refs/branches/upstream.c b/tests-clar/refs/branches/upstream.c index 648acb44d..69e55a0c5 100644 --- a/tests-clar/refs/branches/upstream.c +++ b/tests-clar/refs/branches/upstream.c @@ -113,11 +113,12 @@ void test_refs_branches_upstream__set_unset_upstream(void) cl_git_pass(git_config_get_string(&value, config, "branch.test.merge")); cl_assert_equal_s(value, "refs/heads/master"); + git_reference_free(branch); + /* local */ cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test")); cl_git_pass(git_branch_set_upstream(branch, "master")); - cl_git_pass(git_repository_config(&config, repository)); cl_git_pass(git_config_get_string(&value, config, "branch.test.remote")); cl_assert_equal_s(value, "."); cl_git_pass(git_config_get_string(&value, config, "branch.test.merge")); diff --git a/tests-clar/refs/foreachglob.c b/tests-clar/refs/foreachglob.c index 4da1a15dd..2c458082f 100644 --- a/tests-clar/refs/foreachglob.c +++ b/tests-clar/refs/foreachglob.c @@ -37,11 +37,11 @@ static int count_cb(const char *reference_name, void *payload) return 0; } -static void assert_retrieval(const char *glob, unsigned int flags, int expected_count) +static void assert_retrieval(const char *glob, int expected_count) { int count = 0; - cl_git_pass(git_reference_foreach_glob(repo, glob, flags, count_cb, &count)); + cl_git_pass(git_reference_foreach_glob(repo, glob, count_cb, &count)); cl_assert_equal_i(expected_count, count); } @@ -49,17 +49,17 @@ static void assert_retrieval(const char *glob, unsigned int flags, int expected_ void test_refs_foreachglob__retrieve_all_refs(void) { /* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags */ - assert_retrieval("*", GIT_REF_LISTALL, 22); + assert_retrieval("*", 22); } void test_refs_foreachglob__retrieve_remote_branches(void) { - assert_retrieval("refs/remotes/*", GIT_REF_LISTALL, 2); + assert_retrieval("refs/remotes/*", 2); } void test_refs_foreachglob__retrieve_local_branches(void) { - assert_retrieval("refs/heads/*", GIT_REF_LISTALL, 12); + assert_retrieval("refs/heads/*", 12); } void test_refs_foreachglob__retrieve_partially_named_references(void) @@ -69,7 +69,7 @@ void test_refs_foreachglob__retrieve_partially_named_references(void) * refs/remotes/test/master, refs/tags/test */ - assert_retrieval("*test*", GIT_REF_LISTALL, 4); + assert_retrieval("*test*", 4); } @@ -89,7 +89,7 @@ void test_refs_foreachglob__can_cancel(void) int count = 0; cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob( - repo, "*", GIT_REF_LISTALL, interrupt_cb, &count) ); + repo, "*", interrupt_cb, &count) ); cl_assert_equal_i(11, count); } diff --git a/tests-clar/refs/iterator.c b/tests-clar/refs/iterator.c new file mode 100644 index 000000000..d5555c657 --- /dev/null +++ b/tests-clar/refs/iterator.c @@ -0,0 +1,94 @@ +#include "clar_libgit2.h" +#include "refs.h" +#include "vector.h" + +static git_repository *repo; + +void test_refs_iterator__initialize(void) +{ + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); +} + +void test_refs_iterator__cleanup(void) +{ + git_repository_free(repo); +} + +static const char *refnames[] = { + "refs/heads/br2", + "refs/heads/cannot-fetch", + "refs/heads/chomped", + "refs/heads/haacked", + "refs/heads/master", + "refs/heads/not-good", + "refs/heads/packed", + "refs/heads/packed-test", + "refs/heads/subtrees", + "refs/heads/test", + "refs/heads/track-local", + "refs/heads/trailing", + "refs/notes/fanout", + "refs/remotes/test/master", + "refs/tags/annotated_tag_to_blob", + "refs/tags/e90810b", + "refs/tags/hard_tag", + "refs/tags/point_to_blob", + "refs/tags/taggerless", + "refs/tags/test", + "refs/tags/wrapped_tag", +}; + +void test_refs_iterator__list(void) +{ + git_reference_iterator *iter; + git_vector output; + char *refname; + int error; + size_t i; + + cl_git_pass(git_vector_init(&output, 32, git__strcmp_cb)); + cl_git_pass(git_reference_iterator_new(&iter, repo)); + + do { + const char *name; + error = git_reference_next(&name, iter); + cl_assert(error == 0 || error == GIT_ITEROVER); + if (error != GIT_ITEROVER) { + char *dup = git__strdup(name); + cl_assert(dup != NULL); + cl_git_pass(git_vector_insert(&output, dup)); + } + } while (!error); + + cl_assert_equal_i(output.length, ARRAY_SIZE(refnames)); + + git_vector_sort(&output); + git_vector_foreach(&output, i, refname) { + cl_assert_equal_s(refname, refnames[i]); + } + + git_reference_iterator_free(iter); + + git_vector_foreach(&output, i, refname) { + git__free(refname); + } + git_vector_free(&output); +} + +void test_refs_iterator__empty(void) +{ + git_reference_iterator *iter; + git_odb *odb; + const char *name; + git_repository *empty; + + cl_git_pass(git_odb_new(&odb)); + cl_git_pass(git_repository_wrap_odb(&empty, odb)); + + cl_git_pass(git_reference_iterator_new(&iter, empty)); + cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&name, iter)); + + git_reference_iterator_free(iter); + git_odb_free(odb); + git_repository_free(empty); +} diff --git a/tests-clar/refs/list.c b/tests-clar/refs/list.c index 3948b2b7a..c9c2af4a7 100644 --- a/tests-clar/refs/list.c +++ b/tests-clar/refs/list.c @@ -25,7 +25,7 @@ void test_refs_list__all(void) // try to list all the references in our test repo git_strarray ref_list; - cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&ref_list, g_repo)); /*{ unsigned short i; @@ -41,17 +41,6 @@ void test_refs_list__all(void) git_strarray_free(&ref_list); } -void test_refs_list__symbolic_only(void) -{ - // try to list only the symbolic references - git_strarray ref_list; - - cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_SYMBOLIC)); - cl_assert(ref_list.count == 0); /* no symrefs in the test repo */ - - git_strarray_free(&ref_list); -} - void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_extension(void) { git_strarray ref_list; @@ -61,7 +50,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten "./testrepo/.git/refs/heads/hanwen.lock", "144344043ba4d4a405da03de3844aa829ae8be0e\n"); - cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&ref_list, g_repo)); cl_assert_equal_i((int)ref_list.count, 13); git_strarray_free(&ref_list); diff --git a/tests-clar/refs/listall.c b/tests-clar/refs/listall.c index 8f4c3746b..c696fbb2e 100644 --- a/tests-clar/refs/listall.c +++ b/tests-clar/refs/listall.c @@ -9,7 +9,7 @@ static void ensure_no_refname_starts_with_a_forward_slash(const char *path) size_t i; cl_git_pass(git_repository_open(&repo, path)); - cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&ref_list, repo)); cl_assert(ref_list.count > 0); @@ -38,7 +38,7 @@ void test_refs_listall__from_repository_opened_through_gitdir_path(void) void test_refs_listall__from_repository_with_no_trailing_newline(void) { cl_git_pass(git_repository_open(&repo, cl_fixture("bad_tag.git"))); - cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL)); + cl_git_pass(git_reference_list(&ref_list, repo)); cl_assert(ref_list.count > 0); diff --git a/tests-clar/repo/message.c b/tests-clar/repo/message.c index 59487d51b..629d40c12 100644 --- a/tests-clar/repo/message.c +++ b/tests-clar/repo/message.c @@ -35,13 +35,18 @@ void test_repo_message__message(void) len = git_repository_message(NULL, 0, _repo); cl_assert(len > 0); + _actual = git__malloc(len + 1); cl_assert(_actual != NULL); + /* Test non truncation */ cl_assert(git_repository_message(_actual, len, _repo) > 0); - _actual[len] = '\0'; cl_assert_equal_s(expected, _actual); + /* Test truncation and that trailing NUL is inserted */ + cl_assert(git_repository_message(_actual, 6, _repo) > 0); + cl_assert_equal_s("Test\n", _actual); + cl_git_pass(p_unlink(git_buf_cstr(&_path))); cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(NULL, 0, _repo)); } diff --git a/tests-clar/resources/testrepo2/.gitted/HEAD b/tests-clar/resources/testrepo2/.gitted/HEAD new file mode 100644 index 000000000..cb089cd89 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests-clar/resources/testrepo2/.gitted/config b/tests-clar/resources/testrepo2/.gitted/config new file mode 100644 index 000000000..fc2433caf --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/config @@ -0,0 +1,14 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = false +[remote "origin"] + url = https://github.com/libgit2/false.git + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "master"] + remote = origin + merge = refs/heads/master + rebase = true diff --git a/tests-clar/resources/testrepo2/.gitted/description b/tests-clar/resources/testrepo2/.gitted/description new file mode 100644 index 000000000..498b267a8 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests-clar/resources/testrepo2/.gitted/index b/tests-clar/resources/testrepo2/.gitted/index Binary files differnew file mode 100644 index 000000000..b614d0727 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/index diff --git a/tests-clar/resources/testrepo2/.gitted/info/exclude b/tests-clar/resources/testrepo2/.gitted/info/exclude new file mode 100644 index 000000000..a5196d1be --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/tests-clar/resources/testrepo2/.gitted/logs/HEAD b/tests-clar/resources/testrepo2/.gitted/logs/HEAD new file mode 100644 index 000000000..4e80c69fa --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git diff --git a/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master b/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master new file mode 100644 index 000000000..4e80c69fa --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git diff --git a/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD b/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD new file mode 100644 index 000000000..4e80c69fa --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git diff --git a/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d b/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d Binary files differnew file mode 100644 index 000000000..bfe146a5a --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d diff --git a/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 Binary files differnew file mode 100644 index 000000000..cedb2a22e --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 Binary files differnew file mode 100644 index 000000000..93a16f146 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd Binary files differnew file mode 100644 index 000000000..ba0bfb30c --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd diff --git a/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 Binary files differnew file mode 100644 index 000000000..3cd240db5 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a b/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a new file mode 100644 index 000000000..0c6246061 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a @@ -0,0 +1,2 @@ +xQ +0)reݴ
$ۭ-F-00?iL#HSS#q2D據jC|HSL8$)a#2i6js?JZftΞUiͶqiZ"_/H6
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 Binary files differnew file mode 100644 index 000000000..7ca4ceed5 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 new file mode 100644 index 000000000..8953b6cef --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 @@ -0,0 +1,2 @@ +xQ +0D)6ͦ "xO-FbEo0Ǥ,ske[Pn8R,EpD?g}^3<GhYK8ЖDA);gݧjp4-r;sGA4ۺ=(in7IKFE
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 new file mode 100644 index 000000000..c1f22c54f --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 @@ -0,0 +1,2 @@ +x 1ENi@k2 "X$YW0YcÅszMD08!sXgd::@X0Pw"F/RUzmZZV}|/o5I!1z:vUim}/> +F-
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 b/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 Binary files differnew file mode 100644 index 000000000..1fd79b477 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a Binary files differnew file mode 100644 index 000000000..2ef4faa0f --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a diff --git a/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 Binary files differnew file mode 100644 index 000000000..3d1016daa --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d Binary files differnew file mode 100644 index 000000000..2f9b6b6e3 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d diff --git a/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 Binary files differnew file mode 100644 index 000000000..5df58dda5 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a new file mode 100644 index 000000000..a79612435 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a @@ -0,0 +1,3 @@ +x[ +0E*fդ "W0-Ft݁pS[Yx^ +Db CLhut}8X*4ZsYUA
X3RM) s6輢Mរ&Jm;}<\@ޏpĀv?jۺL?H
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f new file mode 100644 index 000000000..f8588696b --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f @@ -0,0 +1,2 @@ +x;j1Dmdǎ|M3`V{>QvL0I?!4Z=!צ8F!rsQy9]$D&l6A>jFWҵIKNiZ%S + U~̽>' w
[DGڡQ-M>dO}\8g_ШoYr
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd Binary files differnew file mode 100644 index 000000000..d0d7e736e --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 Binary files differnew file mode 100644 index 000000000..18a7f61c2 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 new file mode 100644 index 000000000..0817229bc --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 @@ -0,0 +1,3 @@ +xKj1D)zUB-0uV9<#+W<J&8/seȕKJS +Rv{QrYQN$H\E=6X5K Fr)(dCΆjs}9c-w8o\rI: +l}FW$DsǣٚOWe]V8-Ý"U
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd new file mode 100644 index 000000000..75f541f10 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd @@ -0,0 +1,3 @@ +xQ +0D)ʦI<'lR+FjEo0<xha ]șXUlPF)z4y,\r 'S-mI4 +Xh&F}n+\Y-p|鷜oUz;-alt{?I,:oRcHK
\ No newline at end of file diff --git a/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b b/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b Binary files differnew file mode 100644 index 000000000..599e16084 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b diff --git a/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 Binary files differnew file mode 100644 index 000000000..711223894 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 Binary files differnew file mode 100644 index 000000000..03770969a --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 Binary files differnew file mode 100644 index 000000000..112998d42 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 Binary files differnew file mode 100644 index 000000000..12bf5f3e3 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx Binary files differnew file mode 100644 index 000000000..94c3c71da --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack Binary files differnew file mode 100644 index 000000000..74c7fe4f3 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack diff --git a/tests-clar/resources/testrepo2/.gitted/packed-refs b/tests-clar/resources/testrepo2/.gitted/packed-refs new file mode 100644 index 000000000..97ea6a848 --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/packed-refs @@ -0,0 +1,6 @@ +# pack-refs with: peeled fully-peeled +36060c58702ed4c2a40832c51758d5344201d89a refs/remotes/origin/master +41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed +5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/tags/v0.9 +0c37a5391bbff43c37f0d0371823a5509eed5b1d refs/tags/v1.0 +^5b5b025afb0b4c913b4c338a42934a3863bf3644 diff --git a/tests-clar/resources/testrepo2/.gitted/refs/heads/master b/tests-clar/resources/testrepo2/.gitted/refs/heads/master new file mode 100644 index 000000000..a7eafce3c --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/refs/heads/master @@ -0,0 +1 @@ +36060c58702ed4c2a40832c51758d5344201d89a diff --git a/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD b/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD new file mode 100644 index 000000000..6efe28fff --- /dev/null +++ b/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/tests-clar/resources/testrepo2/README b/tests-clar/resources/testrepo2/README new file mode 100644 index 000000000..1385f264a --- /dev/null +++ b/tests-clar/resources/testrepo2/README @@ -0,0 +1 @@ +hey diff --git a/tests-clar/resources/testrepo2/new.txt b/tests-clar/resources/testrepo2/new.txt new file mode 100644 index 000000000..fa49b0779 --- /dev/null +++ b/tests-clar/resources/testrepo2/new.txt @@ -0,0 +1 @@ +new file diff --git a/tests-clar/resources/testrepo2/subdir/README b/tests-clar/resources/testrepo2/subdir/README new file mode 100644 index 000000000..1385f264a --- /dev/null +++ b/tests-clar/resources/testrepo2/subdir/README @@ -0,0 +1 @@ +hey diff --git a/tests-clar/resources/testrepo2/subdir/new.txt b/tests-clar/resources/testrepo2/subdir/new.txt new file mode 100644 index 000000000..fa49b0779 --- /dev/null +++ b/tests-clar/resources/testrepo2/subdir/new.txt @@ -0,0 +1 @@ +new file diff --git a/tests-clar/resources/testrepo2/subdir/subdir2/README b/tests-clar/resources/testrepo2/subdir/subdir2/README new file mode 100644 index 000000000..1385f264a --- /dev/null +++ b/tests-clar/resources/testrepo2/subdir/subdir2/README @@ -0,0 +1 @@ +hey diff --git a/tests-clar/resources/testrepo2/subdir/subdir2/new.txt b/tests-clar/resources/testrepo2/subdir/subdir2/new.txt new file mode 100644 index 000000000..fa49b0779 --- /dev/null +++ b/tests-clar/resources/testrepo2/subdir/subdir2/new.txt @@ -0,0 +1 @@ +new file diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c index 0138b1712..062a09aeb 100644 --- a/tests-clar/status/worktree.c +++ b/tests-clar/status/worktree.c @@ -672,3 +672,26 @@ void test_status_worktree__file_status_honors_core_ignorecase_false(void) { assert_ignore_case(false, GIT_STATUS_WT_DELETED, GIT_STATUS_WT_NEW); } + +void test_status_worktree__file_status_honors_case_ignorecase_regarding_untracked_files(void) +{ + git_repository *repo = cl_git_sandbox_init("status"); + unsigned int status; + git_index *index; + + cl_repo_set_bool(repo, "core.ignorecase", false); + + repo = cl_git_sandbox_reopen(); + + /* Actually returns GIT_STATUS_IGNORED on Windows */ + cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND); + + cl_git_pass(git_repository_index(&index, repo)); + + cl_git_pass(git_index_add_bypath(index, "new_file")); + cl_git_pass(git_index_write(index)); + git_index_free(index); + + /* Actually returns GIT_STATUS_IGNORED on Windows */ + cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND); +} |