summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md18
-rw-r--r--include/git2/common.h1
-rw-r--r--include/git2/diff.h12
-rw-r--r--include/git2/pack.h8
-rwxr-xr-xscript/cibuild.sh4
-rwxr-xr-xscript/install-deps-osx.sh2
-rw-r--r--script/user_model.c75
-rw-r--r--src/apply.c7
-rw-r--r--src/crlf.c1
-rw-r--r--src/global.c5
-rw-r--r--src/index.c4
-rw-r--r--src/mwindow.c27
-rw-r--r--src/mwindow.h3
-rw-r--r--src/odb_pack.c3
-rw-r--r--src/pack-objects.c148
-rw-r--r--src/pack-objects.h25
-rw-r--r--src/patch_generate.c4
-rw-r--r--src/patch_parse.c8
-rw-r--r--src/remote.c14
-rw-r--r--src/repository.c8
-rw-r--r--src/settings.c8
-rw-r--r--src/util.c6
-rw-r--r--tests/core/strtol.c8
-rw-r--r--tests/core/useragent.c6
-rw-r--r--tests/iterator/iterator_helpers.c10
-rw-r--r--tests/iterator/iterator_helpers.h4
-rw-r--r--tests/repo/env.c277
-rw-r--r--tests/repo/open.c256
28 files changed, 555 insertions, 397 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44d868e7e..241c7be61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,8 +10,15 @@ v0.24 + 1
directory matching the starting directory will not prevent git from
finding a repository in the starting directory or a parent directory.
+* Do not fail when deleting remotes in the presence of broken
+ global configs which contain branches.
+
### API additions
+* You can now get the user-agent used by libgit2 using the
+ `GIT_OPT_GET_USER_AGENT` option with `git_libgit2_opts()`.
+ It is the counterpart to `GIT_OPT_SET_USER_AGENT`.
+
* `git_commit_create_buffer()` creates a commit and writes it into a
user-provided buffer instead of writing it into the object db.
@@ -44,9 +51,18 @@ v0.24 + 1
* `git_blob_create_fromchunks()` has been removed in favour of
`git_blob_create_fromstream()`.
-
### Breaking API changes
+* `git_packbuilder_object_count` and `git_packbuilder_written` now
+ return a `size_t` instead of a `uint32_t` for more thorough
+ compatibility with the rest of the library.
+
+* `git_packbuiler_progress` now provides explicitly sized `uint32_t`
+ values instead of `unsigned int`.
+
+* `git_diff_file` now includes an `id_abbrev` field that reflects the
+ number of nibbles set in the `id` field.
+
v0.24
-------
diff --git a/include/git2/common.h b/include/git2/common.h
index d7428d811..18abe46b3 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -158,6 +158,7 @@ typedef enum {
GIT_OPT_SET_USER_AGENT,
GIT_OPT_ENABLE_STRICT_OBJECT_CREATION,
GIT_OPT_SET_SSL_CIPHERS,
+ GIT_OPT_GET_USER_AGENT,
} git_libgit2_opt_t;
/**
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 005b33965..ac5db711c 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -268,11 +268,6 @@ typedef enum {
* absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta),
* then the oid will be zeroes.
*
- * The `id_abbrev` represents the known length of the `id` field, when
- * converted to a hex string. It is generally `GIT_OID_HEXSZ`, unless this
- * delta was created from reading a patch file, in which case it may be
- * abbreviated to something reasonable, like 7 characters.
- *
* `path` is the NUL-terminated path to the entry relative to the working
* directory of the repository.
*
@@ -282,14 +277,19 @@ typedef enum {
*
* `mode` is, roughly, the stat() `st_mode` value for the item. This will
* be restricted to one of the `git_filemode_t` values.
+ *
+ * The `id_abbrev` represents the known length of the `id` field, when
+ * converted to a hex string. It is generally `GIT_OID_HEXSZ`, unless this
+ * delta was created from reading a patch file, in which case it may be
+ * abbreviated to something reasonable, like 7 characters.
*/
typedef struct {
git_oid id;
- int id_abbrev;
const char *path;
git_off_t size;
uint32_t flags;
uint16_t mode;
+ uint16_t id_abbrev;
} git_diff_file;
/**
diff --git a/include/git2/pack.h b/include/git2/pack.h
index 4941998eb..2dfd825e9 100644
--- a/include/git2/pack.h
+++ b/include/git2/pack.h
@@ -196,7 +196,7 @@ GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_for
* @param pb the packbuilder
* @return the number of objects in the packfile
*/
-GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
+GIT_EXTERN(size_t) git_packbuilder_object_count(git_packbuilder *pb);
/**
* Get the number of objects the packbuilder has already written out
@@ -204,13 +204,13 @@ GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
* @param pb the packbuilder
* @return the number of objects which have already been written
*/
-GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb);
+GIT_EXTERN(size_t) git_packbuilder_written(git_packbuilder *pb);
/** Packbuilder progress notification function */
typedef int (*git_packbuilder_progress)(
int stage,
- unsigned int current,
- unsigned int total,
+ uint32_t current,
+ uint32_t total,
void *payload);
/**
diff --git a/script/cibuild.sh b/script/cibuild.sh
index 92e926490..979eb0ce4 100755
--- a/script/cibuild.sh
+++ b/script/cibuild.sh
@@ -6,6 +6,10 @@ then
exit $?;
fi
+if [ "$TRAVIS_OS_NAME" = "osx" ]; then
+ export PKG_CONFIG_PATH=$(ls -d /usr/local/Cellar/{curl,zlib}/*/lib/pkgconfig | paste -s -d':' -)
+fi
+
# Should we ask Travis to cache this file?
curl -L https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar >poxyproxy.jar || exit $?
# Run this early so we know it's ready by the time we need it
diff --git a/script/install-deps-osx.sh b/script/install-deps-osx.sh
index 5510379d4..4b8393b19 100755
--- a/script/install-deps-osx.sh
+++ b/script/install-deps-osx.sh
@@ -3,4 +3,6 @@
set -x
brew update
+brew install homebrew/dupes/zlib
+brew install curl
brew install libssh2
diff --git a/script/user_model.c b/script/user_model.c
new file mode 100644
index 000000000..a933d735c
--- /dev/null
+++ b/script/user_model.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+void *realloc(void *ptr, size_t size);
+void *memmove(void *dest, const void *src, size_t n);
+size_t strlen(const char *s);
+
+typedef struct va_list_str *va_list;
+
+typedef struct git_vector {
+ void **contents;
+ size_t length;
+} git_vector;
+
+typedef struct git_buf {
+ char *ptr;
+ size_t asize, size;
+} git_buf;
+
+int git_vector_insert(git_vector *v, void *element)
+{
+ if (!v)
+ __coverity_panic__();
+
+ v->contents = realloc(v->contents, ++v->length);
+ if (!v->contents)
+ __coverity_panic__();
+ v->contents[v->length] = element;
+
+ return 0;
+}
+
+int git_buf_len(const struct git_buf *buf)
+{
+ return strlen(buf->ptr);
+}
+
+int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
+{
+ char ch, *s;
+ size_t len;
+
+ __coverity_string_null_sink__(format);
+ __coverity_string_size_sink__(format);
+
+ ch = *format;
+ ch = *(char *)ap;
+
+ buf->ptr = __coverity_alloc__(len);
+ __coverity_writeall__(buf->ptr);
+ buf->size = len;
+
+ return 0;
+}
+
+int git_buf_put(git_buf *buf, const char *data, size_t len)
+{
+ buf->ptr = __coverity_alloc__(buf->size + len + 1);
+ memmove(buf->ptr + buf->size, data, len);
+ buf->size += len;
+ buf->ptr[buf->size + len] = 0;
+ return 0;
+}
+
+int git_buf_set(git_buf *buf, const void *data, size_t len)
+{
+ buf->ptr = __coverity_alloc__(len + 1);
+ memmove(buf->ptr, data, len);
+ buf->size = len + 1;
+ return 0;
+}
diff --git a/src/apply.c b/src/apply.c
index 876860754..40ba647f4 100644
--- a/src/apply.c
+++ b/src/apply.c
@@ -53,7 +53,10 @@ static int patch_image_init_fromstr(
for (start = in; start < in + in_len; start = end) {
end = memchr(start, '\n', in_len);
- if (end < in + in_len)
+ if (end == NULL)
+ end = in + in_len;
+
+ else if (end < in + in_len)
end++;
line = git_pool_mallocz(&out->pool, 1);
@@ -97,7 +100,7 @@ static bool match_hunk(
git_diff_line *preimage_line = git_vector_get(&preimage->lines, i);
git_diff_line *image_line = git_vector_get(&image->lines, linenum + i);
- if (preimage_line->content_len != preimage_line->content_len ||
+ if (preimage_line->content_len != image_line->content_len ||
memcmp(preimage_line->content, image_line->content, image_line->content_len) != 0) {
match = 0;
break;
diff --git a/src/crlf.c b/src/crlf.c
index 5d7510ac7..11895b19f 100644
--- a/src/crlf.c
+++ b/src/crlf.c
@@ -289,6 +289,7 @@ static int crlf_check(
ca.eol = check_eol(attr_values[1]); /* eol */
}
ca.auto_crlf = GIT_AUTO_CRLF_DEFAULT;
+ ca.safe_crlf = GIT_SAFE_CRLF_DEFAULT;
/*
* Use the core Git logic to see if we should perform CRLF for this file
diff --git a/src/global.c b/src/global.c
index eee0aea57..45b1ab8f6 100644
--- a/src/global.c
+++ b/src/global.c
@@ -61,8 +61,9 @@ static int init_common(void)
(ret = git_sysdir_global_init()) == 0 &&
(ret = git_filter_global_init()) == 0 &&
(ret = git_merge_driver_global_init()) == 0 &&
- (ret = git_transport_ssh_global_init()) == 0)
- ret = git_openssl_stream_global_init();
+ (ret = git_transport_ssh_global_init()) == 0 &&
+ (ret = git_openssl_stream_global_init()) == 0)
+ ret = git_mwindow_global_init();
GIT_MEMORY_BARRIER;
diff --git a/src/index.c b/src/index.c
index 6546ea18a..9908ba64b 100644
--- a/src/index.c
+++ b/src/index.c
@@ -2160,12 +2160,12 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
if (git__strtol64(&tmp, buffer, &endptr, 8) < 0 ||
!endptr || endptr == buffer || *endptr ||
- tmp < 0) {
+ tmp < 0 || tmp > UINT32_MAX) {
index_entry_reuc_free(lost);
return index_error_invalid("reading reuc entry stage");
}
- lost->mode[i] = tmp;
+ lost->mode[i] = (uint32_t)tmp;
len = (endptr + 1) - buffer;
if (size <= len) {
diff --git a/src/mwindow.c b/src/mwindow.c
index d3e9be78b..8a5b5caee 100644
--- a/src/mwindow.c
+++ b/src/mwindow.c
@@ -33,25 +33,20 @@ static git_mwindow_ctl mem_ctl;
/* Global list of mwindow files, to open packs once across repos */
git_strmap *git__pack_cache = NULL;
-/**
- * Run under mwindow lock
- */
-int git_mwindow_files_init(void)
+static void git_mwindow_files_free(void)
{
- if (git__pack_cache)
- return 0;
-
- git__on_shutdown(git_mwindow_files_free);
+ git_strmap *tmp = git__pack_cache;
- return git_strmap_alloc(&git__pack_cache);
+ git__pack_cache = NULL;
+ git_strmap_free(tmp);
}
-void git_mwindow_files_free(void)
+int git_mwindow_global_init(void)
{
- git_strmap *tmp = git__pack_cache;
+ assert(!git__pack_cache);
- git__pack_cache = NULL;
- git_strmap_free(tmp);
+ git__on_shutdown(git_mwindow_files_free);
+ return git_strmap_alloc(&git__pack_cache);
}
int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
@@ -69,12 +64,6 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
return -1;
}
- if (git_mwindow_files_init() < 0) {
- git_mutex_unlock(&git__mwindow_mutex);
- git__free(packname);
- return -1;
- }
-
pos = git_strmap_lookup_index(git__pack_cache, packname);
git__free(packname);
diff --git a/src/mwindow.h b/src/mwindow.h
index 63418e458..bdde9e0a4 100644
--- a/src/mwindow.h
+++ b/src/mwindow.h
@@ -43,8 +43,7 @@ int git_mwindow_file_register(git_mwindow_file *mwf);
void git_mwindow_file_deregister(git_mwindow_file *mwf);
void git_mwindow_close(git_mwindow **w_cursor);
-int git_mwindow_files_init(void);
-void git_mwindow_files_free(void);
+extern int git_mwindow_global_init(void);
struct git_pack_file; /* just declaration to avoid cyclical includes */
int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 244e12bc3..005d07264 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -591,9 +591,6 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
struct pack_backend *backend = NULL;
git_buf path = GIT_BUF_INIT;
- if (git_mwindow_files_init() < 0)
- return -1;
-
if (pack_backend__alloc(&backend, 8) < 0)
return -1;
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 288aebb20..9f62322f7 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -28,7 +28,7 @@ struct unpacked {
git_pobject *object;
void *data;
struct git_delta_index *index;
- int depth;
+ size_t depth;
};
struct tree_walk_context {
@@ -99,8 +99,15 @@ static int packbuilder_config(git_packbuilder *pb)
#define config_get(KEY,DST,DFLT) do { \
ret = git_config_get_int64(&val, config, KEY); \
- if (!ret) (DST) = val; \
- else if (ret == GIT_ENOTFOUND) { \
+ if (!ret) { \
+ if (!git__is_sizet(val)) { \
+ giterr_set(GITERR_CONFIG, \
+ "configuration value '%s' is too large", KEY); \
+ ret = -1; \
+ goto out; \
+ } \
+ (DST) = (size_t)val; \
+ } else if (ret == GIT_ENOTFOUND) { \
(DST) = (DFLT); \
ret = 0; \
} else if (ret < 0) goto out; } while (0)
@@ -187,7 +194,7 @@ static void rehash(git_packbuilder *pb)
{
git_pobject *po;
khiter_t pos;
- unsigned int i;
+ size_t i;
int ret;
kh_clear(oid, pb->object_ix);
@@ -222,7 +229,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
return -1;
}
- pb->nr_alloc = (uint32_t)newsize;
+ pb->nr_alloc = newsize;
pb->object_list = git__reallocarray(pb->object_list,
pb->nr_alloc, sizeof(*po));
@@ -272,7 +279,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
static int get_delta(void **out, git_odb *odb, git_pobject *po)
{
git_odb_object *src = NULL, *trg = NULL;
- unsigned long delta_size;
+ size_t delta_size;
void *delta_buf;
int error;
@@ -441,8 +448,8 @@ static int write_one(
return write_object(pb, po, write_cb, cb_data);
}
-GIT_INLINE(void) add_to_write_order(git_pobject **wo, unsigned int *endp,
- git_pobject *po)
+GIT_INLINE(void) add_to_write_order(git_pobject **wo, size_t *endp,
+ git_pobject *po)
{
if (po->filled)
return;
@@ -450,8 +457,8 @@ GIT_INLINE(void) add_to_write_order(git_pobject **wo, unsigned int *endp,
po->filled = 1;
}
-static void add_descendants_to_write_order(git_pobject **wo, unsigned int *endp,
- git_pobject *po)
+static void add_descendants_to_write_order(git_pobject **wo, size_t *endp,
+ git_pobject *po)
{
int add_to_order = 1;
while (po) {
@@ -492,8 +499,8 @@ static void add_descendants_to_write_order(git_pobject **wo, unsigned int *endp,
};
}
-static void add_family_to_write_order(git_pobject **wo, unsigned int *endp,
- git_pobject *po)
+static void add_family_to_write_order(git_pobject **wo, size_t *endp,
+ git_pobject *po)
{
git_pobject *root;
@@ -524,7 +531,7 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
static git_pobject **compute_write_order(git_packbuilder *pb)
{
- unsigned int i, wo_end, last_untagged;
+ size_t i, wo_end, last_untagged;
git_pobject **wo;
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
@@ -629,13 +636,18 @@ static int write_pack(git_packbuilder *pb,
enum write_one_status status;
struct git_pack_header ph;
git_oid entry_oid;
- unsigned int i = 0;
+ size_t i = 0;
int error = 0;
write_order = compute_write_order(pb);
if (write_order == NULL)
return -1;
+ if (!git__is_uint32(pb->nr_objects)) {
+ giterr_set(GITERR_INVALID, "too many objects");
+ return -1;
+ }
+
/* Write pack header */
ph.hdr_signature = htonl(PACK_SIGNATURE);
ph.hdr_version = htonl(PACK_VERSION);
@@ -711,11 +723,18 @@ static int type_size_sort(const void *_a, const void *_b)
return a < b ? -1 : (a > b); /* newest first */
}
-static int delta_cacheable(git_packbuilder *pb, unsigned long src_size,
- unsigned long trg_size, unsigned long delta_size)
+static int delta_cacheable(
+ git_packbuilder *pb,
+ size_t src_size,
+ size_t trg_size,
+ size_t delta_size)
{
- if (pb->max_delta_cache_size &&
- pb->delta_cache_size + delta_size > pb->max_delta_cache_size)
+ size_t new_size;
+
+ if (git__add_sizet_overflow(&new_size, pb->delta_cache_size, delta_size))
+ return 0;
+
+ if (pb->max_delta_cache_size && new_size > pb->max_delta_cache_size)
return 0;
if (delta_size < pb->cache_max_small_delta_size)
@@ -729,15 +748,14 @@ static int delta_cacheable(git_packbuilder *pb, unsigned long src_size,
}
static int try_delta(git_packbuilder *pb, struct unpacked *trg,
- struct unpacked *src, int max_depth,
- unsigned long *mem_usage, int *ret)
+ struct unpacked *src, size_t max_depth,
+ size_t *mem_usage, int *ret)
{
git_pobject *trg_object = trg->object;
git_pobject *src_object = src->object;
git_odb_object *obj;
- unsigned long trg_size, src_size, delta_size,
- sizediff, max_size, sz;
- unsigned int ref_depth;
+ size_t trg_size, src_size, delta_size, sizediff, max_size, sz;
+ size_t ref_depth;
void *delta_buf;
/* Don't bother doing diffs between different types */
@@ -755,7 +773,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
return 0;
/* Now some size filtering heuristics. */
- trg_size = (unsigned long)trg_object->size;
+ trg_size = trg_object->size;
if (!trg_object->delta) {
max_size = trg_size/2 - 20;
ref_depth = 1;
@@ -769,7 +787,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
if (max_size == 0)
return 0;
- src_size = (unsigned long)src_object->size;
+ src_size = src_object->size;
sizediff = src_size < trg_size ? trg_size - src_size : 0;
if (sizediff >= max_size)
return 0;
@@ -781,7 +799,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
if (git_odb_read(&obj, pb->odb, &trg_object->id) < 0)
return -1;
- sz = (unsigned long)git_odb_object_size(obj);
+ sz = git_odb_object_size(obj);
trg->data = git__malloc(sz);
GITERR_CHECK_ALLOC(trg->data);
memcpy(trg->data, git_odb_object_data(obj), sz);
@@ -803,7 +821,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
!git__is_ulong(obj_sz = git_odb_object_size(obj)))
return -1;
- sz = (unsigned long)obj_sz;
+ sz = obj_sz;
src->data = git__malloc(sz);
GITERR_CHECK_ALLOC(src->data);
memcpy(src->data, git_odb_object_data(obj), sz);
@@ -841,11 +859,12 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
git_packbuilder__cache_lock(pb);
if (trg_object->delta_data) {
git__free(trg_object->delta_data);
+ assert(pb->delta_cache_size >= trg_object->delta_size);
pb->delta_cache_size -= trg_object->delta_size;
trg_object->delta_data = NULL;
}
if (delta_cacheable(pb, src_size, trg_size, delta_size)) {
- bool overflow = git__add_uint64_overflow(
+ bool overflow = git__add_sizet_overflow(
&pb->delta_cache_size, pb->delta_cache_size, delta_size);
git_packbuilder__cache_unlock(pb);
@@ -871,13 +890,13 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
return 0;
}
-static unsigned int check_delta_limit(git_pobject *me, unsigned int n)
+static size_t check_delta_limit(git_pobject *me, size_t n)
{
git_pobject *child = me->delta_child;
- unsigned int m = n;
+ size_t m = n;
while (child) {
- unsigned int c = check_delta_limit(child, n + 1);
+ size_t c = check_delta_limit(child, n + 1);
if (m < c)
m = c;
child = child->delta_sibling;
@@ -885,9 +904,9 @@ static unsigned int check_delta_limit(git_pobject *me, unsigned int n)
return m;
}
-static unsigned long free_unpacked(struct unpacked *n)
+static size_t free_unpacked(struct unpacked *n)
{
- unsigned long freed_mem = 0;
+ size_t freed_mem = 0;
if (n->index) {
freed_mem += git_delta_index_size(n->index);
@@ -896,7 +915,7 @@ static unsigned long free_unpacked(struct unpacked *n)
n->index = NULL;
if (n->data) {
- freed_mem += (unsigned long)n->object->size;
+ freed_mem += n->object->size;
git__free(n->data);
n->data = NULL;
}
@@ -905,7 +924,8 @@ static unsigned long free_unpacked(struct unpacked *n)
return freed_mem;
}
-static int report_delta_progress(git_packbuilder *pb, uint32_t count, bool force)
+static int report_delta_progress(
+ git_packbuilder *pb, uint32_t count, bool force)
{
int ret;
@@ -929,15 +949,14 @@ static int report_delta_progress(git_packbuilder *pb, uint32_t count, bool force
}
static int find_deltas(git_packbuilder *pb, git_pobject **list,
- unsigned int *list_size, unsigned int window,
- int depth)
+ size_t *list_size, size_t window, size_t depth)
{
git_pobject *po;
git_buf zbuf = GIT_BUF_INIT;
struct unpacked *array;
- uint32_t idx = 0, count = 0;
- unsigned long mem_usage = 0;
- unsigned int i;
+ size_t idx = 0, count = 0;
+ size_t mem_usage = 0;
+ size_t i;
int error = -1;
array = git__calloc(window, sizeof(struct unpacked));
@@ -945,7 +964,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
for (;;) {
struct unpacked *n = array + idx;
- int max_depth, j, best_base = -1;
+ size_t max_depth, j, best_base = SIZE_MAX;
git_packbuilder__progress_lock(pb);
if (!*list_size) {
@@ -966,7 +985,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
while (pb->window_memory_limit &&
mem_usage > pb->window_memory_limit &&
count > 1) {
- uint32_t tail = (idx + window - count) % window;
+ size_t tail = (idx + window - count) % window;
mem_usage -= free_unpacked(array + tail);
count--;
}
@@ -978,15 +997,18 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
*/
max_depth = depth;
if (po->delta_child) {
- max_depth -= check_delta_limit(po, 0);
- if (max_depth <= 0)
+ size_t delta_limit = check_delta_limit(po, 0);
+
+ if (delta_limit > max_depth)
goto next;
+
+ max_depth -= delta_limit;
}
j = window;
while (--j > 0) {
int ret;
- uint32_t other_idx = idx + j;
+ size_t other_idx = idx + j;
struct unpacked *m;
if (other_idx >= window)
@@ -1027,7 +1049,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
GITERR_CHECK_ALLOC(po->delta_data);
memcpy(po->delta_data, zbuf.ptr, zbuf.size);
- po->z_delta_size = (unsigned long)zbuf.size;
+ po->z_delta_size = zbuf.size;
git_buf_clear(&zbuf);
git_packbuilder__cache_lock(pb);
@@ -1051,10 +1073,10 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
*/
if (po->delta) {
struct unpacked swap = array[best_base];
- int dist = (window + idx - best_base) % window;
- int dst = best_base;
+ size_t dist = (window + idx - best_base) % window;
+ size_t dst = best_base;
while (dist--) {
- int src = (dst + 1) % window;
+ size_t src = (dst + 1) % window;
array[dst] = array[src];
dst = src;
}
@@ -1092,13 +1114,13 @@ struct thread_params {
git_cond cond;
git_mutex mutex;
- unsigned int list_size;
- unsigned int remaining;
+ size_t list_size;
+ size_t remaining;
- int window;
- int depth;
- int working;
- int data_ready;
+ size_t window;
+ size_t depth;
+ size_t working;
+ size_t data_ready;
};
static void *threaded_find_deltas(void *arg)
@@ -1140,11 +1162,11 @@ static void *threaded_find_deltas(void *arg)
}
static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
- unsigned int list_size, unsigned int window,
- int depth)
+ size_t list_size, size_t window, size_t depth)
{
struct thread_params *p;
- int i, ret, active_threads = 0;
+ size_t i;
+ int ret, active_threads = 0;
if (!pb->nr_threads)
pb->nr_threads = git_online_cpus();
@@ -1159,7 +1181,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
/* Partition the work among the threads */
for (i = 0; i < pb->nr_threads; ++i) {
- unsigned sub_size = list_size / (pb->nr_threads - i);
+ size_t sub_size = list_size / (pb->nr_threads - i);
/* don't use too small segments or no deltas will be found */
if (sub_size < 2*window && i+1 < pb->nr_threads)
@@ -1213,7 +1235,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
while (active_threads) {
struct thread_params *target = NULL;
struct thread_params *victim = NULL;
- unsigned sub_size = 0;
+ size_t sub_size = 0;
/* Start by locating a thread that has transitioned its
* 'working' flag from 1 -> 0. This indicates that it is
@@ -1293,7 +1315,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
static int prepare_pack(git_packbuilder *pb)
{
git_pobject **delta_list;
- unsigned int i, n = 0;
+ size_t i, n = 0;
if (pb->nr_objects == 0 || pb->done)
return 0; /* nothing to do */
@@ -1480,12 +1502,12 @@ cleanup:
return error;
}
-uint32_t git_packbuilder_object_count(git_packbuilder *pb)
+size_t git_packbuilder_object_count(git_packbuilder *pb)
{
return pb->nr_objects;
}
-uint32_t git_packbuilder_written(git_packbuilder *pb)
+size_t git_packbuilder_written(git_packbuilder *pb)
{
return pb->nr_written;
}
diff --git a/src/pack-objects.h b/src/pack-objects.h
index 82dea81f5..5a84f4158 100644
--- a/src/pack-objects.h
+++ b/src/pack-objects.h
@@ -42,8 +42,8 @@ typedef struct git_pobject {
* me */
void *delta_data;
- unsigned long delta_size;
- unsigned long z_delta_size;
+ size_t delta_size;
+ size_t z_delta_size;
int written:1,
recursing:1,
@@ -65,10 +65,11 @@ struct git_packbuilder {
git_zstream zstream;
uint32_t nr_objects,
- nr_deltified,
- nr_alloc,
- nr_written,
- nr_remaining;
+ nr_deltified,
+ nr_written,
+ nr_remaining;
+
+ size_t nr_alloc;
git_pobject *object_list;
@@ -85,13 +86,13 @@ struct git_packbuilder {
git_cond progress_cond;
/* configs */
- uint64_t delta_cache_size;
- uint64_t max_delta_cache_size;
- uint64_t cache_max_small_delta_size;
- uint64_t big_file_threshold;
- uint64_t window_memory_limit;
+ size_t delta_cache_size;
+ size_t max_delta_cache_size;
+ size_t cache_max_small_delta_size;
+ size_t big_file_threshold;
+ size_t window_memory_limit;
- int nr_threads; /* nr of threads to use */
+ unsigned int nr_threads; /* nr of threads to use */
git_packbuilder_progress progress_cb;
void *progress_cb_payload;
diff --git a/src/patch_generate.c b/src/patch_generate.c
index 98c14923d..feac4f67a 100644
--- a/src/patch_generate.c
+++ b/src/patch_generate.c
@@ -284,7 +284,7 @@ static int create_binary(
size_t b_datalen)
{
git_buf deflate = GIT_BUF_INIT, delta = GIT_BUF_INIT;
- unsigned long delta_data_len;
+ size_t delta_data_len;
int error;
/* The git_delta function accepts unsigned long only */
@@ -310,7 +310,7 @@ static int create_binary(
if (error == 0) {
error = git_zstream_deflatebuf(
- &delta, delta_data, (size_t)delta_data_len);
+ &delta, delta_data, delta_data_len);
git__free(delta_data);
} else if (error == GIT_EBUFS) {
diff --git a/src/patch_parse.c b/src/patch_parse.c
index 7f21e3f8e..82d2d3e2e 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -192,7 +192,7 @@ static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
static int parse_header_oid(
git_oid *oid,
- int *oid_len,
+ uint16_t *oid_len,
git_patch_parse_ctx *ctx)
{
size_t len;
@@ -202,14 +202,14 @@ static int parse_header_oid(
break;
}
- if (len < GIT_OID_MINPREFIXLEN ||
+ if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_HEXSZ ||
git_oid_fromstrn(oid, ctx->line, len) < 0)
return parse_err("invalid hex formatted object id at line %d",
ctx->line_num);
parse_advance_chars(ctx, len);
- *oid_len = (int)len;
+ *oid_len = (uint16_t)len;
return 0;
}
@@ -897,7 +897,7 @@ done:
*out_len = (path - path_start);
*out = git__strndup(path_start, *out_len);
- return (out == NULL) ? -1 : 0;
+ return (*out == NULL) ? -1 : 0;
}
static int check_filenames(git_patch_parsed *patch)
diff --git a/src/remote.c b/src/remote.c
index 5f89c4026..c1d7d59ea 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -2162,15 +2162,21 @@ static int remove_branch_config_related_entries(
if (git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch) < 0)
break;
- if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
- break;
+ if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) {
+ if (error != GIT_ENOTFOUND)
+ break;
+ giterr_clear();
+ }
git_buf_clear(&buf);
if (git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch) < 0)
break;
- if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
- break;
+ if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) {
+ if (error != GIT_ENOTFOUND)
+ break;
+ giterr_clear();
+ }
}
if (error == GIT_ITEROVER)
diff --git a/src/repository.c b/src/repository.c
index ecc07806e..cf3d18a2d 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -264,7 +264,7 @@ cleanup:
* the stack could remove directories name limits, but at the cost of doing
* repeated malloc/frees inside the loop below, so let's not do it now.
*/
-static int find_ceiling_dir_offset(
+static size_t find_ceiling_dir_offset(
const char *path,
const char *ceiling_directories)
{
@@ -278,7 +278,7 @@ static int find_ceiling_dir_offset(
min_len = (size_t)(git_path_root(path) + 1);
if (ceiling_directories == NULL || min_len == 0)
- return (int)min_len;
+ return min_len;
for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
@@ -305,7 +305,7 @@ static int find_ceiling_dir_offset(
}
}
- return (int)(max_len <= min_len ? min_len : max_len);
+ return (max_len <= min_len ? min_len : max_len);
}
/*
@@ -362,7 +362,7 @@ static int find_repo(
dev_t initial_device = 0;
int min_iterations;
bool in_dot_git;
- int ceiling_offset;
+ size_t ceiling_offset = 0;
git_buf_free(repo_path);
diff --git a/src/settings.c b/src/settings.c
index 21430bce9..cb2317f74 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -207,6 +207,14 @@ int git_libgit2_opts(int key, ...)
#endif
break;
+ case GIT_OPT_GET_USER_AGENT:
+ {
+ git_buf *out = va_arg(ap, git_buf *);
+ git_buf_sanitize(out);
+ error = git_buf_sets(out, git__user_agent);
+ }
+ break;
+
default:
giterr_set(GITERR_INVALID, "invalid option key");
error = -1;
diff --git a/src/util.c b/src/util.c
index 3090c7437..e9cccea20 100644
--- a/src/util.c
+++ b/src/util.c
@@ -128,8 +128,8 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
v = c - 'A' + 10;
if (v >= base)
break;
- nn = n*base + v;
- if (nn < n)
+ nn = n * base + (neg ? -v : v);
+ if ((!neg && nn < n) || (neg && nn > n))
ovfl = 1;
n = nn;
}
@@ -148,7 +148,7 @@ Return:
return -1;
}
- *result = neg ? -n : n;
+ *result = n;
return 0;
}
diff --git a/tests/core/strtol.c b/tests/core/strtol.c
index 8765e042b..0d3b6a5e6 100644
--- a/tests/core/strtol.c
+++ b/tests/core/strtol.c
@@ -33,5 +33,13 @@ void test_core_strtol__int64(void)
cl_assert(i == 2147483657LL);
cl_git_pass(git__strtol64(&i, " -2147483657 ", NULL, 10));
cl_assert(i == -2147483657LL);
+ cl_git_pass(git__strtol64(&i, " 9223372036854775807 ", NULL, 10));
+ cl_assert(i == INT64_MAX);
+ cl_git_pass(git__strtol64(&i, " -9223372036854775808 ", NULL, 10));
+ cl_assert(i == INT64_MIN);
+ cl_git_pass(git__strtol64(&i, " 0x7fffffffffffffff ", NULL, 16));
+ cl_assert(i == INT64_MAX);
+ cl_git_pass(git__strtol64(&i, " -0x8000000000000000 ", NULL, 16));
+ cl_assert(i == INT64_MIN);
}
diff --git a/tests/core/useragent.c b/tests/core/useragent.c
index 6d06693a8..5c09223bb 100644
--- a/tests/core/useragent.c
+++ b/tests/core/useragent.c
@@ -4,8 +4,14 @@
void test_core_useragent__get(void)
{
const char *custom_name = "super duper git";
+ git_buf buf = GIT_BUF_INIT;
cl_assert_equal_p(NULL, git_libgit2__user_agent());
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_USER_AGENT, custom_name));
cl_assert_equal_s(custom_name, git_libgit2__user_agent());
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_GET_USER_AGENT, &buf));
+ cl_assert_equal_s(custom_name, buf.ptr);
+
+ git_buf_free(&buf);
}
diff --git a/tests/iterator/iterator_helpers.c b/tests/iterator/iterator_helpers.c
index a3e803299..ae48fcd46 100644
--- a/tests/iterator/iterator_helpers.c
+++ b/tests/iterator/iterator_helpers.c
@@ -18,18 +18,16 @@ static void assert_at_end(git_iterator *i, bool verbose)
void expect_iterator_items(
git_iterator *i,
- int expected_flat,
+ size_t expected_flat,
const char **expected_flat_paths,
- int expected_total,
+ size_t expected_total,
const char **expected_total_paths)
{
const git_index_entry *entry;
- int count, error;
+ size_t count;
int no_trees = !(git_iterator_flags(i) & GIT_ITERATOR_INCLUDE_TREES);
bool v = false;
-
- if (expected_flat < 0) { v = true; expected_flat = -expected_flat; }
- if (expected_total < 0) { v = true; expected_total = -expected_total; }
+ int error;
if (v) fprintf(stderr, "== %s ==\n", no_trees ? "notrees" : "trees");
diff --git a/tests/iterator/iterator_helpers.h b/tests/iterator/iterator_helpers.h
index 8d0a17014..1884b41a1 100644
--- a/tests/iterator/iterator_helpers.h
+++ b/tests/iterator/iterator_helpers.h
@@ -1,9 +1,9 @@
extern void expect_iterator_items(
git_iterator *i,
- int expected_flat,
+ size_t expected_flat,
const char **expected_flat_paths,
- int expected_total,
+ size_t expected_total,
const char **expected_total_paths);
extern void expect_advance_over(
diff --git a/tests/repo/env.c b/tests/repo/env.c
new file mode 100644
index 000000000..5a89c0d49
--- /dev/null
+++ b/tests/repo/env.c
@@ -0,0 +1,277 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "sysdir.h"
+#include <ctype.h>
+
+static void clear_git_env(void)
+{
+ cl_setenv("GIT_DIR", NULL);
+ cl_setenv("GIT_CEILING_DIRECTORIES", NULL);
+ cl_setenv("GIT_INDEX_FILE", NULL);
+ cl_setenv("GIT_NAMESPACE", NULL);
+ cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
+ cl_setenv("GIT_WORK_TREE", NULL);
+ cl_setenv("GIT_COMMON_DIR", NULL);
+}
+
+void test_repo_env__initialize(void)
+{
+ clear_git_env();
+}
+
+void test_repo_env__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+
+ if (git_path_isdir("attr"))
+ git_futils_rmdir_r("attr", NULL, GIT_RMDIR_REMOVE_FILES);
+ if (git_path_isdir("testrepo.git"))
+ git_futils_rmdir_r("testrepo.git", NULL, GIT_RMDIR_REMOVE_FILES);
+ if (git_path_isdir("peeled.git"))
+ git_futils_rmdir_r("peeled.git", NULL, GIT_RMDIR_REMOVE_FILES);
+
+ clear_git_env();
+}
+
+static int GIT_FORMAT_PRINTF(2, 3) cl_setenv_printf(const char *name, const char *fmt, ...)
+{
+ int ret;
+ va_list args;
+ git_buf buf = GIT_BUF_INIT;
+
+ va_start(args, fmt);
+ cl_git_pass(git_buf_vprintf(&buf, fmt, args));
+ va_end(args);
+
+ ret = cl_setenv(name, git_buf_cstr(&buf));
+ git_buf_free(&buf);
+ return ret;
+}
+
+/* Helper functions for test_repo_open__env, passing through the file and line
+ * from the caller rather than those of the helper. The expression strings
+ * distinguish between the possible failures within the helper. */
+
+static void env_pass_(const char *path, const char *file, int line)
+{
+ git_repository *repo;
+ cl_git_pass_(git_repository_open_ext(NULL, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
+ cl_git_pass_(git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
+ cl_assert_at_line(git__suffixcmp(git_repository_path(repo), "attr/.git/") == 0, file, line);
+ cl_assert_at_line(git__suffixcmp(git_repository_workdir(repo), "attr/") == 0, file, line);
+ cl_assert_at_line(!git_repository_is_bare(repo), file, line);
+ git_repository_free(repo);
+}
+#define env_pass(path) env_pass_((path), __FILE__, __LINE__)
+
+#define cl_git_fail_at_line(expr, file, line) clar__assert((expr) < 0, file, line, "Expected function call to fail: " #expr, NULL, 1)
+
+static void env_fail_(const char *path, const char *file, int line)
+{
+ git_repository *repo;
+ cl_git_fail_at_line(git_repository_open_ext(NULL, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
+ cl_git_fail_at_line(git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
+}
+#define env_fail(path) env_fail_((path), __FILE__, __LINE__)
+
+static void env_cd_(
+ const char *path,
+ void (*passfail_)(const char *, const char *, int),
+ const char *file, int line)
+{
+ git_buf cwd_buf = GIT_BUF_INIT;
+ cl_git_pass(git_path_prettify_dir(&cwd_buf, ".", NULL));
+ cl_must_pass(p_chdir(path));
+ passfail_(NULL, file, line);
+ cl_must_pass(p_chdir(git_buf_cstr(&cwd_buf)));
+ git_buf_free(&cwd_buf);
+}
+#define env_cd_pass(path) env_cd_((path), env_pass_, __FILE__, __LINE__)
+#define env_cd_fail(path) env_cd_((path), env_fail_, __FILE__, __LINE__)
+
+static void env_check_objects_(bool a, bool t, bool p, const char *file, int line)
+{
+ git_repository *repo;
+ git_oid oid_a, oid_t, oid_p;
+ git_object *object;
+ cl_git_pass(git_oid_fromstr(&oid_a, "45141a79a77842c59a63229403220a4e4be74e3d"));
+ cl_git_pass(git_oid_fromstr(&oid_t, "1385f264afb75a56a5bec74243be9b367ba4ca08"));
+ cl_git_pass(git_oid_fromstr(&oid_p, "0df1a5865c8abfc09f1f2182e6a31be550e99f07"));
+ cl_git_pass_(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
+
+ if (a) {
+ cl_git_pass_(git_object_lookup(&object, repo, &oid_a, GIT_OBJ_BLOB), file, line);
+ git_object_free(object);
+ } else {
+ cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_a, GIT_OBJ_BLOB), file, line);
+ }
+
+ if (t) {
+ cl_git_pass_(git_object_lookup(&object, repo, &oid_t, GIT_OBJ_BLOB), file, line);
+ git_object_free(object);
+ } else {
+ cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_t, GIT_OBJ_BLOB), file, line);
+ }
+
+ if (p) {
+ cl_git_pass_(git_object_lookup(&object, repo, &oid_p, GIT_OBJ_COMMIT), file, line);
+ git_object_free(object);
+ } else {
+ cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_p, GIT_OBJ_COMMIT), file, line);
+ }
+
+ git_repository_free(repo);
+}
+#define env_check_objects(a, t, t2) env_check_objects_((a), (t), (t2), __FILE__, __LINE__)
+
+void test_repo_env__open(void)
+{
+ git_repository *repo = NULL;
+ git_buf repo_dir_buf = GIT_BUF_INIT;
+ const char *repo_dir = NULL;
+ git_index *index = NULL;
+ const char *t_obj = "testrepo.git/objects";
+ const char *p_obj = "peeled.git/objects";
+
+ clear_git_env();
+
+ cl_fixture_sandbox("attr");
+ cl_fixture_sandbox("testrepo.git");
+ cl_fixture_sandbox("peeled.git");
+ cl_git_pass(p_rename("attr/.gitted", "attr/.git"));
+
+ cl_git_pass(git_path_prettify_dir(&repo_dir_buf, "attr", NULL));
+ repo_dir = git_buf_cstr(&repo_dir_buf);
+
+ /* GIT_DIR that doesn't exist */
+ cl_setenv("GIT_DIR", "does-not-exist");
+ env_fail(NULL);
+ /* Explicit start_path overrides GIT_DIR */
+ env_pass("attr");
+ env_pass("attr/.git");
+ env_pass("attr/sub");
+ env_pass("attr/sub/sub");
+
+ /* GIT_DIR with relative paths */
+ cl_setenv("GIT_DIR", "attr/.git");
+ env_pass(NULL);
+ cl_setenv("GIT_DIR", "attr");
+ env_fail(NULL);
+ cl_setenv("GIT_DIR", "attr/sub");
+ env_fail(NULL);
+ cl_setenv("GIT_DIR", "attr/sub/sub");
+ env_fail(NULL);
+
+ /* GIT_DIR with absolute paths */
+ cl_setenv_printf("GIT_DIR", "%s/.git", repo_dir);
+ env_pass(NULL);
+ cl_setenv("GIT_DIR", repo_dir);
+ env_fail(NULL);
+ cl_setenv_printf("GIT_DIR", "%s/sub", repo_dir);
+ env_fail(NULL);
+ cl_setenv_printf("GIT_DIR", "%s/sub/sub", repo_dir);
+ env_fail(NULL);
+ cl_setenv("GIT_DIR", NULL);
+
+ /* Searching from the current directory */
+ env_cd_pass("attr");
+ env_cd_pass("attr/.git");
+ env_cd_pass("attr/sub");
+ env_cd_pass("attr/sub/sub");
+
+ /* A ceiling directory blocks searches from ascending into that
+ * directory, but doesn't block the start_path itself. */
+ cl_setenv("GIT_CEILING_DIRECTORIES", repo_dir);
+ env_cd_pass("attr");
+ env_cd_fail("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s/sub", repo_dir);
+ env_cd_pass("attr");
+ env_cd_pass("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ /* Multiple ceiling directories */
+ cl_setenv_printf("GIT_CEILING_DIRECTORIES", "123%c%s/sub%cabc",
+ GIT_PATH_LIST_SEPARATOR, repo_dir, GIT_PATH_LIST_SEPARATOR);
+ env_cd_pass("attr");
+ env_cd_pass("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s%c%s/sub",
+ repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
+ env_cd_pass("attr");
+ env_cd_fail("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s/sub%c%s",
+ repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
+ env_cd_pass("attr");
+ env_cd_fail("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s%c%s/sub/sub",
+ repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
+ env_cd_pass("attr");
+ env_cd_fail("attr/sub");
+ env_cd_fail("attr/sub/sub");
+
+ cl_setenv("GIT_CEILING_DIRECTORIES", NULL);
+
+ /* Index files */
+ cl_setenv("GIT_INDEX_FILE", cl_fixture("gitgit.index"));
+ cl_git_pass(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL));
+ cl_git_pass(git_repository_index(&index, repo));
+ cl_assert_equal_s(git_index_path(index), cl_fixture("gitgit.index"));
+ cl_assert_equal_i(git_index_entrycount(index), 1437);
+ git_index_free(index);
+ git_repository_free(repo);
+ cl_setenv("GIT_INDEX_FILE", NULL);
+
+ /* Namespaces */
+ cl_setenv("GIT_NAMESPACE", "some-namespace");
+ cl_git_pass(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL));
+ cl_assert_equal_s(git_repository_get_namespace(repo), "some-namespace");
+ git_repository_free(repo);
+ cl_setenv("GIT_NAMESPACE", NULL);
+
+ /* Object directories and alternates */
+ env_check_objects(true, false, false);
+
+ cl_setenv("GIT_OBJECT_DIRECTORY", t_obj);
+ env_check_objects(false, true, false);
+ cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
+
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", t_obj);
+ env_check_objects(true, true, false);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
+
+ cl_setenv("GIT_OBJECT_DIRECTORY", p_obj);
+ env_check_objects(false, false, true);
+ cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
+
+ cl_setenv("GIT_OBJECT_DIRECTORY", t_obj);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", p_obj);
+ env_check_objects(false, true, true);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
+ cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
+
+ cl_setenv_printf("GIT_ALTERNATE_OBJECT_DIRECTORIES",
+ "%s%c%s", t_obj, GIT_PATH_LIST_SEPARATOR, p_obj);
+ env_check_objects(true, true, true);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
+
+ cl_setenv_printf("GIT_ALTERNATE_OBJECT_DIRECTORIES",
+ "%s%c%s", p_obj, GIT_PATH_LIST_SEPARATOR, t_obj);
+ env_check_objects(true, true, true);
+ cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
+
+ cl_fixture_cleanup("peeled.git");
+ cl_fixture_cleanup("testrepo.git");
+ cl_fixture_cleanup("attr");
+
+ git_buf_free(&repo_dir_buf);
+
+ clear_git_env();
+}
diff --git a/tests/repo/open.c b/tests/repo/open.c
index 86353dd25..6114ad2e1 100644
--- a/tests/repo/open.c
+++ b/tests/repo/open.c
@@ -3,26 +3,6 @@
#include "sysdir.h"
#include <ctype.h>
-static void clear_git_env(void)
-{
- cl_setenv("GIT_DIR", NULL);
- cl_setenv("GIT_CEILING_DIRECTORIES", NULL);
- cl_setenv("GIT_INDEX_FILE", NULL);
- cl_setenv("GIT_NAMESPACE", NULL);
- cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
- cl_setenv("GIT_WORK_TREE", NULL);
- cl_setenv("GIT_COMMON_DIR", NULL);
-}
-
-static git_buf cwd_backup_buf = GIT_BUF_INIT;
-
-void test_repo_open__initialize(void)
-{
- if (!git_buf_is_allocated(&cwd_backup_buf))
- cl_git_pass(git_path_prettify_dir(&cwd_backup_buf, ".", NULL));
- clear_git_env();
-}
void test_repo_open__cleanup(void)
{
@@ -30,15 +10,6 @@ void test_repo_open__cleanup(void)
if (git_path_isdir("alternate"))
git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES);
- if (git_path_isdir("attr"))
- git_futils_rmdir_r("attr", NULL, GIT_RMDIR_REMOVE_FILES);
- if (git_path_isdir("testrepo.git"))
- git_futils_rmdir_r("testrepo.git", NULL, GIT_RMDIR_REMOVE_FILES);
- if (git_path_isdir("peeled.git"))
- git_futils_rmdir_r("peeled.git", NULL, GIT_RMDIR_REMOVE_FILES);
-
- cl_must_pass(p_chdir(git_buf_cstr(&cwd_backup_buf)));
- clear_git_env();
}
void test_repo_open__bare_empty_repo(void)
@@ -432,230 +403,3 @@ void test_repo_open__force_bare(void)
git_repository_free(barerepo);
}
-static int GIT_FORMAT_PRINTF(2, 3) cl_setenv_printf(const char *name, const char *fmt, ...)
-{
- int ret;
- va_list args;
- git_buf buf = GIT_BUF_INIT;
-
- va_start(args, fmt);
- cl_git_pass(git_buf_vprintf(&buf, fmt, args));
- va_end(args);
-
- ret = cl_setenv(name, git_buf_cstr(&buf));
- git_buf_free(&buf);
- return ret;
-}
-
-/* Helper functions for test_repo_open__env, passing through the file and line
- * from the caller rather than those of the helper. The expression strings
- * distinguish between the possible failures within the helper. */
-
-static void env_pass_(const char *path, const char *file, int line)
-{
- git_repository *repo;
- cl_git_pass_(git_repository_open_ext(NULL, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
- cl_git_pass_(git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
- cl_assert_at_line(git__suffixcmp(git_repository_path(repo), "attr/.git/") == 0, file, line);
- cl_assert_at_line(git__suffixcmp(git_repository_workdir(repo), "attr/") == 0, file, line);
- cl_assert_at_line(!git_repository_is_bare(repo), file, line);
- git_repository_free(repo);
-}
-#define env_pass(path) env_pass_((path), __FILE__, __LINE__)
-
-#define cl_git_fail_at_line(expr, file, line) clar__assert((expr) < 0, file, line, "Expected function call to fail: " #expr, NULL, 1)
-
-static void env_fail_(const char *path, const char *file, int line)
-{
- git_repository *repo;
- cl_git_fail_at_line(git_repository_open_ext(NULL, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
- cl_git_fail_at_line(git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
-}
-#define env_fail(path) env_fail_((path), __FILE__, __LINE__)
-
-static void env_cd_(
- const char *path,
- void (*passfail_)(const char *, const char *, int),
- const char *file, int line)
-{
- git_buf cwd_buf = GIT_BUF_INIT;
- cl_git_pass(git_path_prettify_dir(&cwd_buf, ".", NULL));
- cl_must_pass(p_chdir(path));
- passfail_(NULL, file, line);
- cl_must_pass(p_chdir(git_buf_cstr(&cwd_buf)));
-}
-#define env_cd_pass(path) env_cd_((path), env_pass_, __FILE__, __LINE__)
-#define env_cd_fail(path) env_cd_((path), env_fail_, __FILE__, __LINE__)
-
-static void env_check_objects_(bool a, bool t, bool p, const char *file, int line)
-{
- git_repository *repo;
- git_oid oid_a, oid_t, oid_p;
- git_object *object;
- cl_git_pass(git_oid_fromstr(&oid_a, "45141a79a77842c59a63229403220a4e4be74e3d"));
- cl_git_pass(git_oid_fromstr(&oid_t, "1385f264afb75a56a5bec74243be9b367ba4ca08"));
- cl_git_pass(git_oid_fromstr(&oid_p, "0df1a5865c8abfc09f1f2182e6a31be550e99f07"));
- cl_git_pass_(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL), file, line);
- if (a) {
- cl_git_pass_(git_object_lookup(&object, repo, &oid_a, GIT_OBJ_BLOB), file, line);
- git_object_free(object);
- } else
- cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_a, GIT_OBJ_BLOB), file, line);
- if (t) {
- cl_git_pass_(git_object_lookup(&object, repo, &oid_t, GIT_OBJ_BLOB), file, line);
- git_object_free(object);
- } else
- cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_t, GIT_OBJ_BLOB), file, line);
- if (p) {
- cl_git_pass_(git_object_lookup(&object, repo, &oid_p, GIT_OBJ_COMMIT), file, line);
- git_object_free(object);
- } else
- cl_git_fail_at_line(git_object_lookup(&object, repo, &oid_p, GIT_OBJ_COMMIT), file, line);
- git_repository_free(repo);
-}
-#define env_check_objects(a, t, t2) env_check_objects_((a), (t), (t2), __FILE__, __LINE__)
-
-void test_repo_open__env(void)
-{
- git_repository *repo = NULL;
- git_buf repo_dir_buf = GIT_BUF_INIT;
- const char *repo_dir = NULL;
- git_index *index = NULL;
- const char *t_obj = "testrepo.git/objects";
- const char *p_obj = "peeled.git/objects";
-
- cl_fixture_sandbox("attr");
- cl_fixture_sandbox("testrepo.git");
- cl_fixture_sandbox("peeled.git");
- cl_git_pass(p_rename("attr/.gitted", "attr/.git"));
-
- cl_git_pass(git_path_prettify_dir(&repo_dir_buf, "attr", NULL));
- repo_dir = git_buf_cstr(&repo_dir_buf);
-
- /* GIT_DIR that doesn't exist */
- cl_setenv("GIT_DIR", "does-not-exist");
- env_fail(NULL);
- /* Explicit start_path overrides GIT_DIR */
- env_pass("attr");
- env_pass("attr/.git");
- env_pass("attr/sub");
- env_pass("attr/sub/sub");
-
- /* GIT_DIR with relative paths */
- cl_setenv("GIT_DIR", "attr/.git");
- env_pass(NULL);
- cl_setenv("GIT_DIR", "attr");
- env_fail(NULL);
- cl_setenv("GIT_DIR", "attr/sub");
- env_fail(NULL);
- cl_setenv("GIT_DIR", "attr/sub/sub");
- env_fail(NULL);
-
- /* GIT_DIR with absolute paths */
- cl_setenv_printf("GIT_DIR", "%s/.git", repo_dir);
- env_pass(NULL);
- cl_setenv("GIT_DIR", repo_dir);
- env_fail(NULL);
- cl_setenv_printf("GIT_DIR", "%s/sub", repo_dir);
- env_fail(NULL);
- cl_setenv_printf("GIT_DIR", "%s/sub/sub", repo_dir);
- env_fail(NULL);
- cl_setenv("GIT_DIR", NULL);
-
- /* Searching from the current directory */
- env_cd_pass("attr");
- env_cd_pass("attr/.git");
- env_cd_pass("attr/sub");
- env_cd_pass("attr/sub/sub");
-
- /* A ceiling directory blocks searches from ascending into that
- * directory, but doesn't block the start_path itself. */
- cl_setenv("GIT_CEILING_DIRECTORIES", repo_dir);
- env_cd_pass("attr");
- env_cd_fail("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s/sub", repo_dir);
- env_cd_pass("attr");
- env_cd_pass("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- /* Multiple ceiling directories */
- cl_setenv_printf("GIT_CEILING_DIRECTORIES", "123%c%s/sub%cabc",
- GIT_PATH_LIST_SEPARATOR, repo_dir, GIT_PATH_LIST_SEPARATOR);
- env_cd_pass("attr");
- env_cd_pass("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s%c%s/sub",
- repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
- env_cd_pass("attr");
- env_cd_fail("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s/sub%c%s",
- repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
- env_cd_pass("attr");
- env_cd_fail("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- cl_setenv_printf("GIT_CEILING_DIRECTORIES", "%s%c%s/sub/sub",
- repo_dir, GIT_PATH_LIST_SEPARATOR, repo_dir);
- env_cd_pass("attr");
- env_cd_fail("attr/sub");
- env_cd_fail("attr/sub/sub");
-
- cl_setenv("GIT_CEILING_DIRECTORIES", NULL);
-
- /* Index files */
- cl_setenv("GIT_INDEX_FILE", cl_fixture("gitgit.index"));
- cl_git_pass(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL));
- cl_git_pass(git_repository_index(&index, repo));
- cl_assert_equal_s(git_index_path(index), cl_fixture("gitgit.index"));
- cl_assert_equal_i(git_index_entrycount(index), 1437);
- git_index_free(index);
- git_repository_free(repo);
- cl_setenv("GIT_INDEX_FILE", NULL);
-
- /* Namespaces */
- cl_setenv("GIT_NAMESPACE", "some-namespace");
- cl_git_pass(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL));
- cl_assert_equal_s(git_repository_get_namespace(repo), "some-namespace");
- git_repository_free(repo);
- cl_setenv("GIT_NAMESPACE", NULL);
-
- /* Object directories and alternates */
- env_check_objects(true, false, false);
-
- cl_setenv("GIT_OBJECT_DIRECTORY", t_obj);
- env_check_objects(false, true, false);
- cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
-
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", t_obj);
- env_check_objects(true, true, false);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
-
- cl_setenv("GIT_OBJECT_DIRECTORY", p_obj);
- env_check_objects(false, false, true);
- cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
-
- cl_setenv("GIT_OBJECT_DIRECTORY", t_obj);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", p_obj);
- env_check_objects(false, true, true);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
- cl_setenv("GIT_OBJECT_DIRECTORY", NULL);
-
- cl_setenv_printf("GIT_ALTERNATE_OBJECT_DIRECTORIES",
- "%s%c%s", t_obj, GIT_PATH_LIST_SEPARATOR, p_obj);
- env_check_objects(true, true, true);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
-
- cl_setenv_printf("GIT_ALTERNATE_OBJECT_DIRECTORIES",
- "%s%c%s", p_obj, GIT_PATH_LIST_SEPARATOR, t_obj);
- env_check_objects(true, true, true);
- cl_setenv("GIT_ALTERNATE_OBJECT_DIRECTORIES", NULL);
-
- cl_fixture_cleanup("peeled.git");
- cl_fixture_cleanup("testrepo.git");
- cl_fixture_cleanup("attr");
-}