void test_reset_mixed__reflog_is_correct(void) { git_buf buf = GIT_BUF_INIT; git_annotated_commit *annotated; const char *exp_msg = "commit: Updating test data so we can test inter-hunk-context"; reflog_check(repo, "HEAD", 9, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 9, "*****@*****.**", exp_msg); /* Branch not moving, no reflog entry */ cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}")); cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL)); reflog_check(repo, "HEAD", 9, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 9, "*****@*****.**", exp_msg); git_object_free(target); target = NULL; /* Moved branch, expect id in message */ cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}")); git_buf_clear(&buf); cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL)); reflog_check(repo, "HEAD", 10, NULL, git_buf_cstr(&buf)); reflog_check(repo, "refs/heads/master", 10, NULL, git_buf_cstr(&buf)); git_buf_free(&buf); /* Moved branch, expect revspec in message */ exp_msg = "reset: moving to HEAD~^{commit}"; cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "HEAD~^{commit}")); cl_git_pass(git_reset_from_annotated(repo, annotated, GIT_RESET_MIXED, NULL)); reflog_check(repo, "HEAD", 11, NULL, exp_msg); reflog_check(repo, "refs/heads/master", 11, NULL, exp_msg); git_annotated_commit_free(annotated); }
static int merge_differently_filtered_files(char *files[]) { git_reference *head; git_object *head_object; int error; cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT)); cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL)); /* Emulate checkout with a broken or misconfigured filter: modify some * files on-disk and then update the index with the updated file size * and time, as if some filter applied them. These files should not be * treated as dirty since we created them. * * (Make sure to update the index stamp to defeat racy-git protections * trying to sanity check the files in the index; those would rehash the * files, showing them as dirty, the exact mechanism we're trying to avoid.) */ write_files(files); hack_index(files); cl_git_pass(git_index_write(repo_index)); error = merge_branch(); git_object_free(head_object); git_reference_free(head); return error; }
void test_reset_mixed__cleanup(void) { git_object_free(target); target = NULL; cl_git_sandbox_cleanup(); }
void test_checkout_tree__can_not_update_index(void) { git_oid oid; git_object *head; unsigned int status; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_index *index; opts.checkout_strategy |= GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_UPDATE_INDEX; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "HEAD")); cl_git_pass(git_object_lookup(&head, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts, NULL, NULL)); cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_write(index)); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); git_object_free(head); git_index_free(index); }
static void stage_content(char *content[]) { git_reference *head; git_object *head_object; git_buf path = GIT_BUF_INIT; char *filename, *text; size_t i; cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT)); cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL)); for (i = 0, filename = content[i], text = content[++i]; filename && text; filename = content[++i], text = content[++i]) { git_buf_clear(&path); cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename)); cl_git_mkfile(path.ptr, text); cl_git_pass(git_index_add_bypath(repo_index, filename)); } git_object_free(head_object); git_reference_free(head); git_buf_free(&path); }
static void action_create_tag(tag_state *state) { git_repository *repo = state->repo; tag_options *opts = state->opts; git_signature *tagger; git_oid oid; git_object *target; check(!opts->tag_name, "Name required"); check(!opts->message, "Message required"); if (!opts->target) opts->target = "HEAD"; check_lg2(git_revparse_single(&target, repo, opts->target), "Unable to resolve spec", opts->target); check_lg2(git_signature_default(&tagger, repo), "Unable to create signature", NULL); check_lg2(git_tag_create(&oid, repo, opts->tag_name, target, tagger, opts->message, opts->force), "Unable to create tag", NULL); git_object_free(target); git_signature_free(tagger); }
void Object_dealloc(Object* self) { git_object_free(self->obj); Py_XDECREF(self->repo); PyObject_Del(self); }
void test_refs_branches_create__cleanup(void) { git_object_free(target); git_repository_free(repo); cl_fixture_cleanup("testrepo.git"); }
void test_checkout_tree__can_checkout_and_remove_directory(void) { cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); /* Checkout brach "subtrees" and update HEAD, so that HEAD matches the * current working tree */ cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL)); cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/")); cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt")); git_object_free(g_object); g_object = NULL; /* Checkout brach "master" and update HEAD, so that HEAD matches the * current working tree */ cl_git_pass(git_revparse_single(&g_object, g_repo, "master")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master", NULL, NULL)); /* This directory should no longer exist */ cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); }
void git_repository_free(git_repository *repo) { git_hashtable_iterator it; git_object *object; if (repo == NULL) return; free(repo->path_workdir); free(repo->path_index); free(repo->path_repository); free(repo->path_odb); git_hashtable_iterator_init(repo->objects, &it); while ((object = (git_object *) git_hashtable_iterator_next(&it)) != NULL) git_object_free(object); git_hashtable_free(repo->objects); git_repository__refcache_free(&repo->references); if (repo->db != NULL) git_odb_close(repo->db); if (repo->index != NULL) git_index_free(repo->index); free(repo); }
void test_refs_read__loose_tag(void) { // lookup a loose tag reference git_reference *reference; git_object *object; git_buf ref_name_from_tag_name = GIT_BUF_INIT; cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); cl_assert(git_reference_type(reference) & GIT_REF_OID); cl_assert(git_reference_is_packed(reference) == 0); cl_assert_equal_s(reference->name, loose_tag_ref_name); cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(reference), GIT_OBJ_ANY)); cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJ_TAG); /* Ensure the name of the tag matches the name of the reference */ cl_git_pass(git_buf_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object))); cl_assert_equal_s(ref_name_from_tag_name.ptr, loose_tag_ref_name); git_buf_free(&ref_name_from_tag_name); git_object_free(object); git_reference_free(reference); }
void Object_dealloc(Object* self) { Py_CLEAR(self->repo); git_object_free(self->obj); PyObject_Del(self); }
static int walk_and_search(git_object **out, git_revwalk *walk, regex_t *regex) { int error; git_oid oid; git_object *obj; while (!(error = git_revwalk_next(&oid, walk))) { error = git_object_lookup(&obj, git_revwalk_repository(walk), &oid, GIT_OBJ_COMMIT); if ((error < 0) && (error != GIT_ENOTFOUND)) return -1; if (!regexec(regex, git_commit_message((git_commit*)obj), 0, NULL, 0)) { *out = obj; return 0; } git_object_free(obj); } if (error < 0 && error == GIT_ITEROVER) error = GIT_ENOTFOUND; return error; }
int git_revparse_ext( git_object **object_out, git_reference **reference_out, git_repository *repo, const char *spec) { int error; size_t identifier_len; git_object *obj = NULL; git_reference *ref = NULL; if ((error = revparse__ext(&obj, &ref, &identifier_len, repo, spec)) < 0) goto cleanup; *object_out = obj; *reference_out = ref; GIT_UNUSED(identifier_len); return 0; cleanup: git_object_free(obj); git_reference_free(ref); return error; }
int CRepositoryBrowser::ReadTreeRecursive(git_repository &repo, git_tree * tree, CShadowFilesTree * treeroot) { size_t count = git_tree_entrycount(tree); for (int i = 0; i < count; ++i) { const git_tree_entry *entry = git_tree_entry_byindex(tree, i); if (entry == NULL) continue; const int mode = git_tree_entry_filemode(entry); CString base = CUnicodeUtils::GetUnicode(git_tree_entry_name(entry), CP_UTF8); const git_oid *oid = git_tree_entry_id(entry); CShadowFilesTree * pNextTree = &treeroot->m_ShadowTree[base]; pNextTree->m_sName = base; pNextTree->m_pParent = treeroot; pNextTree->m_hash = CGitHash((char *)oid->id); if (mode == GIT_FILEMODE_COMMIT) pNextTree->m_bSubmodule = true; else if (mode & S_IFDIR) { pNextTree->m_bFolder = true; TVINSERTSTRUCT tvinsert = {0}; tvinsert.hParent = treeroot->m_hTree; tvinsert.hInsertAfter = TVI_SORT; tvinsert.itemex.mask = TVIF_DI_SETITEM | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; tvinsert.itemex.pszText = base.GetBuffer(base.GetLength()); tvinsert.itemex.lParam = (LPARAM)pNextTree; tvinsert.itemex.iImage = m_nIconFolder; tvinsert.itemex.iSelectedImage = m_nOpenIconFolder; pNextTree->m_hTree = m_RepoTree.InsertItem(&tvinsert); base.ReleaseBuffer(); git_object *object = nullptr; git_tree_entry_to_object(&object, &repo, entry); if (object == nullptr) continue; ReadTreeRecursive(repo, (git_tree*)object, pNextTree); git_object_free(object); } else { git_blob * blob = nullptr; git_blob_lookup(&blob, &repo, oid); if (blob == NULL) continue; pNextTree->m_iSize = git_blob_rawsize(blob); git_blob_free(blob); } } return 0; }
static int handle_colon_syntax( git_object **out, git_object *obj, const char *path) { git_object *tree; int error = -1; git_tree_entry *entry = NULL; if ((error = git_object_peel(&tree, obj, GIT_OBJ_TREE)) < 0) return error == GIT_ENOTFOUND ? GIT_EINVALIDSPEC : error; if (*path == '\0') { *out = tree; return 0; } /* * TODO: Handle the relative path syntax * (:./relative/path and :../relative/path) */ if ((error = git_tree_entry_bypath(&entry, (git_tree *)tree, path)) < 0) goto cleanup; error = git_tree_entry_to_object(out, git_object_owner(tree), entry); cleanup: git_tree_entry_free(entry); git_object_free(tree); return error; }
void test_repo_head__setting_head_updates_reflog(void) { git_object *tag; git_signature *sig; git_annotated_commit *annotated; cl_git_pass(git_signature_now(&sig, "me", "*****@*****.**")); cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked")); cl_git_pass(git_repository_set_head(repo, "refs/heads/unborn")); cl_git_pass(git_revparse_single(&tag, repo, "tags/test")); cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag))); cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked")); test_reflog(repo, 2, NULL, "refs/heads/haacked", "*****@*****.**", "checkout: moving from master to haacked"); test_reflog(repo, 1, NULL, "tags/test^{commit}", "*****@*****.**", "checkout: moving from unborn to e90810b8df3e80c413d903f631643c716887138d"); test_reflog(repo, 0, "tags/test^{commit}", "refs/heads/haacked", "*****@*****.**", "checkout: moving from e90810b8df3e80c413d903f631643c716887138d to haacked"); cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "haacked~0")); cl_git_pass(git_repository_set_head_detached_from_annotated(repo, annotated)); test_reflog(repo, 0, NULL, "refs/heads/haacked", "*****@*****.**", "checkout: moving from haacked to haacked~0"); git_annotated_commit_free(annotated); git_object_free(tag); git_signature_free(sig); }
int git_branch_create( git_reference **ref_out, git_repository *repository, const char *branch_name, const git_object *target, int force) { git_object *commit = NULL; git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT; int error = -1; assert(branch_name && target && ref_out); assert(git_object_owner(target) == repository); if (git_object_peel(&commit, (git_object *)target, GIT_OBJ_COMMIT) < 0) return create_error_invalid("The given target does not resolve to a commit"); if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; error = git_reference_create_oid(&branch, repository, git_buf_cstr(&canonical_branch_name), git_object_id(commit), force); if (!error) *ref_out = branch; cleanup: git_object_free(commit); git_buf_free(&canonical_branch_name); return error; }
/* * call-seq: * tag.target -> git_object */ static VALUE rb_git_tag_target(VALUE self) { git_reference *ref, *resolved_ref; git_repository *repo; git_object *target; int error; VALUE rb_repo = rugged_owner(self); rugged_check_repo(rb_repo); Data_Get_Struct(self, git_reference, ref); Data_Get_Struct(rb_repo, git_repository, repo); error = git_reference_resolve(&resolved_ref, ref); rugged_exception_check(error); error = git_object_lookup(&target, repo, git_reference_target(resolved_ref), GIT_OBJ_ANY); git_reference_free(resolved_ref); rugged_exception_check(error); if (git_object_type(target) == GIT_OBJ_TAG) { git_object *annotation_target; error = git_tag_target(&annotation_target, (git_tag *)target); git_object_free(target); rugged_exception_check(error); return rugged_object_new(rb_repo, annotation_target); } else { return rugged_object_new(rb_repo, target); } }
PyObject * Repository_reset(Repository *self, PyObject* args) { PyObject *py_oid; git_oid oid; git_object *target = NULL; int err, reset_type; size_t len; if (!PyArg_ParseTuple(args, "Oi", &py_oid, &reset_type )) return NULL; len = py_oid_to_git_oid(py_oid, &oid); if (len == 0) return NULL; err = git_object_lookup_prefix(&target, self->repo, &oid, len, GIT_OBJ_ANY); err = err < 0 ? err : git_reset(self->repo, target, reset_type); git_object_free(target); if (err < 0) return Error_set_oid(err, &oid, len); Py_RETURN_NONE; }
void test_refs_read__nested_symbolic(void) { // lookup a nested symbolic reference git_reference *reference, *resolved_ref; git_object *object; git_oid id; cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name)); cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC); cl_assert(git_reference_is_packed(reference) == 0); cl_assert_equal_s(reference->name, head_tracker_sym_ref_name); cl_git_pass(git_reference_resolve(&resolved_ref, reference)); cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID); cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(resolved_ref), GIT_OBJ_ANY)); cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJ_COMMIT); git_oid_fromstr(&id, current_master_tip); cl_assert(git_oid_cmp(&id, git_object_id(object)) == 0); git_object_free(object); git_reference_free(reference); git_reference_free(resolved_ref); }
void test_object_tag_write__overwrite(void) { // Attempt to write a tag bearing the same name than an already existing tag git_oid target_id, tag_id; git_signature *tagger; git_object *target; git_oid_fromstr(&target_id, tagged_commit); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT)); /* create signature */ cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60)); cl_assert_equal_i(GIT_EEXISTS, git_tag_create( &tag_id, /* out id */ g_repo, "e90810b", target, tagger, tagger_message, 0)); git_object_free(target); git_signature_free(tagger); }
void test_object_tag_write__lightweight(void) { // write a lightweight tag to the repository and read it again git_oid target_id, object_id; git_reference *ref_tag; git_object *target; git_oid_fromstr(&target_id, tagged_commit); cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT)); cl_git_pass(git_tag_create_lightweight( &object_id, g_repo, "light-tag", target, 0)); git_object_free(target); cl_assert(git_oid_cmp(&object_id, &target_id) == 0); cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/light-tag")); cl_assert(git_oid_cmp(git_reference_oid(ref_tag), &target_id) == 0); cl_git_pass(git_tag_delete(g_repo, "light-tag")); git_reference_free(ref_tag); }
void test_describe_describe__describe_a_repo_with_no_refs(void) { git_repository *repo; git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; git_object *object; git_describe_result *result = NULL; repo = cl_git_sandbox_init("testrepo.git"); cl_git_pass(git_revparse_single(&object, repo, "HEAD")); cl_git_pass(git_reference_foreach(repo, delete_cb, NULL)); /* Impossible to describe without falling back to OIDs */ cl_git_fail(git_describe_commit(&result, object, &opts)); /* Try again with OID fallbacks */ opts.show_commit_oid_as_fallback = 1; cl_git_pass(git_describe_commit(&result, object, &opts)); git_describe_result_free(result); git_object_free(object); git_buf_dispose(&buf); cl_git_sandbox_cleanup(); }
PyObject * Repository_create_tag(Repository *self, PyObject *args) { PyObject *py_oid; Signature *py_tagger; char *tag_name, *message; git_oid oid; git_object *target = NULL; int err, target_type, len; if (!PyArg_ParseTuple(args, "sOiO!s", &tag_name, &py_oid, &target_type, &SignatureType, &py_tagger, &message)) return NULL; len = py_str_to_git_oid(py_oid, &oid); if (len < 0) return NULL; err = git_object_lookup_prefix(&target, self->repo, &oid, (unsigned int)len, target_type); err = err < 0 ? err : git_tag_create(&oid, self->repo, tag_name, target, py_tagger->signature, message, 0); git_object_free(target); if (err < 0) return Error_set_oid(err, &oid, len); return git_oid_to_python(oid.id); }
static void retrieve_target_from_oid(git_commit **out, git_repository *repo, const char *sha) { git_object *obj; cl_git_pass(git_revparse_single(&obj, repo, sha)); cl_git_pass(git_commit_lookup(out, repo, git_object_id(obj))); git_object_free(obj); }
void test_reset_hard__cleanup(void) { if (target != NULL) { git_object_free(target); target = NULL; } cl_git_sandbox_cleanup(); }
int git_branch_create( git_oid *oid_out, git_repository *repo, const char *branch_name, const git_object *target, int force) { git_otype target_type = GIT_OBJ_BAD; git_object *commit = NULL; git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT; int error = -1; assert(repo && branch_name && target && oid_out); if (git_object_owner(target) != repo) return create_error_invalid("The given target does not belong to this repository"); target_type = git_object_type(target); switch (target_type) { case GIT_OBJ_TAG: if (git_tag_peel(&commit, (git_tag *)target) < 0) goto cleanup; if (git_object_type(commit) != GIT_OBJ_COMMIT) { create_error_invalid("The given target does not resolve to a commit"); goto cleanup; } break; case GIT_OBJ_COMMIT: commit = (git_object *)target; break; default: return create_error_invalid("Only git_tag and git_commit objects are valid targets."); } if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; if (git_reference_create_oid(&branch, repo, git_buf_cstr(&canonical_branch_name), git_object_id(commit), force) < 0) goto cleanup; git_oid_cpy(oid_out, git_reference_oid(branch)); error = 0; cleanup: if (target_type == GIT_OBJ_TAG) git_object_free(commit); git_reference_free(branch); git_buf_free(&canonical_branch_name); return error; }
static void assert_workdir_matches_tree( git_repository *repo, const git_oid *id, const char *root, bool recurse) { git_object *obj; git_tree *tree; size_t i, max_i; git_buf path = GIT_BUF_INIT; if (!root) root = git_repository_workdir(repo); cl_assert(root); cl_git_pass(git_object_lookup(&obj, repo, id, GIT_OBJ_ANY)); cl_git_pass(git_object_peel((git_object **)&tree, obj, GIT_OBJ_TREE)); git_object_free(obj); max_i = git_tree_entrycount(tree); for (i = 0; i < max_i; ++i) { const git_tree_entry *te = git_tree_entry_byindex(tree, i); cl_assert(te); cl_git_pass(git_buf_joinpath(&path, root, git_tree_entry_name(te))); switch (git_tree_entry_type(te)) { case GIT_OBJ_COMMIT: assert_dir_exists(path.ptr); break; case GIT_OBJ_TREE: assert_dir_exists(path.ptr); if (recurse) assert_workdir_matches_tree( repo, git_tree_entry_id(te), path.ptr, true); break; case GIT_OBJ_BLOB: switch (git_tree_entry_filemode(te)) { case GIT_FILEMODE_BLOB: case GIT_FILEMODE_BLOB_EXECUTABLE: assert_file_exists(path.ptr); /* because of cross-platform, don't confirm exec bit yet */ break; case GIT_FILEMODE_LINK: cl_assert_(git_path_exists(path.ptr), path.ptr); /* because of cross-platform, don't confirm link yet */ break; default: cl_assert(false); /* really?! */ } break; default: cl_assert(false); /* really?!! */ } } git_tree_free(tree); git_buf_free(&path); }
void test_repo_pathspec__tree5(void) { git_object *tree; git_strarray s; git_pathspec *ps; git_pathspec_match_list *m; /* { "S*" } */ s.strings = str5; s.count = ARRAY_SIZE(str5); cl_git_pass(git_pathspec_new(&ps, &s)); cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD~2^{tree}")); cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree, GIT_PATHSPEC_USE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps)); cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m)); cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m)); git_pathspec_match_list_free(m); cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree, GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps)); cl_assert_equal_sz(5, git_pathspec_match_list_entrycount(m)); cl_assert_equal_s("staged_changes", git_pathspec_match_list_entry(m, 0)); cl_assert_equal_s("staged_delete_modified_file", git_pathspec_match_list_entry(m, 4)); cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m)); git_pathspec_match_list_free(m); git_object_free(tree); cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD^{tree}")); cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree, GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps)); cl_assert_equal_sz(9, git_pathspec_match_list_entrycount(m)); cl_assert_equal_s("staged_changes", git_pathspec_match_list_entry(m, 0)); cl_assert_equal_s("subdir.txt", git_pathspec_match_list_entry(m, 5)); cl_assert_equal_s("subdir/current_file", git_pathspec_match_list_entry(m, 6)); cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m)); git_pathspec_match_list_free(m); git_object_free(tree); git_pathspec_free(ps); }