Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2019-01-28 13:23:50 +0300
committerGitHub <noreply@github.com>2019-01-28 13:23:50 +0300
commit8d1b36a6d6cd0d0d1657a04634ea5b3301455715 (patch)
tree0701902d616a5457dcd3877c940a5fb3319a70a2
parent313440c394589af4387daa71b31821ed9b7f4462 (diff)
parent703885a813c7e2a6266437814ae88290a39b8f05 (diff)
Merge pull request #4942 from libgit2/ethomson/v0.27.8
Release v0.27.8
-rw-r--r--CHANGELOG.md33
-rw-r--r--include/git2/refs.h2
-rw-r--r--include/git2/version.h4
-rw-r--r--src/annotated_commit.c8
-rw-r--r--src/apply.c3
-rw-r--r--src/attr_file.c5
-rw-r--r--src/commit.c2
-rw-r--r--src/config.c4
-rw-r--r--src/diff_tform.c2
-rw-r--r--src/filter.c6
-rw-r--r--src/ignore.c25
-rw-r--r--src/odb_loose.c14
-rw-r--r--src/patch_parse.c20
-rw-r--r--src/refs.c17
-rw-r--r--src/signature.c2
-rw-r--r--src/submodule.c2
-rw-r--r--src/tree.c29
-rw-r--r--src/util.c50
-rw-r--r--tests/apply/fromfile.c3
-rw-r--r--tests/commit/signature.c20
-rw-r--r--tests/config/read.c20
-rw-r--r--tests/core/strtol.c42
-rw-r--r--tests/merge/annotated_commit.c26
-rw-r--r--tests/status/ignore.c67
24 files changed, 298 insertions, 108 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7e72d343..e935b77ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,36 @@
+v0.27.8
+-------
+
+This is a bugfix release with the following change:
+
+- Negative gitignore rules should match git's behavior. For example,
+ given a gitignore rule of `*.test` and a second gitignore rule of
+ `!dir/*`, we would incorrect apply the negation rules. With this
+ fix, we behave like git.
+
+- Always provide custom transport implementations with the URL in the
+ action function. v0.27.7 included a change that would erroneously
+ provide NULL to subsequent calls to the action function. This is
+ fixed.
+
+- Fix several bugs parsing malformed commits and malformed trees.
+
+- Allow configuration file directory locations to be specified as
+ `/dev/null`.
+
+- Ensure that when an error occurs reading from the loose ODB backend
+ that we do not segfault.
+
+- Ensure that when a filter stream application fails that we do not
+ segfault.
+
+- Ensure that any configuration reading failures are propagated while
+ loading submodule information.
+
+- Peel annotated tags fully when creating an annotated commit.
+
+- Ensure that numbers are parsed correctly in a variety of places.
+
v0.27.7
-------
diff --git a/include/git2/refs.h b/include/git2/refs.h
index 0dd453e55..75afea5c8 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -710,7 +710,7 @@ GIT_EXTERN(int) git_reference_normalize_name(
*/
GIT_EXTERN(int) git_reference_peel(
git_object **out,
- git_reference *ref,
+ const git_reference *ref,
git_otype type);
/**
diff --git a/include/git2/version.h b/include/git2/version.h
index 964e4a58b..d59738084 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -7,10 +7,10 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.27.7"
+#define LIBGIT2_VERSION "0.27.8"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 27
-#define LIBGIT2_VER_REVISION 7
+#define LIBGIT2_VER_REVISION 8
#define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION 27
diff --git a/src/annotated_commit.c b/src/annotated_commit.c
index 72ba80a22..59891b6ab 100644
--- a/src/annotated_commit.c
+++ b/src/annotated_commit.c
@@ -123,19 +123,19 @@ int git_annotated_commit_from_ref(
git_repository *repo,
const git_reference *ref)
{
- git_reference *resolved;
+ git_object *peeled;
int error = 0;
assert(out && repo && ref);
*out = NULL;
- if ((error = git_reference_resolve(&resolved, ref)) < 0)
+ if ((error = git_reference_peel(&peeled, ref, GIT_OBJ_COMMIT)) < 0)
return error;
error = annotated_commit_init_from_id(out,
repo,
- git_reference_target(resolved),
+ git_object_id(peeled),
git_reference_name(ref));
if (!error) {
@@ -143,7 +143,7 @@ int git_annotated_commit_from_ref(
GITERR_CHECK_ALLOC((*out)->ref_name);
}
- git_reference_free(resolved);
+ git_object_free(peeled);
return error;
}
diff --git a/src/apply.c b/src/apply.c
index 7801a0a54..2b3f0793f 100644
--- a/src/apply.c
+++ b/src/apply.c
@@ -312,8 +312,9 @@ static int apply_binary(
&patch->binary.old_file)) < 0)
goto done;
+ /* Verify that the resulting file with the reverse patch applied matches the source file */
if (source_len != reverse.size ||
- memcmp(source, reverse.ptr, source_len) != 0) {
+ (source_len && memcmp(source, reverse.ptr, source_len) != 0)) {
error = apply_err("binary patch did not apply cleanly");
goto done;
}
diff --git a/src/attr_file.c b/src/attr_file.c
index f46cce3de..6821587bc 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -594,8 +594,9 @@ int git_attr_fnmatch__parse(
}
if (*pattern == '!' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWNEG) != 0) {
- spec->flags = spec->flags |
- GIT_ATTR_FNMATCH_NEGATIVE | GIT_ATTR_FNMATCH_LEADINGDIR;
+ spec->flags = spec->flags | GIT_ATTR_FNMATCH_NEGATIVE;
+ if ((spec->flags & GIT_ATTR_FNMATCH_NOLEADINGDIR) == 0)
+ spec->flags |= GIT_ATTR_FNMATCH_LEADINGDIR;
pattern++;
}
diff --git a/src/commit.c b/src/commit.c
index 8972c077d..4fee8c8da 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -419,7 +419,7 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
return -1;
/* Some tools create multiple author fields, ignore the extra ones */
- while ((size_t)(buffer_end - buffer) >= strlen("author ") && !git__prefixcmp(buffer, "author ")) {
+ while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) {
if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0)
return -1;
diff --git a/src/config.c b/src/config.c
index 5d95c2458..ba225297c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -109,7 +109,7 @@ int git_config_add_file_ondisk(
assert(cfg && path);
res = p_stat(path, &st);
- if (res < 0 && errno != ENOENT) {
+ if (res < 0 && errno != ENOENT && errno != ENOTDIR) {
giterr_set(GITERR_CONFIG, "failed to stat '%s'", path);
return -1;
}
@@ -513,6 +513,8 @@ int git_config_backend_foreach_match(
regex_t regex;
int error = 0;
+ assert(backend && cb);
+
if (regexp != NULL) {
if ((error = p_regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
giterr_set_regex(&regex, error);
diff --git a/src/diff_tform.c b/src/diff_tform.c
index a9706e002..686addff4 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -816,6 +816,8 @@ int git_diff_find_similar(
diff_find_match *best_match;
git_diff_file swap;
+ assert(diff);
+
if ((error = normalize_find_opts(diff, &opts, given_opts)) < 0)
return error;
diff --git a/src/filter.c b/src/filter.c
index 6ab09790b..ad741d6af 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -809,6 +809,7 @@ static int proxy_stream_close(git_writestream *s)
{
struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
git_buf *writebuf;
+ git_error_state error_state = {0};
int error;
assert(proxy_stream);
@@ -826,6 +827,11 @@ static int proxy_stream_close(git_writestream *s)
git_buf_sanitize(proxy_stream->output);
writebuf = proxy_stream->output;
} else {
+ /* close stream before erroring out taking care
+ * to preserve the original error */
+ giterr_state_capture(&error_state, error);
+ proxy_stream->target->close(proxy_stream->target);
+ giterr_state_restore(&error_state);
return error;
}
diff --git a/src/ignore.c b/src/ignore.c
index 76b997245..3b68e14a8 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -133,23 +133,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
continue;
}
- /*
- * When dealing with a directory, we add '/<star>' so
- * p_fnmatch() honours FNM_PATHNAME. Checking for LEADINGDIR
- * alone isn't enough as that's also set for nagations, so we
- * need to check that NEGATIVE is off.
- */
git_buf_clear(&buf);
- if (rule->containing_dir) {
+ if (rule->containing_dir)
git_buf_puts(&buf, rule->containing_dir);
- }
-
- error = git_buf_puts(&buf, rule->pattern);
+ git_buf_puts(&buf, rule->pattern);
- if ((rule->flags & (GIT_ATTR_FNMATCH_LEADINGDIR | GIT_ATTR_FNMATCH_NEGATIVE)) == GIT_ATTR_FNMATCH_LEADINGDIR)
- error = git_buf_PUTS(&buf, "/*");
-
- if (error < 0)
+ if (git_buf_oom(&buf))
goto out;
if ((error = p_fnmatch(git_buf_cstr(&buf), path, fnflags)) < 0) {
@@ -203,7 +192,10 @@ static int parse_ignore_file(
break;
}
- match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG;
+ match->flags =
+ GIT_ATTR_FNMATCH_ALLOWSPACE |
+ GIT_ATTR_FNMATCH_ALLOWNEG |
+ GIT_ATTR_FNMATCH_NOLEADINGDIR;
if (!(error = git_attr_fnmatch__parse(
match, &attrs->pool, context, &scan)))
@@ -445,6 +437,9 @@ static bool ignore_lookup_in_rules(
git_attr_fnmatch *match;
git_vector_rforeach(&file->rules, j, match) {
+ if (match->flags & GIT_ATTR_FNMATCH_DIRECTORY &&
+ path->is_dir == GIT_DIR_FLAG_FALSE)
+ continue;
if (git_attr_fnmatch__match(match, path)) {
*ignored = ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0) ?
GIT_IGNORE_TRUE : GIT_IGNORE_FALSE;
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 470421e15..840efbe90 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -1028,11 +1028,15 @@ static int loose_backend__readstream(
done:
if (error < 0) {
- git_futils_mmap_free(&stream->map);
- git_zstream_free(&stream->zstream);
- git_hash_ctx_cleanup(hash_ctx);
- git__free(hash_ctx);
- git__free(stream);
+ if (stream) {
+ git_futils_mmap_free(&stream->map);
+ git_zstream_free(&stream->zstream);
+ git__free(stream);
+ }
+ if (hash_ctx) {
+ git_hash_ctx_cleanup(hash_ctx);
+ git__free(hash_ctx);
+ }
}
git_buf_free(&object_path);
diff --git a/src/patch_parse.c b/src/patch_parse.c
index e02c87cf3..7f6c013b1 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -458,26 +458,6 @@ done:
return error;
}
-static int parse_number(git_off_t *out, git_patch_parse_ctx *ctx)
-{
- const char *end;
- int64_t num;
-
- if (!git__isdigit(ctx->parse_ctx.line[0]))
- return -1;
-
- if (git__strntol64(&num, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 10) < 0)
- return -1;
-
- if (num < 0)
- return -1;
-
- *out = num;
- git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line));
-
- return 0;
-}
-
static int parse_int(int *out, git_patch_parse_ctx *ctx)
{
git_off_t num;
diff --git a/src/refs.c b/src/refs.c
index c42968359..96ad6d8ad 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -709,6 +709,8 @@ int git_reference_rename(
git_signature *who;
int error;
+ assert(out && ref);
+
if ((error = git_reference__log_signature(&who, ref->db->repo)) < 0)
return error;
@@ -1337,7 +1339,7 @@ int git_reference_is_note(const git_reference *ref)
return git_reference__is_note(ref->name);
}
-static int peel_error(int error, git_reference *ref, const char* msg)
+static int peel_error(int error, const git_reference *ref, const char* msg)
{
giterr_set(
GITERR_INVALID,
@@ -1347,10 +1349,11 @@ static int peel_error(int error, git_reference *ref, const char* msg)
int git_reference_peel(
git_object **peeled,
- git_reference *ref,
+ const git_reference *ref,
git_otype target_type)
{
- git_reference *resolved = NULL;
+ const git_reference *resolved = NULL;
+ git_reference *allocated = NULL;
git_object *target = NULL;
int error;
@@ -1359,8 +1362,10 @@ int git_reference_peel(
if (ref->type == GIT_REF_OID) {
resolved = ref;
} else {
- if ((error = git_reference_resolve(&resolved, ref)) < 0)
+ if ((error = git_reference_resolve(&allocated, ref)) < 0)
return peel_error(error, ref, "Cannot resolve reference");
+
+ resolved = allocated;
}
/*
@@ -1389,9 +1394,7 @@ int git_reference_peel(
cleanup:
git_object_free(target);
-
- if (resolved != ref)
- git_reference_free(resolved);
+ git_reference_free(allocated);
return error;
}
diff --git a/src/signature.c b/src/signature.c
index 91864bb88..11416d786 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -248,7 +248,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
if ((tz_start[0] != '-' && tz_start[0] != '+') ||
git__strntol32(&offset, tz_start + 1,
- buffer_end - tz_start + 1, &tz_end, 10) < 0) {
+ buffer_end - tz_start - 1, &tz_end, 10) < 0) {
/* malformed timezone, just assume it's zero */
offset = 0;
}
diff --git a/src/submodule.c b/src/submodule.c
index 06b7de585..2bfc46880 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -181,7 +181,7 @@ static int load_submodule_names(git_strmap *out, git_repository *repo, git_confi
if ((error = git_config_iterator_glob_new(&iter, cfg, key)) < 0)
return error;
- while (git_config_next(&entry, iter) == 0) {
+ while ((error = git_config_next(&entry, iter)) == 0) {
const char *fdot, *ldot;
fdot = strchr(entry->name, '.');
ldot = strrchr(entry->name, '.');
diff --git a/src/tree.c b/src/tree.c
index a014ce807..d1c1d7769 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -399,21 +399,21 @@ static int tree_error(const char *str, const char *path)
return -1;
}
-static int parse_mode(unsigned int *modep, const char *buffer, const char **buffer_out)
+static int parse_mode(uint16_t *mode_out, const char *buffer, size_t buffer_len, const char **buffer_out)
{
- unsigned char c;
- unsigned int mode = 0;
+ int32_t mode;
+ int error;
- if (*buffer == ' ')
+ if (!buffer_len || git__isspace(*buffer))
return -1;
- while ((c = *buffer++) != ' ') {
- if (c < '0' || c > '7')
- return -1;
- mode = (mode << 3) + (c - '0');
- }
- *modep = mode;
- *buffer_out = buffer;
+ if ((error = git__strntol32(&mode, buffer, buffer_len, buffer_out, 8)) < 0)
+ return error;
+
+ if (mode < 0 || mode > UINT16_MAX)
+ return -1;
+
+ *mode_out = mode;
return 0;
}
@@ -437,11 +437,14 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
git_tree_entry *entry;
size_t filename_len;
const char *nul;
- unsigned int attr;
+ uint16_t attr;
- if (parse_mode(&attr, buffer, &buffer) < 0 || !buffer)
+ if (parse_mode(&attr, buffer, buffer_end - buffer, &buffer) < 0 || !buffer)
return tree_error("failed to parse tree: can't parse filemode", NULL);
+ if (buffer >= buffer_end || (*buffer++) != ' ')
+ return tree_error("failed to parse tree: missing space after filemode", NULL);
+
if ((nul = memchr(buffer, 0, buffer_end - buffer)) == NULL)
return tree_error("failed to parse tree: object is corrupted", NULL);
diff --git a/src/util.c b/src/util.c
index 911921857..a81557bac 100644
--- a/src/util.c
+++ b/src/util.c
@@ -83,36 +83,56 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
/*
* White space
*/
- while (git__isspace(*p))
- p++;
+ while (nptr_len && git__isspace(*p))
+ p++, nptr_len--;
+
+ if (!nptr_len)
+ goto Return;
/*
* Sign
*/
- if (*p == '-' || *p == '+')
- if (*p++ == '-')
+ if (*p == '-' || *p == '+') {
+ if (*p == '-')
neg = 1;
+ p++;
+ nptr_len--;
+ }
+
+ if (!nptr_len)
+ goto Return;
/*
- * Base
+ * Automatically detect the base if none was given to us.
+ * Right now, we assume that a number starting with '0x'
+ * is hexadecimal and a number starting with '0' is
+ * octal.
*/
if (base == 0) {
if (*p != '0')
base = 10;
- else {
+ else if (nptr_len > 2 && (p[1] == 'x' || p[1] == 'X'))
+ base = 16;
+ else
base = 8;
- if (p[1] == 'x' || p[1] == 'X') {
- p += 2;
- base = 16;
- }
- }
- } else if (base == 16 && *p == '0') {
- if (p[1] == 'x' || p[1] == 'X')
- p += 2;
- } else if (base < 0 || 36 < base)
+ }
+
+ if (base < 0 || 36 < base)
goto Return;
/*
+ * Skip prefix of '0x'-prefixed hexadecimal numbers. There is no
+ * need to do the same for '0'-prefixed octal numbers as a
+ * leading '0' does not have any impact. Also, if we skip a
+ * leading '0' in such a string, then we may end up with no
+ * digits left and produce an error later on which isn't one.
+ */
+ if (base == 16 && nptr_len > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ p += 2;
+ nptr_len -= 2;
+ }
+
+ /*
* Non-empty sequence of digits
*/
for (; nptr_len > 0; p++,ndig++,nptr_len--) {
diff --git a/tests/apply/fromfile.c b/tests/apply/fromfile.c
index 31fffa1a2..211f6dcbb 100644
--- a/tests/apply/fromfile.c
+++ b/tests/apply/fromfile.c
@@ -43,7 +43,8 @@ static int apply_patchfile(
if (error == 0) {
cl_assert_equal_i(new_len, result.size);
- cl_assert(memcmp(new, result.ptr, new_len) == 0);
+ if (new_len)
+ cl_assert(memcmp(new, result.ptr, new_len) == 0);
cl_assert_equal_s(filename_expected, filename);
cl_assert_equal_i(mode_expected, mode);
diff --git a/tests/commit/signature.c b/tests/commit/signature.c
index 286079fa2..d8edbaaa9 100644
--- a/tests/commit/signature.c
+++ b/tests/commit/signature.c
@@ -43,6 +43,26 @@ void test_commit_signature__leading_and_trailing_crud_is_trimmed(void)
assert_name_and_email("nulltoken \xe2\x98\xba", "emeric.fermas@gmail.com", "nulltoken \xe2\x98\xba", "emeric.fermas@gmail.com");
}
+void test_commit_signature__timezone_does_not_read_oob(void)
+{
+ const char *header = "A <a@example.com> 1461698487 +1234", *header_end;
+ git_signature *sig;
+
+ /* Let the buffer end midway between the timezone offeset's "+12" and "34" */
+ header_end = header + strlen(header) - 2;
+
+ sig = git__calloc(1, sizeof(git_signature));
+ cl_assert(sig);
+
+ cl_git_pass(git_signature__parse(sig, &header, header_end, NULL, '\0'));
+ cl_assert_equal_s(sig->name, "A");
+ cl_assert_equal_s(sig->email, "a@example.com");
+ cl_assert_equal_i(sig->when.time, 1461698487);
+ cl_assert_equal_i(sig->when.offset, 12);
+
+ git_signature_free(sig);
+}
+
void test_commit_signature__angle_brackets_in_names_are_not_supported(void)
{
cl_git_fail(try_build_signature("<Phil Haack", "phil@haack", 1234567890, 60));
diff --git a/tests/config/read.c b/tests/config/read.c
index 646567134..df745a567 100644
--- a/tests/config/read.c
+++ b/tests/config/read.c
@@ -524,6 +524,26 @@ void test_config_read__fallback_from_local_to_global_and_from_global_to_system(v
git_config_free(cfg);
}
+void test_config_read__parent_dir_is_file(void)
+{
+ git_config *cfg;
+ int count;
+
+ cl_git_pass(git_config_new(&cfg));
+ /*
+ * Verify we can add non-existing files when the parent directory is not
+ * a directory.
+ */
+ cl_git_pass(git_config_add_file_ondisk(cfg, "/dev/null/.gitconfig",
+ GIT_CONFIG_LEVEL_SYSTEM, NULL, 0));
+
+ count = 0;
+ cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
+ cl_assert_equal_i(0, count);
+
+ git_config_free(cfg);
+}
+
/*
* At the beginning of the test, config18 has:
* int32global = 28
diff --git a/tests/core/strtol.c b/tests/core/strtol.c
index ba79fba51..6f4e63af3 100644
--- a/tests/core/strtol.c
+++ b/tests/core/strtol.c
@@ -64,6 +64,28 @@ void test_core_strtol__int64(void)
assert_l64_fails("-0x8000000000000001", 16);
}
+void test_core_strtol__base_autodetection(void)
+{
+ assert_l64_parses("0", 0, 0);
+ assert_l64_parses("00", 0, 0);
+ assert_l64_parses("0x", 0, 0);
+ assert_l64_parses("0foobar", 0, 0);
+ assert_l64_parses("07", 7, 0);
+ assert_l64_parses("017", 15, 0);
+ assert_l64_parses("0x8", 8, 0);
+ assert_l64_parses("0x18", 24, 0);
+}
+
+void test_core_strtol__buffer_length_with_autodetection_truncates(void)
+{
+ int64_t i64;
+
+ cl_git_pass(git__strntol64(&i64, "011", 2, NULL, 0));
+ cl_assert_equal_i(i64, 1);
+ cl_git_pass(git__strntol64(&i64, "0x11", 3, NULL, 0));
+ cl_assert_equal_i(i64, 1);
+}
+
void test_core_strtol__buffer_length_truncates(void)
{
int32_t i32;
@@ -76,6 +98,26 @@ void test_core_strtol__buffer_length_truncates(void)
cl_assert_equal_i(i64, 1);
}
+void test_core_strtol__buffer_length_with_leading_ws_truncates(void)
+{
+ int64_t i64;
+
+ cl_git_fail(git__strntol64(&i64, " 1", 1, NULL, 10));
+
+ cl_git_pass(git__strntol64(&i64, " 11", 2, NULL, 10));
+ cl_assert_equal_i(i64, 1);
+}
+
+void test_core_strtol__buffer_length_with_leading_sign_truncates(void)
+{
+ int64_t i64;
+
+ cl_git_fail(git__strntol64(&i64, "-1", 1, NULL, 10));
+
+ cl_git_pass(git__strntol64(&i64, "-11", 2, NULL, 10));
+ cl_assert_equal_i(i64, -1);
+}
+
void test_core_strtol__error_message_cuts_off(void)
{
assert_l32_fails("2147483657foobar", 10);
diff --git a/tests/merge/annotated_commit.c b/tests/merge/annotated_commit.c
new file mode 100644
index 000000000..cfdf849e5
--- /dev/null
+++ b/tests/merge/annotated_commit.c
@@ -0,0 +1,26 @@
+#include "clar_libgit2.h"
+
+
+static git_repository *g_repo;
+
+void test_merge_annotated_commit__initialize(void)
+{
+ g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_merge_annotated_commit__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_merge_annotated_commit__lookup_annotated_tag(void)
+{
+ git_annotated_commit *commit;
+ git_reference *ref;
+
+ cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/tags/test"));
+ cl_git_pass(git_annotated_commit_from_ref(&commit, g_repo, ref));
+
+ git_annotated_commit_free(commit);
+ git_reference_free(ref);
+}
diff --git a/tests/status/ignore.c b/tests/status/ignore.c
index dc58e8b45..824475e8c 100644
--- a/tests/status/ignore.c
+++ b/tests/status/ignore.c
@@ -1158,27 +1158,58 @@ void test_status_ignore__subdir_ignore_everything_except_certain_files(void)
void test_status_ignore__deeper(void)
{
- int ignored;
+ const char *test_files[] = {
+ "empty_standard_repo/foo.data",
+ "empty_standard_repo/bar.data",
+ "empty_standard_repo/dont_ignore/foo.data",
+ "empty_standard_repo/dont_ignore/bar.data",
+ NULL
+ };
- g_repo = cl_git_sandbox_init("empty_standard_repo");
+ make_test_data("empty_standard_repo", test_files);
+ cl_git_mkfile("empty_standard_repo/.gitignore",
+ "*.data\n"
+ "!dont_ignore/*.data\n");
- cl_git_mkfile("empty_standard_repo/.gitignore",
- "*.data\n"
- "!dont_ignore/*.data\n");
+ assert_is_ignored("foo.data");
+ assert_is_ignored("bar.data");
- cl_git_pass(p_mkdir("empty_standard_repo/dont_ignore", 0777));
- cl_git_mkfile("empty_standard_repo/foo.data", "");
- cl_git_mkfile("empty_standard_repo/bar.data", "");
- cl_git_mkfile("empty_standard_repo/dont_ignore/foo.data", "");
- cl_git_mkfile("empty_standard_repo/dont_ignore/bar.data", "");
+ refute_is_ignored("dont_ignore/foo.data");
+ refute_is_ignored("dont_ignore/bar.data");
+}
- cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "foo.data"));
- cl_assert_equal_i(1, ignored);
- cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "bar.data"));
- cl_assert_equal_i(1, ignored);
+void test_status_ignore__unignored_dir_with_ignored_contents(void)
+{
+ static const char *test_files[] = {
+ "empty_standard_repo/dir/a.test",
+ "empty_standard_repo/dir/subdir/a.test",
+ NULL
+ };
- cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "dont_ignore/foo.data"));
- cl_assert_equal_i(0, ignored);
- cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "dont_ignore/bar.data"));
- cl_assert_equal_i(0, ignored);
+ make_test_data("empty_standard_repo", test_files);
+ cl_git_mkfile(
+ "empty_standard_repo/.gitignore",
+ "*.test\n"
+ "!dir/*\n");
+
+ refute_is_ignored("dir/a.test");
+ assert_is_ignored("dir/subdir/a.test");
+}
+
+void test_status_ignore__unignored_subdirs(void)
+{
+ static const char *test_files[] = {
+ "empty_standard_repo/dir/a.test",
+ "empty_standard_repo/dir/subdir/a.test",
+ NULL
+ };
+
+ make_test_data("empty_standard_repo", test_files);
+ cl_git_mkfile(
+ "empty_standard_repo/.gitignore",
+ "dir/*\n"
+ "!dir/*/\n");
+
+ assert_is_ignored("dir/a.test");
+ refute_is_ignored("dir/subdir/a.test");
}