summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBrian Lopez <seniorlopez@gmail.com>2018-01-02 13:29:49 -0800
committerBrian Lopez <seniorlopez@gmail.com>2018-01-02 13:29:49 -0800
commite8bc855834e188dd87515ef232758a70357f4c85 (patch)
tree5ed7b6d899a644b5c46d8ab90c0758a55900e9f9 /tests
parent72fbf05ceb088e6592b44d7656ed2bca14506696 (diff)
parent7610638ec829ffd6da6d5f74b5b14dbb32b74924 (diff)
downloadlibgit2-e8bc855834e188dd87515ef232758a70357f4c85.tar.gz
Merge remote-tracking branch 'origin/master' into charliesome/trailer-info
Diffstat (limited to 'tests')
-rw-r--r--tests/core/string.c42
-rw-r--r--tests/diff/blob.c39
-rw-r--r--tests/fetchhead/nonetwork.c88
-rw-r--r--tests/merge/workdir/submodules.c36
-rw-r--r--tests/notes/notes.c274
-rw-r--r--tests/odb/largefiles.c114
-rw-r--r--tests/pack/indexer.c68
-rw-r--r--tests/patch/parse.c6
-rw-r--r--tests/patch/patch_common.h10
-rw-r--r--tests/refs/iterator.c84
-rw-r--r--tests/resources/merge-resolve/.gitted/objects/50/c5dc8cdfe40c688eb0a0e23be54dd57cae2e782
-rw-r--r--tests/resources/merge-resolve/.gitted/objects/7a/a825857f87aea74ddf13d954568aa30dfcdeb4bin0 -> 117 bytes
-rw-r--r--tests/resources/merge-resolve/.gitted/refs/heads/delete-submodule1
13 files changed, 738 insertions, 26 deletions
diff --git a/tests/core/string.c b/tests/core/string.c
index 90e8fa027..85db0c662 100644
--- a/tests/core/string.c
+++ b/tests/core/string.c
@@ -40,6 +40,48 @@ void test_core_string__2(void)
cl_assert(git__strcasesort_cmp("fooBar", "foobar") < 0);
}
+/* compare prefixes with len */
+void test_core_string__prefixncmp(void)
+{
+ cl_assert(git__prefixncmp("", 0, "") == 0);
+ cl_assert(git__prefixncmp("a", 1, "") == 0);
+ cl_assert(git__prefixncmp("", 0, "a") < 0);
+ cl_assert(git__prefixncmp("a", 1, "b") < 0);
+ cl_assert(git__prefixncmp("b", 1, "a") > 0);
+ cl_assert(git__prefixncmp("ab", 2, "a") == 0);
+ cl_assert(git__prefixncmp("ab", 1, "a") == 0);
+ cl_assert(git__prefixncmp("ab", 2, "ac") < 0);
+ cl_assert(git__prefixncmp("a", 1, "ac") < 0);
+ cl_assert(git__prefixncmp("ab", 1, "ac") < 0);
+ cl_assert(git__prefixncmp("ab", 2, "aa") > 0);
+ cl_assert(git__prefixncmp("ab", 1, "aa") < 0);
+}
+
+/* compare prefixes with len */
+void test_core_string__prefixncmp_icase(void)
+{
+ cl_assert(git__prefixncmp_icase("", 0, "") == 0);
+ cl_assert(git__prefixncmp_icase("a", 1, "") == 0);
+ cl_assert(git__prefixncmp_icase("", 0, "a") < 0);
+ cl_assert(git__prefixncmp_icase("a", 1, "b") < 0);
+ cl_assert(git__prefixncmp_icase("A", 1, "b") < 0);
+ cl_assert(git__prefixncmp_icase("a", 1, "B") < 0);
+ cl_assert(git__prefixncmp_icase("b", 1, "a") > 0);
+ cl_assert(git__prefixncmp_icase("B", 1, "a") > 0);
+ cl_assert(git__prefixncmp_icase("b", 1, "A") > 0);
+ cl_assert(git__prefixncmp_icase("ab", 2, "a") == 0);
+ cl_assert(git__prefixncmp_icase("Ab", 2, "a") == 0);
+ cl_assert(git__prefixncmp_icase("ab", 2, "A") == 0);
+ cl_assert(git__prefixncmp_icase("ab", 1, "a") == 0);
+ cl_assert(git__prefixncmp_icase("ab", 2, "ac") < 0);
+ cl_assert(git__prefixncmp_icase("Ab", 2, "ac") < 0);
+ cl_assert(git__prefixncmp_icase("ab", 2, "Ac") < 0);
+ cl_assert(git__prefixncmp_icase("a", 1, "ac") < 0);
+ cl_assert(git__prefixncmp_icase("ab", 1, "ac") < 0);
+ cl_assert(git__prefixncmp_icase("ab", 2, "aa") > 0);
+ cl_assert(git__prefixncmp_icase("ab", 1, "aa") < 0);
+}
+
void test_core_string__strcmp(void)
{
cl_assert(git__strcmp("", "") == 0);
diff --git a/tests/diff/blob.c b/tests/diff/blob.c
index c3933c313..05cc28218 100644
--- a/tests/diff/blob.c
+++ b/tests/diff/blob.c
@@ -1,6 +1,19 @@
#include "clar_libgit2.h"
#include "diff_helpers.h"
+#define BLOB_DIFF \
+ "diff --git a/file b/file\n" \
+ "index 45141a7..4d713dc 100644\n" \
+ "--- a/file\n" \
+ "+++ b/file\n" \
+ "@@ -1 +1,6 @@\n" \
+ " Hello from the root\n" \
+ "+\n" \
+ "+Some additional lines\n" \
+ "+\n" \
+ "+Down here below\n" \
+ "+\n"
+
static git_repository *g_repo = NULL;
static diff_expects expected;
static git_diff_options opts;
@@ -65,6 +78,32 @@ static void assert_one_modified(
cl_assert_equal_i(dels, exp->line_dels);
}
+void test_diff_blob__patch_with_freed_blobs(void)
+{
+ git_oid a_oid, b_oid;
+ git_blob *a, *b;
+ git_patch *p;
+ git_buf buf = GIT_BUF_INIT;
+
+ /* tests/resources/attr/root_test1 */
+ cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
+ cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4));
+ /* tests/resources/attr/root_test2 */
+ cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
+ cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4));
+
+ cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, NULL));
+
+ git_blob_free(a);
+ git_blob_free(b);
+
+ cl_git_pass(git_patch_to_buf(&buf, p));
+ cl_assert_equal_s(buf.ptr, BLOB_DIFF);
+
+ git_patch_free(p);
+ git_buf_free(&buf);
+}
+
void test_diff_blob__can_compare_text_blobs(void)
{
git_blob *a, *b, *c;
diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c
index ea4b70e4a..4dabb577e 100644
--- a/tests/fetchhead/nonetwork.c
+++ b/tests/fetchhead/nonetwork.c
@@ -353,20 +353,25 @@ void test_fetchhead_nonetwork__quote_in_branch_name(void)
}
static bool found_master;
-static bool find_master_called;
+static bool found_haacked;
+static bool find_master_haacked_called;
-int find_master(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
+int find_master_haacked(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
{
GIT_UNUSED(remote_url);
GIT_UNUSED(oid);
GIT_UNUSED(payload);
- find_master_called = true;
+ find_master_haacked_called = true;
if (!strcmp("refs/heads/master", ref_name)) {
cl_assert(is_merge);
found_master = true;
}
+ if (!strcmp("refs/heads/haacked", ref_name)) {
+ cl_assert(is_merge);
+ found_haacked = true;
+ }
return 0;
}
@@ -375,10 +380,12 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void)
{
git_remote *remote;
git_buf path = GIT_BUF_INIT;
- char *refspec = "refs/heads/master";
+ char *refspec1 = "refs/heads/master";
+ char *refspec2 = "refs/heads/haacked";
+ char *refspecs[] = { refspec1, refspec2 };
git_strarray specs = {
- &refspec,
- 1,
+ refspecs,
+ 2,
};
cl_set_cleanup(&cleanup_repository, "./test1");
@@ -391,9 +398,74 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void)
cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL));
cl_assert(git_path_exists(path.ptr));
- cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master, NULL));
- cl_assert(find_master_called);
+ cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master_haacked, NULL));
+ cl_assert(find_master_haacked_called);
cl_assert(found_master);
+ cl_assert(found_haacked);
+
+ git_remote_free(remote);
+ git_buf_free(&path);
+}
+
+static bool count_refs_called;
+struct prefix_count {
+ const char *prefix;
+ int count;
+ int expected;
+};
+
+int count_refs(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
+{
+ int i;
+ struct prefix_count *prefix_counts = (struct prefix_count *) payload;
+
+ GIT_UNUSED(remote_url);
+ GIT_UNUSED(oid);
+ GIT_UNUSED(is_merge);
+
+ count_refs_called = true;
+
+ for (i = 0; prefix_counts[i].prefix; i++) {
+ if (!git__prefixcmp(ref_name, prefix_counts[i].prefix))
+ prefix_counts[i].count++;
+ }
+
+ return 0;
+}
+
+void test_fetchhead_nonetwork__create_with_multiple_refspecs(void)
+{
+ git_remote *remote;
+ git_buf path = GIT_BUF_INIT;
+
+ cl_set_cleanup(&cleanup_repository, "./test1");
+ cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+ cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git")));
+ git_remote_free(remote);
+ cl_git_pass(git_remote_add_fetch(g_repo, "origin", "+refs/notes/*:refs/origin/notes/*"));
+ /* Pick up the new refspec */
+ cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
+
+ cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD"));
+ cl_assert(!git_path_exists(path.ptr));
+ cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+ cl_assert(git_path_exists(path.ptr));
+
+ {
+ int i;
+ struct prefix_count prefix_counts[] = {
+ {"refs/notes/", 0, 1},
+ {"refs/heads/", 0, 12},
+ {"refs/tags/", 0, 7},
+ {NULL, 0, 0},
+ };
+
+ cl_git_pass(git_repository_fetchhead_foreach(g_repo, count_refs, &prefix_counts));
+ cl_assert(count_refs_called);
+ for (i = 0; prefix_counts[i].prefix; i++)
+ cl_assert_equal_i(prefix_counts[i].expected, prefix_counts[i].count);
+ }
git_remote_free(remote);
git_buf_free(&path);
diff --git a/tests/merge/workdir/submodules.c b/tests/merge/workdir/submodules.c
index 7c18c2ffb..c4cc188a8 100644
--- a/tests/merge/workdir/submodules.c
+++ b/tests/merge/workdir/submodules.c
@@ -12,6 +12,7 @@ static git_repository *repo;
#define SUBMODULE_MAIN_BRANCH "submodules"
#define SUBMODULE_OTHER_BRANCH "submodules-branch"
#define SUBMODULE_OTHER2_BRANCH "submodules-branch2"
+#define SUBMODULE_DELETE_BRANCH "delete-submodule"
#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
@@ -93,3 +94,38 @@ void test_merge_workdir_submodules__take_changed(void)
git_reference_free(their_ref);
git_reference_free(our_ref);
}
+
+
+void test_merge_workdir_submodules__update_delete_conflict(void)
+{
+ git_reference *our_ref, *their_ref;
+ git_commit *our_commit;
+ git_annotated_commit *their_head;
+ git_index *index;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", 0, ".gitmodules" },
+ { 0100644, "5887a5e516c53bd58efb0f02ec6aa031b6fe9ad7", 0, "file1.txt" },
+ { 0100644, "4218670ab81cc219a9f94befb5c5dad90ec52648", 0, "file2.txt" },
+ { 0160000, "d3d806a4bef96889117fd7ebac0e3cb5ec152932", 1, "submodule"},
+ { 0160000, "297aa6cd028b3336c7802c7a6f49143da4e1602d", 3, "submodule" },
+ };
+
+ cl_git_pass(git_reference_lookup(&our_ref, repo, "refs/heads/" SUBMODULE_DELETE_BRANCH));
+ cl_git_pass(git_commit_lookup(&our_commit, repo, git_reference_target(our_ref)));
+ cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD, NULL));
+
+ cl_git_pass(git_reference_lookup(&their_ref, repo, "refs/heads/" SUBMODULE_MAIN_BRANCH));
+ cl_git_pass(git_annotated_commit_from_ref(&their_head, repo, their_ref));
+
+ cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, 1, NULL, NULL));
+
+ cl_git_pass(git_repository_index(&index, repo));
+ cl_assert(merge_test_index(index, merge_index_entries, 5));
+
+ git_index_free(index);
+ git_annotated_commit_free(their_head);
+ git_commit_free(our_commit);
+ git_reference_free(their_ref);
+ git_reference_free(our_ref);
+}
diff --git a/tests/notes/notes.c b/tests/notes/notes.c
index a91bf5bdf..9626f53b3 100644
--- a/tests/notes/notes.c
+++ b/tests/notes/notes.c
@@ -73,6 +73,128 @@ static int note_list_cb(
return 0;
}
+struct note_create_payload {
+ const char *note_oid;
+ const char *object_oid;
+ unsigned seen;
+};
+
+static int note_list_create_cb(
+ const git_oid *blob_oid, const git_oid *annotated_obj_id, void *payload)
+{
+ git_oid expected_note_oid, expected_target_oid;
+ struct note_create_payload *notes = payload;
+ size_t i;
+
+ for (i = 0; notes[i].note_oid != NULL; i++) {
+ cl_git_pass(git_oid_fromstr(&expected_note_oid, notes[i].note_oid));
+
+ if (git_oid_cmp(&expected_note_oid, blob_oid) != 0)
+ continue;
+
+ cl_git_pass(git_oid_fromstr(&expected_target_oid, notes[i].object_oid));
+
+ if (git_oid_cmp(&expected_target_oid, annotated_obj_id) != 0)
+ continue;
+
+ notes[i].seen = 1;
+ return 0;
+ }
+
+ cl_fail("Did not see expected note");
+ return 0;
+}
+
+void assert_notes_seen(struct note_create_payload payload[], size_t n)
+{
+ size_t seen = 0, i;
+
+ for (i = 0; payload[i].note_oid != NULL; i++) {
+ if (payload[i].seen)
+ seen++;
+ }
+
+ cl_assert_equal_i(seen, n);
+}
+
+void test_notes_notes__can_create_a_note(void)
+{
+ git_oid note_oid;
+ static struct note_create_payload can_create_a_note[] = {
+ { "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
+ { NULL, NULL, 0 }
+ };
+
+ create_note(&note_oid, "refs/notes/i-can-see-dead-notes", can_create_a_note[0].object_oid, "I decorate 4a20\n");
+
+ cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note));
+
+ assert_notes_seen(can_create_a_note, 1);
+}
+
+void test_notes_notes__can_create_a_note_from_commit(void)
+{
+ git_oid oid;
+ git_oid notes_commit_out;
+ git_reference *ref;
+ static struct note_create_payload can_create_a_note_from_commit[] = {
+ { "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
+ { NULL, NULL, 0 }
+ };
+
+ cl_git_pass(git_oid_fromstr(&oid, can_create_a_note_from_commit[0].object_oid));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1));
+
+ /* create_from_commit will not update any ref,
+ * so we must manually create the ref, that points to the commit */
+ cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_out, 0, NULL));
+
+ cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note_from_commit));
+
+ assert_notes_seen(can_create_a_note_from_commit, 1);
+
+ git_reference_free(ref);
+}
+
+
+/* Test that we can create a note from a commit, given an existing commit */
+void test_notes_notes__can_create_a_note_from_commit_given_an_existing_commit(void)
+{
+ git_oid oid;
+ git_oid notes_commit_out;
+ git_commit *existing_notes_commit = NULL;
+ git_reference *ref;
+ static struct note_create_payload can_create_a_note_from_commit_given_an_existing_commit[] = {
+ { "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
+ { "1aaf94147c21f981e0a20bf57b89137c5a6aae52", "9fd738e8f7967c078dceed8190330fc8648ee56a", 0 },
+ { NULL, NULL, 0 }
+ };
+
+ cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
+
+ cl_git_pass(git_oid_fromstr(&oid, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+
+ git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_out);
+
+ cl_assert(existing_notes_commit);
+
+ cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, existing_notes_commit, _sig, _sig, &oid, "I decorate 9fd7\n", 0));
+
+ /* create_from_commit will not update any ref,
+ * so we must manually create the ref, that points to the commit */
+ cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_out, 0, NULL));
+
+ cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note_from_commit_given_an_existing_commit));
+
+ assert_notes_seen(can_create_a_note_from_commit_given_an_existing_commit, 2);
+
+ git_commit_free(existing_notes_commit);
+ git_reference_free(ref);
+}
+
/*
* $ git notes --ref i-can-see-dead-notes add -m "I decorate a65f" a65fedf39aefe402d3bb6e24df4d4f5fe4547750
* $ git notes --ref i-can-see-dead-notes add -m "I decorate c478" c47800c7266a2be04c571c04d5a6614691ea99bd
@@ -253,6 +375,71 @@ static char *messages[] = {
#define MESSAGES_COUNT (sizeof(messages)/sizeof(messages[0])) - 1
+/* Test that we can read a note */
+void test_notes_notes__can_read_a_note(void)
+{
+ git_oid note_oid, target_oid;
+ git_note *note;
+
+ create_note(&note_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n");
+
+ cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+ cl_git_pass(git_note_read(&note, _repo, "refs/notes/i-can-see-dead-notes", &target_oid));
+
+ cl_assert_equal_s(git_note_message(note), "I decorate 4a20\n");
+
+ git_note_free(note);
+}
+
+/* Test that we can read a note with from commit api */
+void test_notes_notes__can_read_a_note_from_a_commit(void)
+{
+ git_oid oid, notes_commit_oid;
+ git_commit *notes_commit;
+ git_note *note;
+
+ cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1));
+
+ git_commit_lookup(&notes_commit, _repo, &notes_commit_oid);
+
+ cl_assert(notes_commit);
+
+ cl_git_pass(git_note_commit_read(&note, _repo, notes_commit, &oid));
+
+ cl_assert_equal_s(git_note_message(note), "I decorate 4a20\n");
+
+ git_commit_free(notes_commit);
+ git_note_free(note);
+}
+
+/* Test that we can read a commit with no note fails */
+void test_notes_notes__attempt_to_read_a_note_from_a_commit_with_no_note_fails(void)
+{
+ git_oid oid, notes_commit_oid;
+ git_commit *notes_commit;
+ git_note *note;
+
+ cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1));
+
+ git_commit_lookup(&notes_commit, _repo, &notes_commit_oid);
+
+ cl_git_pass(git_note_commit_remove(&notes_commit_oid, _repo, notes_commit, _sig, _sig, &oid));
+ git_commit_free(notes_commit);
+
+ git_commit_lookup(&notes_commit, _repo, &notes_commit_oid);
+
+ cl_assert(notes_commit);
+
+ cl_git_fail_with(GIT_ENOTFOUND, git_note_commit_read(&note, _repo, notes_commit, &oid));
+
+ git_commit_free(notes_commit);
+}
+
/*
* $ git ls-tree refs/notes/fanout
* 040000 tree 4b22b35d44b5a4f589edf3dc89196399771796ea 84
@@ -298,6 +485,50 @@ void test_notes_notes__can_read_a_note_in_an_existing_fanout(void)
git_note_free(note);
}
+/* Can remove a note */
+void test_notes_notes__can_remove_a_note(void)
+{
+ git_oid note_oid, target_oid;
+ git_note *note;
+
+ create_note(&note_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n");
+
+ cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+ cl_git_pass(git_note_remove(_repo, "refs/notes/i-can-see-dead-notes", _sig, _sig, &target_oid));
+
+ cl_git_fail(git_note_read(&note, _repo, "refs/notes/i-can-see-dead-notes", &target_oid));
+}
+
+/* Can remove a note from a commit */
+void test_notes_notes__can_remove_a_note_from_commit(void)
+{
+ git_oid oid, notes_commit_oid;
+ git_note *note = NULL;
+ git_commit *existing_notes_commit;
+ git_reference *ref;
+
+ cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
+
+ git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_oid);
+
+ cl_assert(existing_notes_commit);
+
+ cl_git_pass(git_note_commit_remove(&notes_commit_oid, _repo, existing_notes_commit, _sig, _sig, &oid));
+
+ /* remove_from_commit will not update any ref,
+ * so we must manually create the ref, that points to the commit */
+ cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_oid, 0, NULL));
+
+ cl_git_fail(git_note_read(&note, _repo, "refs/notes/i-can-see-dead-notes", &oid));
+
+ git_commit_free(existing_notes_commit);
+ git_reference_free(ref);
+ git_note_free(note);
+}
+
+
void test_notes_notes__can_remove_a_note_in_an_existing_fanout(void)
{
git_oid target_oid;
@@ -388,3 +619,46 @@ void test_notes_notes__empty_iterate(void)
cl_git_fail(git_note_iterator_new(&iter, _repo, "refs/notes/commits"));
}
+
+void test_notes_notes__iterate_from_commit(void)
+{
+ git_note_iterator *iter;
+ git_note *note;
+ git_oid note_id, annotated_id;
+ git_oid oids[2];
+ git_oid notes_commit_oids[2];
+ git_commit *notes_commits[2];
+ const char* note_message[] = {
+ "I decorate a65f\n",
+ "I decorate c478\n"
+ };
+ int i, err;
+
+ cl_git_pass(git_oid_fromstr(&(oids[0]), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+ cl_git_pass(git_oid_fromstr(&(oids[1]), "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+
+ cl_git_pass(git_note_commit_create(&notes_commit_oids[0], NULL, _repo, NULL, _sig, _sig, &(oids[0]), note_message[0], 0));
+
+ git_commit_lookup(&notes_commits[0], _repo, &notes_commit_oids[0]);
+ cl_assert(notes_commits[0]);
+
+ cl_git_pass(git_note_commit_create(&notes_commit_oids[1], NULL, _repo, notes_commits[0], _sig, _sig, &(oids[1]), note_message[1], 0));
+
+ git_commit_lookup(&notes_commits[1], _repo, &notes_commit_oids[1]);
+ cl_assert(notes_commits[1]);
+
+ cl_git_pass(git_note_commit_iterator_new(&iter, notes_commits[1]));
+
+ for (i = 0; (err = git_note_next(&note_id, &annotated_id, iter)) >= 0; ++i) {
+ cl_git_pass(git_note_commit_read(&note, _repo, notes_commits[1], &annotated_id));
+ cl_assert_equal_s(git_note_message(note), note_message[i]);
+ git_note_free(note);
+ }
+
+ cl_assert_equal_i(GIT_ITEROVER, err);
+ cl_assert_equal_i(2, i);
+
+ git_note_iterator_free(iter);
+ git_commit_free(notes_commits[0]);
+ git_commit_free(notes_commits[1]);
+}
diff --git a/tests/odb/largefiles.c b/tests/odb/largefiles.c
new file mode 100644
index 000000000..22f136df5
--- /dev/null
+++ b/tests/odb/largefiles.c
@@ -0,0 +1,114 @@
+#include "clar_libgit2.h"
+#include "git2/odb_backend.h"
+
+static git_repository *repo;
+static git_odb *odb;
+
+void test_odb_largefiles__initialize(void)
+{
+ repo = cl_git_sandbox_init("testrepo.git");
+ cl_git_pass(git_repository_odb(&odb, repo));
+}
+
+void test_odb_largefiles__cleanup(void)
+{
+ git_odb_free(odb);
+ cl_git_sandbox_cleanup();
+}
+
+static void writefile(git_oid *oid)
+{
+ static git_odb_stream *stream;
+ git_buf buf = GIT_BUF_INIT;
+ size_t i;
+
+ for (i = 0; i < 3041; i++)
+ cl_git_pass(git_buf_puts(&buf, "Hello, world.\n"));
+
+ cl_git_pass(git_odb_open_wstream(&stream, odb, 5368709122, GIT_OBJ_BLOB));
+ for (i = 0; i < 126103; i++)
+ cl_git_pass(git_odb_stream_write(stream, buf.ptr, buf.size));
+
+ cl_git_pass(git_odb_stream_finalize_write(oid, stream));
+
+ git_odb_stream_free(stream);
+ git_buf_free(&buf);
+}
+
+void test_odb_largefiles__write_from_memory(void)
+{
+ git_oid expected, oid;
+ git_buf buf = GIT_BUF_INIT;
+ size_t i;
+
+#ifndef GIT_ARCH_64
+ cl_skip();
+#endif
+
+ if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE") ||
+ !cl_is_env_set("GITTEST_INVASIVE_MEMORY") ||
+ !cl_is_env_set("GITTEST_SLOW"))
+ cl_skip();
+
+ for (i = 0; i < (3041*126103); i++)
+ cl_git_pass(git_buf_puts(&buf, "Hello, world.\n"));
+
+ git_oid_fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c");
+ cl_git_pass(git_odb_write(&oid, odb, buf.ptr, buf.size, GIT_OBJ_BLOB));
+
+ cl_assert_equal_oid(&expected, &oid);
+}
+
+void test_odb_largefiles__streamwrite(void)
+{
+ git_oid expected, oid;
+
+ if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE") ||
+ !cl_is_env_set("GITTEST_SLOW"))
+ cl_skip();
+
+ git_oid_fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c");
+ writefile(&oid);
+
+ cl_assert_equal_oid(&expected, &oid);
+}
+
+void test_odb_largefiles__read_into_memory(void)
+{
+ git_oid oid;
+ git_odb_object *obj;
+
+#ifndef GIT_ARCH_64
+ cl_skip();
+#endif
+
+ if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE") ||
+ !cl_is_env_set("GITTEST_INVASIVE_MEMORY") ||
+ !cl_is_env_set("GITTEST_SLOW"))
+ cl_skip();
+
+ writefile(&oid);
+ cl_git_pass(git_odb_read(&obj, odb, &oid));
+
+ git_odb_object_free(obj);
+}
+
+void test_odb_largefiles__read_into_memory_rejected_on_32bit(void)
+{
+ git_oid oid;
+ git_odb_object *obj = NULL;
+
+#ifdef GIT_ARCH_64
+ cl_skip();
+#endif
+
+ if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE") ||
+ !cl_is_env_set("GITTEST_INVASIVE_MEMORY") ||
+ !cl_is_env_set("GITTEST_SLOW"))
+ cl_skip();
+
+ writefile(&oid);
+ cl_git_fail(git_odb_read(&obj, odb, &oid));
+
+ git_odb_object_free(obj);
+}
diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c
index a28ee3e07..f3c2204bd 100644
--- a/tests/pack/indexer.c
+++ b/tests/pack/indexer.c
@@ -41,6 +41,29 @@ static const unsigned char thin_pack[] = {
static const unsigned int thin_pack_len = 78;
/*
+ * Packfile with one object. It references an object which is not in the
+ * packfile and has a corrupt length (states the deltified stream is 1 byte
+ * long, where it is actually 6).
+ */
+static const unsigned char corrupt_thin_pack[] = {
+ 0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x71, 0xe6, 0x8f, 0xe8, 0x12, 0x9b, 0x54, 0x6b, 0x10, 0x1a, 0xee, 0x95,
+ 0x10, 0xc5, 0x32, 0x8e, 0x7f, 0x21, 0xca, 0x1d, 0x18, 0x78, 0x9c, 0x63,
+ 0x62, 0x66, 0x4e, 0xcb, 0xcf, 0x07, 0x00, 0x02, 0xac, 0x01, 0x4d, 0x07,
+ 0x67, 0x03, 0xc5, 0x40, 0x99, 0x49, 0xb1, 0x3b, 0x7d, 0xae, 0x9b, 0x0e,
+ 0xdd, 0xde, 0xc6, 0x76, 0x43, 0x24, 0x64
+};
+static const unsigned int corrupt_thin_pack_len = 67;
+
+/*
+ * Packfile with a missing trailer.
+ */
+static const unsigned char missing_trailer_pack[] = {
+ 0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x50, 0xf4, 0x3b,
+};
+static const unsigned int missing_trailer_pack_len = 12;
+
+/*
* Packfile that causes the packfile stream to open in a way in which it leaks
* the stream reader.
*/
@@ -71,6 +94,22 @@ void test_pack_indexer__out_of_order(void)
git_indexer_free(idx);
}
+void test_pack_indexer__missing_trailer(void)
+{
+ git_indexer *idx = 0;
+ git_transfer_progress stats = { 0 };
+
+ cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+ cl_git_pass(git_indexer_append(
+ idx, missing_trailer_pack, missing_trailer_pack_len, &stats));
+ cl_git_fail(git_indexer_commit(idx, &stats));
+
+ cl_assert(giterr_last() != NULL);
+ cl_assert_equal_i(giterr_last()->klass, GITERR_INDEXER);
+
+ git_indexer_free(idx);
+}
+
void test_pack_indexer__leaky(void)
{
git_indexer *idx = 0;
@@ -153,6 +192,35 @@ void test_pack_indexer__fix_thin(void)
}
}
+void test_pack_indexer__corrupt_length(void)
+{
+ git_indexer *idx = NULL;
+ git_transfer_progress stats = { 0 };
+ git_repository *repo;
+ git_odb *odb;
+ git_oid id, should_id;
+
+ cl_git_pass(git_repository_init(&repo, "thin.git", true));
+ cl_git_pass(git_repository_odb(&odb, repo));
+
+ /* Store the missing base into your ODB so the indexer can fix the pack */
+ cl_git_pass(git_odb_write(&id, odb, base_obj, base_obj_len, GIT_OBJ_BLOB));
+ git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18");
+ cl_assert_equal_oid(&should_id, &id);
+
+ cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL, NULL));
+ cl_git_pass(git_indexer_append(
+ idx, corrupt_thin_pack, corrupt_thin_pack_len, &stats));
+ cl_git_fail(git_indexer_commit(idx, &stats));
+
+ cl_assert(giterr_last() != NULL);
+ cl_assert_equal_i(giterr_last()->klass, GITERR_ZLIB);
+
+ git_indexer_free(idx);
+ git_odb_free(odb);
+ git_repository_free(repo);
+}
+
static int find_tmp_file_recurs(void *opaque, git_buf *path)
{
int error = 0;
diff --git a/tests/patch/parse.c b/tests/patch/parse.c
index 8350ac2dd..a40ad7b23 100644
--- a/tests/patch/parse.c
+++ b/tests/patch/parse.c
@@ -102,3 +102,9 @@ void test_patch_parse__invalid_patches_fails(void)
strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL));
}
+void test_patch_parse__files_with_whitespaces_succeeds(void)
+{
+ git_patch *patch;
+ cl_git_pass(git_patch_from_buffer(&patch, PATCH_NAME_WHITESPACE, strlen(PATCH_NAME_WHITESPACE), NULL));
+ git_patch_free(patch);
+}
diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h
index a20ebd617..e838e6089 100644
--- a/tests/patch/patch_common.h
+++ b/tests/patch/patch_common.h
@@ -575,6 +575,16 @@
"+added line with no nl\n" \
"\\ No newline at end of file\n"
+#define PATCH_NAME_WHITESPACE \
+ "diff --git a/file with spaces.txt b/file with spaces.txt\n" \
+ "index 9432026..83759c0 100644\n" \
+ "--- a/file with spaces.txt\n" \
+ "+++ b/file with spaces.txt\n" \
+ "@@ -0,3 +0,2 @@\n" \
+ " and this\n" \
+ "-is additional context\n" \
+ " below it!\n" \
+
#define PATCH_CORRUPT_GIT_HEADER \
"diff --git a/file.txt\n" \
"index 9432026..0f39b9a 100644\n" \
diff --git a/tests/refs/iterator.c b/tests/refs/iterator.c
index c77451309..56f6ce505 100644
--- a/tests/refs/iterator.c
+++ b/tests/refs/iterator.c
@@ -6,12 +6,12 @@ static git_repository *repo;
void test_refs_iterator__initialize(void)
{
- cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+ repo = cl_git_sandbox_init("testrepo.git");
}
void test_refs_iterator__cleanup(void)
{
- git_repository_free(repo);
+ cl_git_sandbox_cleanup();
}
static const char *refnames[] = {
@@ -36,6 +36,36 @@ static const char *refnames[] = {
"refs/tags/taggerless",
"refs/tags/test",
"refs/tags/wrapped_tag",
+ NULL
+};
+
+static const char *refnames_with_symlink[] = {
+ "refs/heads/br2",
+ "refs/heads/cannot-fetch",
+ "refs/heads/chomped",
+ "refs/heads/haacked",
+ "refs/heads/link/a",
+ "refs/heads/link/b",
+ "refs/heads/link/c",
+ "refs/heads/link/d",
+ "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",
+ NULL
};
static int refcmp_cb(const void *a, const void *b)
@@ -46,21 +76,21 @@ static int refcmp_cb(const void *a, const void *b)
return strcmp(refa->name, refb->name);
}
-static void assert_all_refnames_match(git_vector *output)
+static void assert_all_refnames_match(const char **expected, git_vector *names)
{
size_t i;
git_reference *ref;
- cl_assert_equal_sz(output->length, ARRAY_SIZE(refnames));
-
- git_vector_sort(output);
+ git_vector_sort(names);
- git_vector_foreach(output, i, ref) {
- cl_assert_equal_s(ref->name, refnames[i]);
+ git_vector_foreach(names, i, ref) {
+ cl_assert(expected[i] != NULL);
+ cl_assert_equal_s(expected[i], ref->name);
git_reference_free(ref);
}
+ cl_assert(expected[i] == NULL);
- git_vector_free(output);
+ git_vector_free(names);
}
void test_refs_iterator__list(void)
@@ -82,7 +112,7 @@ void test_refs_iterator__list(void)
git_reference_iterator_free(iter);
- assert_all_refnames_match(&output);
+ assert_all_refnames_match(refnames, &output);
}
void test_refs_iterator__empty(void)
@@ -115,7 +145,29 @@ void test_refs_iterator__foreach(void)
git_vector output;
cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
- assert_all_refnames_match(&output);
+ assert_all_refnames_match(refnames, &output);
+}
+
+void test_refs_iterator__foreach_through_symlink(void)
+{
+ git_vector output;
+
+#ifdef GIT_WIN32
+ cl_skip();
+#endif
+
+ cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
+
+ cl_git_pass(p_mkdir("refs", 0777));
+ cl_git_mkfile("refs/a", "1234567890123456789012345678901234567890");
+ cl_git_mkfile("refs/b", "1234567890123456789012345678901234567890");
+ cl_git_mkfile("refs/c", "1234567890123456789012345678901234567890");
+ cl_git_mkfile("refs/d", "1234567890123456789012345678901234567890");
+
+ cl_git_pass(p_symlink("../../../refs", "testrepo.git/refs/heads/link"));
+
+ cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
+ assert_all_refnames_match(refnames_with_symlink, &output);
}
static int refs_foreach_cancel_cb(git_reference *reference, void *payload)
@@ -156,12 +208,11 @@ void test_refs_iterator__foreach_name(void)
cl_git_pass(
git_reference_foreach_name(repo, refs_foreach_name_cb, &output));
- cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames));
git_vector_sort(&output);
git_vector_foreach(&output, i, name) {
- cl_assert_equal_s(name, refnames[i]);
- git__free(name);
+ cl_assert(refnames[i] != NULL);
+ cl_assert_equal_s(refnames[i], name);
}
git_vector_free(&output);
@@ -194,7 +245,7 @@ void test_refs_iterator__concurrent_delete(void)
const char *name;
int error;
- git_repository_free(repo);
+ cl_git_sandbox_cleanup();
repo = cl_git_sandbox_init("testrepo");
cl_git_pass(git_reference_iterator_new(&iter, repo));
@@ -215,7 +266,4 @@ void test_refs_iterator__concurrent_delete(void)
cl_assert_equal_i(GIT_ITEROVER, error);
cl_assert_equal_i(full_count, concurrent_count);
-
- cl_git_sandbox_cleanup();
- repo = NULL;
}
diff --git a/tests/resources/merge-resolve/.gitted/objects/50/c5dc8cdfe40c688eb0a0e23be54dd57cae2e78 b/tests/resources/merge-resolve/.gitted/objects/50/c5dc8cdfe40c688eb0a0e23be54dd57cae2e78
new file mode 100644
index 000000000..c04baa14b
--- /dev/null
+++ b/tests/resources/merge-resolve/.gitted/objects/50/c5dc8cdfe40c688eb0a0e23be54dd57cae2e78
@@ -0,0 +1,2 @@
+x]
+0})Jv">x/I6ZhIӞ*aeZC`F6;KLO).y8N^ }a'Ѱ S*gpmHp_sh/O>.PiF?,kJZGoJT \ No newline at end of file
diff --git a/tests/resources/merge-resolve/.gitted/objects/7a/a825857f87aea74ddf13d954568aa30dfcdeb4 b/tests/resources/merge-resolve/.gitted/objects/7a/a825857f87aea74ddf13d954568aa30dfcdeb4
new file mode 100644
index 000000000..b9c06303b
--- /dev/null
+++ b/tests/resources/merge-resolve/.gitted/objects/7a/a825857f87aea74ddf13d954568aa30dfcdeb4
Binary files differ
diff --git a/tests/resources/merge-resolve/.gitted/refs/heads/delete-submodule b/tests/resources/merge-resolve/.gitted/refs/heads/delete-submodule
new file mode 100644
index 000000000..1951316d5
--- /dev/null
+++ b/tests/resources/merge-resolve/.gitted/refs/heads/delete-submodule
@@ -0,0 +1 @@
+50c5dc8cdfe40c688eb0a0e23be54dd57cae2e78