Merge remote-tracking branch 'carlosmn/empty-name' into empty-name
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a228e3..402ff22 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -131,7 +131,9 @@
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 adc7ed8..d7a5847 100644
--- a/examples/general.c
+++ b/examples/general.c
@@ -453,7 +453,7 @@
// 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 e1d4253..754bda7 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -55,6 +55,19 @@
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 @@
/**
* 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 @@
* @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(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 @@
*
* @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_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 cd238e1..e0464c6 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -460,10 +460,19 @@
* 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 d5f599f..8dbf38c 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 @@
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 aca9ed9..43751d3 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -165,6 +165,10 @@
/** 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 8302949..dd6dc68 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -124,40 +124,43 @@
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;
- filter.branch_cb = branch_cb;
- filter.branch_type = list_flags;
- filter.callback_payload = payload;
+ if (git_reference_iterator_new(&iter, repo) < 0)
+ return -1;
- return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
+ 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;
+ }
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+ git_reference_iterator_free(iter);
+ return error;
+
}
int git_branch_move(
diff --git a/src/clone.c b/src/clone.c
index 38c0d40..499195d 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -243,7 +243,6 @@
/* 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 @@
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 3dc647c..be6e32c 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -292,7 +292,7 @@
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 a9a40c3..e57cd1e 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -296,7 +296,7 @@
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 e0dff9c..f466546 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -535,7 +535,7 @@
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 2214ae1..07fcf47 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -593,6 +593,8 @@
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 a6807f2..9b8ccdd 100644
--- a/src/object.c
+++ b/src/object.c
@@ -117,7 +117,7 @@
{
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 0499d86..452d717 100644
--- a/src/push.c
+++ b/src/push.c
@@ -180,7 +180,7 @@
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 33a1934..9f9037c 100644
--- a/src/refdb.c
+++ b/src/refdb.c
@@ -124,15 +124,62 @@
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;
+
+ return 0;
+}
+
+int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob)
+{
+ if (!db->backend) {
+ giterr_set(GITERR_REFERENCE, "There are no backends loaded");
+ return -1;
+ }
+
+ 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_next(const char **out, git_reference_iterator *iter)
+{
+ int error;
+
+ if (!iter->glob)
+ return iter->backend->next(out, iter);
+
+ /* 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 {
@@ -141,43 +188,6 @@
void *payload;
};
-static int fromglob_cb(const char *reference_name, void *payload)
-{
- struct glob_cb_data *data = (struct glob_cb_data *)payload;
-
- if (!p_fnmatch(data->glob, reference_name, 0))
- return data->callback(reference_name, data->payload);
-
- 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 error;
- struct glob_cb_data data;
-
- assert(db && db->backend && glob && callback);
-
- 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);
- }
-
- return error;
-}
-
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 047113a..2edd05d 100644
--- a/src/refdb.h
+++ b/src/refdb.h
@@ -26,18 +26,10 @@
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 c0a32ba..c462a42 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 @@
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 @@
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 @@
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,65 +562,21 @@
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;
-
- type = GIT_REF_INVALID;
-
- 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;
- }
-
- git_buf_free(&ref_file);
- return type;
-}
-
-static int _dirent_loose_listall(void *_data, git_buf *full_path)
-{
- 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);
-
- /* do not add twice a reference that exists already in the packfile */
- if (git_strmap_exists(data->backend->refcache.packfile, file_path))
- return 0;
-
- 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 */
- }
-
- /* Locked references aren't returned */
- if (!git__suffixcmp(file_path, GIT_FILELOCK_EXTENSION))
- return 0;
-
- if (data->callback(file_path, data->callback_payload))
- data->callback_error = GIT_EUSER;
-
- return data->callback_error;
-}
-
-static int refdb_fs_backend__foreach(
- git_refdb_backend *_backend,
- unsigned int list_type,
- git_reference_foreach_cb callback,
- void *payload)
-{
+ 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;
-
- GIT_UNUSED(ref);
assert(_backend);
backend = (refdb_fs_backend *)_backend;
@@ -624,32 +584,107 @@
if (packed_load(backend) < 0)
return -1;
- /* 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;
- });
+ 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 void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
+{
+ refdb_fs_iter *iter = (refdb_fs_iter *) _iter;
+
+ git_buf_free(&iter->buf);
+ git_iterator_free(iter->fsiter);
+ git__free(iter);
+}
+
+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;
}
- /* now list the loose references, trying not to
- * duplicate the ref names already in the packed-refs file */
+ *out = kh_key(iter->h, iter->k);
+ iter->k++;
- 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;
+ return 0;
+}
- if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0)
+static int iter_loose(const char **out, refdb_fs_iter *iter)
+{
+ const git_index_entry *entry;
+ int retry;
+ git_strmap *packfile_refs;
+ refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
+
+ packfile_refs = backend->refcache.packfile;
+
+ do {
+ khiter_t pos;
+ if (git_iterator_current(&entry, iter->fsiter) < 0)
+ return -1;
+
+ git_buf_clear(&iter->buf);
+ if (!entry)
+ return GIT_ITEROVER;
+
+ if (git_buf_printf(&iter->buf, "refs/%s", entry->path) < 0)
+ return -1;
+
+ git_iterator_advance(NULL, iter->fsiter);
+
+ /* 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;
+
+ *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;
- return data.callback_error ? GIT_EUSER : result;
+ if (iter->loose)
+ return iter_loose(out, iter);
+
+ 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 @@
{
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 @@
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 8bba394..9c6c5c6 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -139,7 +139,7 @@
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 @@
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_foreach(
git_repository *repo,
- unsigned int list_flags,
git_reference_foreach_cb callback,
void *payload)
{
- git_refdb *refdb;
- git_repository_refdb__weakptr(&refdb, repo);
+ git_reference_iterator *iter;
+ const char *name;
+ int error;
- return git_refdb_foreach(refdb, list_flags, callback, payload);
+ 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;
+
+ 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 @@
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 @@
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_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;
+ }
+ }
- return git_refdb_foreach_glob(refdb, glob, list_flags, callback, payload);
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+out:
+ git_reference_iterator_free(iter);
+ return error;
}
int git_reference_has_log(
diff --git a/src/remote.c b/src/remote.c
index 6925376..e5a7df7 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -292,7 +292,7 @@
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 @@
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 @@
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 e2cedc0..4ab3921 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1473,7 +1473,7 @@
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 @@
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 e8cc32a..05231e3 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 @@
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 @@
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 @@
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 @@
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 16f0662..528d02b 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -186,7 +186,7 @@
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 73472ab..89f3eed 100644
--- a/src/status.c
+++ b/src/status.c
@@ -266,6 +266,7 @@
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 @@
}
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;
diff --git a/src/tag.c b/src/tag.c
index a4f2e25..f81956d 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -427,7 +427,7 @@
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 8b4d50c..bd3bf93 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -124,7 +124,7 @@
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 765b914..67d3095 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -21,8 +21,8 @@
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 @@
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 @@
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 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 e502001..d803c81 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -893,7 +893,7 @@
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 68d1716..de0e41b 100644
--- a/tests-clar/clar_libgit2.c
+++ b/tests-clar/clar_libgit2.c
@@ -190,6 +190,18 @@
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 93909d8..3fcf45a 100644
--- a/tests-clar/clar_libgit2.h
+++ b/tests-clar/clar_libgit2.h
@@ -60,6 +60,7 @@
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 8b17fd9..8aae1fb 100644
--- a/tests-clar/clone/nonetwork.c
+++ b/tests-clar/clone/nonetwork.c
@@ -185,6 +185,7 @@
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 @@
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 5a8af93..8134cb6 100644
--- a/tests-clar/diff/rename.c
+++ b/tests-clar/diff/rename.c
@@ -364,7 +364,7 @@
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 @@
/* 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 7d8d2cb..e6096e2 100644
--- a/tests-clar/merge/trees/trivial.c
+++ b/tests-clar/merge/trees/trivial.c
@@ -67,7 +67,7 @@
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 bcf298c..09335b3 100644
--- a/tests-clar/network/fetchlocal.c
+++ b/tests-clar/network/fetchlocal.c
@@ -34,7 +34,7 @@
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 @@
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 @@
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 4c24db8..21f27bc 100644
--- a/tests-clar/network/remote/remotes.c
+++ b/tests-clar/network/remote/remotes.c
@@ -118,13 +118,13 @@
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 @@
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 @@
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 e06760e..b927b25 100644
--- a/tests-clar/object/cache.c
+++ b/tests-clar/object/cache.c
@@ -80,7 +80,7 @@
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 @@
}
}
- 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 243b5bb..d2594cd 100644
--- a/tests-clar/refdb/inmemory.c
+++ b/tests-clar/refdb/inmemory.c
@@ -163,7 +163,7 @@
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 @@
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 627254e..961e18d 100644
--- a/tests-clar/refdb/testdb.c
+++ b/tests-clar/refdb/testdb.c
@@ -112,33 +112,49 @@
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 @@
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 96a5bc2..57f9c0e 100644
--- a/tests-clar/refs/branches/foreach.c
+++ b/tests-clar/refs/branches/foreach.c
@@ -24,6 +24,8 @@
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 @@
{
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 @@
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 @@
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 648acb4..69e55a0 100644
--- a/tests-clar/refs/branches/upstream.c
+++ b/tests-clar/refs/branches/upstream.c
@@ -113,11 +113,12 @@
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 4da1a15..2c45808 100644
--- a/tests-clar/refs/foreachglob.c
+++ b/tests-clar/refs/foreachglob.c
@@ -37,11 +37,11 @@
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 @@
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 @@
* refs/remotes/test/master, refs/tags/test
*/
- assert_retrieval("*test*", GIT_REF_LISTALL, 4);
+ assert_retrieval("*test*", 4);
}
@@ -89,7 +89,7 @@
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 0000000..d5555c6
--- /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 3948b2b..c9c2af4 100644
--- a/tests-clar/refs/list.c
+++ b/tests-clar/refs/list.c
@@ -25,7 +25,7 @@
// 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 @@
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 @@
"./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 8f4c374..c696fbb 100644
--- a/tests-clar/refs/listall.c
+++ b/tests-clar/refs/listall.c
@@ -9,7 +9,7 @@
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_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 59487d5..629d40c 100644
--- a/tests-clar/repo/message.c
+++ b/tests-clar/repo/message.c
@@ -35,13 +35,18 @@
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 0000000..cb089cd
--- /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 0000000..fc2433c
--- /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 0000000..498b267
--- /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
new file mode 100644
index 0000000..b614d07
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/index
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/info/exclude b/tests-clar/resources/testrepo2/.gitted/info/exclude
new file mode 100644
index 0000000..a5196d1
--- /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 0000000..4e80c69
--- /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 0000000..4e80c69
--- /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 0000000..4e80c69
--- /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
new file mode 100644
index 0000000..bfe146a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100644
index 0000000..cedb2a2
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100644
index 0000000..93a16f1
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100644
index 0000000..ba0bfb3
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2
new file mode 100644
index 0000000..3cd240d
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2
Binary files differ
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 0000000..0c62460
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100644
index 0000000..7ca4cee
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
Binary files differ
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 0000000..8953b6c
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xQ
+Â0DýÎ)öÊ6ͦ "xO°-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±g}Ê^3²âÙ<µåµGhYKÄèÒ8ÐDAÉ)¿ÉÈ;gôݧÚàjïp4Õ¯ô-çû¢óãêrÁ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ 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 0000000..c1f22c5
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xÛ 1EýNi@Ék2 "X$ÙYW0YcÿíÀ¿Ã
s¸¥ÕzïÚÚõMDÏ0æ8!¶ÉÌÞsXªgÚdí::@X0»P¢wÙ"F/ÍRàUz÷¥múZZïú²¤ÒV}|/o5ÝÒêI£!¬1z Æ:vùÇUim}ê/¢>
+ö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
new file mode 100644
index 0000000..1fd79b4
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100644
index 0000000..2ef4faa
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0
new file mode 100644
index 0000000..3d1016d
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100644
index 0000000..2f9b6b6
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100644
index 0000000..5df58dd
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
Binary files differ
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 0000000..a796124
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
Binary files differ
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 0000000..f858869
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100644
index 0000000..d0d7e73
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100644
index 0000000..18a7f61
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
Binary files differ
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 0000000..0817229
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+W<Jú¶Ý&8Ê/s¨eµµÈKJ«½S
+ØRvÌÁ{©æQîr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(dCÎjÊs®}Àô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}FW$Ds´Ç£©ÿÙOW
e]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 0000000..75f541f
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xQ
+Â0DýÎ)öʦ»I<'ØlR+Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]ÈåXUlÞPF)Åz4yóµ,\r 'SÂÄ-mI4
+Xhô&òÌFÞ}n+\µõY´-p|é·oUî¶z;-aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ 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
new file mode 100644
index 0000000..599e160
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100644
index 0000000..7112238
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100644
index 0000000..0377096
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100644
index 0000000..112998d
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100644
index 0000000..12bf5f3
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100644
index 0000000..94c3c71
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100644
index 0000000..74c7fe4
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/packed-refs b/tests-clar/resources/testrepo2/.gitted/packed-refs
new file mode 100644
index 0000000..97ea6a8
--- /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 0000000..a7eafce
--- /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 0000000..6efe28f
--- /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 0000000..1385f26
--- /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 0000000..fa49b07
--- /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 0000000..1385f26
--- /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 0000000..fa49b07
--- /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 0000000..1385f26
--- /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 0000000..fa49b07
--- /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 0138b17..062a09a 100644
--- a/tests-clar/status/worktree.c
+++ b/tests-clar/status/worktree.c
@@ -672,3 +672,26 @@
{
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);
+}