void test_status_worktree__first_commit_in_progress(void) { git_repository *repo; git_index *index; status_entry_single result; cl_git_pass(git_repository_init(&repo, "getting_started", 0)); cl_git_mkfile("getting_started/testfile.txt", "content\n"); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(1, result.count); cl_assert(result.status == GIT_STATUS_WT_NEW); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_from_workdir(index, "testfile.txt")); cl_git_pass(git_index_write(index)); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(1, result.count); cl_assert(result.status == GIT_STATUS_INDEX_NEW); git_index_free(index); git_repository_free(repo); }
void test_status_ignore__subdirectories(void) { status_entry_single st; int ignored; git_status_options opts; GIT_UNUSED(opts); g_repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_mkfile( "empty_standard_repo/ignore_me", "I'm going to be ignored!"); cl_git_rewritefile("empty_standard_repo/.gitignore", "ignore_me\n"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert_equal_i(2, st.count); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_file(&st.status, g_repo, "ignore_me")); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_should_ignore(&ignored, g_repo, "ignore_me")); cl_assert(ignored); /* So, interestingly, as per the comment in diff_from_iterators() the * following file is ignored, but in a way so that it does not show up * in status even if INCLUDE_IGNORED is used. This actually matches * core git's behavior - if you follow these steps and try running "git * status -uall --ignored" then the following file and directory will * not show up in the output at all. */ cl_git_pass( git_futils_mkdir_r("empty_standard_repo/test/ignore_me", NULL, 0775)); cl_git_mkfile( "empty_standard_repo/test/ignore_me/file", "I'm going to be ignored!"); opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS; memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert_equal_i(2, st.count); cl_git_pass(git_status_file(&st.status, g_repo, "test/ignore_me/file")); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass( git_status_should_ignore(&ignored, g_repo, "test/ignore_me/file")); cl_assert(ignored); }
void test_status_ignore__subdirectories(void) { status_entry_single st; int ignored; g_repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_mkfile( "empty_standard_repo/ignore_me", "I'm going to be ignored!"); cl_git_rewritefile("empty_standard_repo/.gitignore", "ignore_me\n"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert_equal_i(2, st.count); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_file(&st.status, g_repo, "ignore_me")); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_should_ignore(&ignored, g_repo, "ignore_me")); cl_assert(ignored); /* I've changed libgit2 so that the behavior here now differs from * core git but seems to make more sense. In core git, the following * items are skipped completed, even if --ignored is passed to status. * It you mirror these steps and run "git status -uall --ignored" then * you will not see "test/ignore_me/" in the results. * * However, we had a couple reports of this as a bug, plus there is a * similar circumstance where we were differing for core git when you * used a rooted path for an ignore, so I changed this behavior. */ cl_git_pass(git_futils_mkdir_r( "empty_standard_repo/test/ignore_me", NULL, 0775)); cl_git_mkfile( "empty_standard_repo/test/ignore_me/file", "I'm going to be ignored!"); cl_git_mkfile( "empty_standard_repo/test/ignore_me/file2", "Me, too!"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert_equal_i(3, st.count); cl_git_pass(git_status_file(&st.status, g_repo, "test/ignore_me/file")); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass( git_status_should_ignore(&ignored, g_repo, "test/ignore_me/file")); cl_assert(ignored); }
void test_status_worktree__empty_repository(void) { int count = 0; git_status_foreach(_repository, cb_status__count, &count); cl_assert(count == 0); }
/* this test is equivalent to t18-status.c:statuscb2 */ void test_status_worktree__purged_worktree(void) { status_entry_counts counts; git_repository *repo = cl_git_sandbox_init("status"); git_buf workdir = GIT_BUF_INIT; /* first purge the contents of the worktree */ cl_git_pass(git_buf_sets(&workdir, git_repository_workdir(repo))); cl_git_pass(git_path_direach(&workdir, remove_file_cb, NULL)); git_buf_free(&workdir); /* now get status */ memset(&counts, 0x0, sizeof(status_entry_counts)); counts.expected_entry_count = entry_count2; counts.expected_paths = entry_paths2; counts.expected_statuses = entry_statuses2; cl_git_pass( git_status_foreach(repo, cb_status__normal, &counts) ); cl_assert_equal_i(counts.expected_entry_count, counts.entry_count); cl_assert_equal_i(0, counts.wrong_status_flags_count); cl_assert_equal_i(0, counts.wrong_sorted_path); }
static void check_status_at_line( git_repository *repo, size_t index_adds, size_t index_dels, size_t index_mods, size_t wt_adds, size_t wt_dels, size_t wt_mods, size_t ignores, const char *file, int line) { index_status_counts vals; memset(&vals, 0, sizeof(vals)); cl_git_pass(git_status_foreach(repo, index_status_cb, &vals)); clar__assert_equal( file,line,"wrong index adds", 1, "%"PRIuZ, index_adds, vals.index_adds); clar__assert_equal( file,line,"wrong index dels", 1, "%"PRIuZ, index_dels, vals.index_dels); clar__assert_equal( file,line,"wrong index mods", 1, "%"PRIuZ, index_mods, vals.index_mods); clar__assert_equal( file,line,"wrong workdir adds", 1, "%"PRIuZ, wt_adds, vals.wt_adds); clar__assert_equal( file,line,"wrong workdir dels", 1, "%"PRIuZ, wt_dels, vals.wt_dels); clar__assert_equal( file,line,"wrong workdir mods", 1, "%"PRIuZ, wt_mods, vals.wt_mods); clar__assert_equal( file,line,"wrong ignores", 1, "%"PRIuZ, ignores, vals.ignores); }
void test_status_ignore__filenames_with_special_prefixes_do_not_interfere_with_status_retrieval(void) { status_entry_single st; char *test_cases[] = { "!file", "#blah", "[blah]", "[attr]", "[attr]blah", NULL }; int i; for (i = 0; *(test_cases + i) != NULL; i++) { git_buf file = GIT_BUF_INIT; char *file_name = *(test_cases + i); git_repository *repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_pass(git_buf_joinpath(&file, "empty_standard_repo", file_name)); cl_git_mkfile(git_buf_cstr(&file), "Please don't ignore me!"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(repo, cb_status__single, &st)); cl_assert(st.count == 1); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&st.status, repo, file_name)); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_sandbox_cleanup(); git_buf_free(&file); } }
void test_status_ignore__empty_repo_with_gitignore_rewrite(void) { status_entry_single st; int ignored; g_repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_mkfile( "empty_standard_repo/look-ma.txt", "I'm going to be ignored!"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert(st.count == 1); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt")); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_should_ignore(&ignored, g_repo, "look-ma.txt")); cl_assert(!ignored); cl_git_rewritefile("empty_standard_repo/.gitignore", "*.nomatch\n"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert(st.count == 2); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt")); cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_should_ignore(&ignored, g_repo, "look-ma.txt")); cl_assert(!ignored); cl_git_rewritefile("empty_standard_repo/.gitignore", "*.txt\n"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st)); cl_assert(st.count == 2); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt")); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_should_ignore(&ignored, g_repo, "look-ma.txt")); cl_assert(ignored); }
/* this test is equivalent to t18-status.c:statuscb1 */ void test_status_worktree__empty_repository(void) { int count = 0; git_repository *repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_pass(git_status_foreach(repo, cb_status__count, &count)); cl_assert_equal_i(0, count); }
void test_status_worktree__issue_592_ignores_0(void) { int count = 0; status_entry_single st; git_repository *repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_status_foreach(repo, cb_status__count, &count)); cl_assert_equal_i(0, count); cl_git_rewritefile("issue_592/.gitignore", ".gitignore\n*.txt\nc/\n[tT]*/\n"); cl_git_pass(git_status_foreach(repo, cb_status__count, &count)); cl_assert_equal_i(1, count); /* This is a situation where the behavior of libgit2 is * different from core git. Core git will show ignored.txt * in the list of ignored files, even though the directory * "t" is ignored and the file is untracked because we have * the explicit "*.txt" ignore rule. Libgit2 just excludes * all untracked files that are contained within ignored * directories without explicitly listing them. */ cl_git_rewritefile("issue_592/t/ignored.txt", "ping"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(repo, cb_status__single, &st)); cl_assert_equal_i(1, st.count); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_rewritefile("issue_592/c/ignored_by_dir", "ping"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(repo, cb_status__single, &st)); cl_assert_equal_i(1, st.count); cl_assert(st.status == GIT_STATUS_IGNORED); cl_git_rewritefile("issue_592/t/ignored_by_dir_pattern", "ping"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(repo, cb_status__single, &st)); cl_assert_equal_i(1, st.count); cl_assert(st.status == GIT_STATUS_IGNORED); }
PyObject * Repository_status(Repository *self, PyObject *args) { PyObject *payload_dict; payload_dict = PyDict_New(); git_status_foreach(self->repo, read_status_cb, payload_dict); return payload_dict; }
void test_status_worktree__interruptable_foreach(void) { int count = 0; git_repository *repo = cl_git_sandbox_init("status"); cl_assert_equal_i( GIT_EUSER, git_status_foreach(repo, cb_status__interrupt, &count) ); cl_assert_equal_i(8, count); }
void test_status_worktree__issue_592_2(void) { git_repository *repo; git_buf path = GIT_BUF_INIT; repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c/a.txt")); cl_git_pass(p_unlink(git_buf_cstr(&path))); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); git_buf_free(&path); }
void GitWrapper::removeDeletedFromIndex(git_repository *repo, git_index* index) { git_status_foreach(repo, [] (const char *path, unsigned int status_flags, void *payload) -> int { if(status_flags & GIT_STATUS_WT_DELETED) { int i = 55; git_index * index = static_cast<git_index*>(payload); git_index_remove_bypath(index,path); } return 0; }, index); }
void test_status_worktree__issue_592_ignored_dirs_with_tracked_content(void) { int count = 0; git_repository *repo = cl_git_sandbox_init("issue_592b"); cl_git_pass(git_status_foreach(repo, cb_status__count, &count)); cl_assert_equal_i(1, count); /* if we are really mimicking core git, then only ignored1.txt * at the top level will show up in the ignores list here. * everything else will be unmodified or skipped completely. */ }
void test_status_worktree__issue_592_3(void) { git_repository *repo; git_buf path = GIT_BUF_INIT; repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c")); cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_DIRREMOVAL_FILES_AND_DIRS)); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); git_buf_free(&path); }
static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt) { git_oid base; const git_oid *local_id, *remote_id; if (!git_reference_cmp(local, remote)) return 0; // Dirty modified state in the working tree? We're not going // to update either way if (git_status_foreach(repo, check_clean, NULL)) return report_error("local cached copy is dirty, skipping update"); local_id = git_reference_target(local); remote_id = git_reference_target(remote); if (!local_id || !remote_id) return report_error("Unable to get local or remote SHA1"); if (git_merge_base(&base, repo, local_id, remote_id)) return report_error("Unable to find common commit of local and remote branches"); /* Is the remote strictly newer? Use it */ if (git_oid_equal(&base, local_id)) return reset_to_remote(repo, local, remote_id); /* Is the local repo the more recent one? See if we can update upstream */ if (git_oid_equal(&base, remote_id)) return update_remote(repo, origin, local, remote, rt); /* Merging a bare repository always needs user action */ if (git_repository_is_bare(repo)) return report_error("Local and remote have diverged, merge of bare branch needed"); /* Merging will definitely need the head branch too */ if (git_branch_is_head(local) != 1) return report_error("Local and remote do not match, local branch not HEAD - cannot update"); /* * Some day we migth try a clean merge here. * * But I couldn't find any good examples of this, so for now * you'd need to merge divergent histories manually. But we've * at least verified above that we have a working tree and the * current branch is checked out and clean, so we *could* try * to merge. */ return report_error("Local and remote have diverged, need to merge"); }
void test_status_worktree__issue_592_5(void) { git_repository *repo; git_buf path = GIT_BUF_INIT; repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t")); cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(p_mkdir(git_buf_cstr(&path), 0777)); cl_git_pass(git_status_foreach(repo, cb_status__check_592, NULL)); git_buf_free(&path); }
/** * Tests - Status determination on a working tree */ void test_status_worktree__whole_repository(void) { struct status_entry_counts counts; memset(&counts, 0x0, sizeof(struct status_entry_counts)); counts.expected_entry_count = entry_count0; counts.expected_paths = entry_paths0; counts.expected_statuses = entry_statuses0; cl_git_pass( git_status_foreach(_repository, cb_status__normal, &counts) ); cl_assert(counts.entry_count == counts.expected_entry_count); cl_assert(counts.wrong_status_flags_count == 0); cl_assert(counts.wrong_sorted_path == 0); }
/* this test is equivalent to t18-status.c:statuscb0 */ void test_status_worktree__whole_repository(void) { status_entry_counts counts; git_repository *repo = cl_git_sandbox_init("status"); memset(&counts, 0x0, sizeof(status_entry_counts)); counts.expected_entry_count = entry_count0; counts.expected_paths = entry_paths0; counts.expected_statuses = entry_statuses0; cl_git_pass( git_status_foreach(repo, cb_status__normal, &counts) ); cl_assert_equal_i(counts.expected_entry_count, counts.entry_count); cl_assert_equal_i(0, counts.wrong_status_flags_count); cl_assert_equal_i(0, counts.wrong_sorted_path); }
static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt) { git_oid base; const git_oid *local_id, *remote_id; if (!git_reference_cmp(local, remote)) return 0; // Dirty modified state in the working tree? We're not going // to update either way if (git_status_foreach(repo, check_clean, NULL)) return report_error("local cached copy is dirty, skipping update"); local_id = git_reference_target(local); remote_id = git_reference_target(remote); if (!local_id || !remote_id) return report_error("Unable to get local or remote SHA1"); if (git_merge_base(&base, repo, local_id, remote_id)) return report_error("Unable to find common commit of local and remote branches"); /* Is the remote strictly newer? Use it */ if (git_oid_equal(&base, local_id)) return reset_to_remote(repo, local, remote_id); /* Is the local repo the more recent one? See if we can update upstream */ if (git_oid_equal(&base, remote_id)) return update_remote(repo, origin, local, remote, rt); /* Merging a bare repository always needs user action */ if (git_repository_is_bare(repo)) return report_error("Local and remote have diverged, merge of bare branch needed"); /* Merging will definitely need the head branch too */ if (git_branch_is_head(local) != 1) return report_error("Local and remote do not match, local branch not HEAD - cannot update"); /* Ok, let's try to merge these */ return try_to_git_merge(repo, local, remote, &base, local_id, remote_id); }
static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, const char *remote_url, const char *branch, enum remote_transport rt) { git_oid base; const git_oid *local_id, *remote_id; int ret = 0; if (verbose) fprintf(stderr, "git storage: try to update\n"); if (!git_reference_cmp(local, remote)) return 0; // Dirty modified state in the working tree? We're not going // to update either way if (git_status_foreach(repo, check_clean, NULL)) { if (is_subsurface_cloud) goto cloud_data_error; else return report_error("local cached copy is dirty, skipping update"); } local_id = git_reference_target(local); remote_id = git_reference_target(remote); if (!local_id || !remote_id) { if (is_subsurface_cloud) goto cloud_data_error; else return report_error("Unable to get local or remote SHA1"); } if (git_merge_base(&base, repo, local_id, remote_id)) { // TODO: // if they have no merge base, they actually are different repos // so instead merge this as merging a commit into a repo - git_merge() appears to do that // but needs testing and cleanup afterwards // if (is_subsurface_cloud) goto cloud_data_error; else return report_error("Unable to find common commit of local and remote branches"); } /* Is the remote strictly newer? Use it */ if (git_oid_equal(&base, local_id)) { git_storage_update_progress(translate("gettextFromC", "Update local storage to match cloud storage")); return reset_to_remote(repo, local, remote_id); } /* Is the local repo the more recent one? See if we can update upstream */ if (git_oid_equal(&base, remote_id)) { if (verbose) fprintf(stderr, "local is newer than remote, update remote\n"); git_storage_update_progress(translate("gettextFromC", "Push local changes to cloud storage")); return update_remote(repo, origin, local, remote, rt); } /* Merging a bare repository always needs user action */ if (git_repository_is_bare(repo)) { if (is_subsurface_cloud) goto cloud_data_error; else return report_error("Local and remote have diverged, merge of bare branch needed"); } /* Merging will definitely need the head branch too */ if (git_branch_is_head(local) != 1) { if (is_subsurface_cloud) goto cloud_data_error; else return report_error("Local and remote do not match, local branch not HEAD - cannot update"); } /* Ok, let's try to merge these */ git_storage_update_progress(translate("gettextFromC", "Try to merge local changes into cloud storage")); ret = try_to_git_merge(repo, &local, remote, &base, local_id, remote_id); if (ret == 0) return update_remote(repo, origin, local, remote, rt); else return ret; cloud_data_error: // since we are working with Subsurface cloud storage we want to make the user interaction // as painless as possible. So if something went wrong with the local cache, tell the user // about it an move it away return cleanup_local_cache(remote_url, branch); }
} BEGIN_TEST(statuscb0, "test retrieving status for worktree of repository") git_repository *repo; struct status_entry_counts counts; must_pass(copydir_recurs(STATUS_WORKDIR_FOLDER, TEMP_REPO_FOLDER)); must_pass(p_rename(STATUS_REPOSITORY_TEMP_FOLDER, TEST_STD_REPO_FOLDER)); must_pass(git_repository_open(&repo, TEST_STD_REPO_FOLDER)); memset(&counts, 0x0, sizeof(struct status_entry_counts)); counts.expected_entry_count = ENTRY_COUNT0; counts.expected_paths = entry_paths0; counts.expected_statuses = entry_statuses0; must_pass(git_status_foreach(repo, status_cb, &counts)); must_be_true(counts.entry_count == counts.expected_entry_count); must_be_true(counts.wrong_status_flags_count == 0); must_be_true(counts.wrong_sorted_path == 0); git_repository_free(repo); git_futils_rmdir_r(TEMP_REPO_FOLDER, 1); END_TEST static int status_cb1(const char *GIT_UNUSED(path), unsigned int GIT_UNUSED(status_flags), void *payload) { int *count = (int *)payload;; GIT_UNUSED_ARG(path); GIT_UNUSED_ARG(status_flags);
void test_status_worktree__space_in_filename(void) { git_repository *repo; git_index *index; status_entry_single result; unsigned int status_flags; #define FILE_WITH_SPACE "LICENSE - copy.md" cl_git_pass(git_repository_init(&repo, "with_space", 0)); cl_git_mkfile("with_space/" FILE_WITH_SPACE, "I have a space in my name\n"); /* file is new to working directory */ memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(1, result.count); cl_assert(result.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); cl_assert(status_flags == GIT_STATUS_WT_NEW); /* ignore the file */ cl_git_rewritefile("with_space/.gitignore", "*.md\n.gitignore\n"); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); cl_assert(status_flags == GIT_STATUS_IGNORED); /* don't ignore the file */ cl_git_rewritefile("with_space/.gitignore", ".gitignore\n"); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); cl_assert(status_flags == GIT_STATUS_WT_NEW); /* add the file to the index */ cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_from_workdir(index, FILE_WITH_SPACE)); cl_git_pass(git_index_write(index)); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_INDEX_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); cl_assert(status_flags == GIT_STATUS_INDEX_NEW); git_index_free(index); git_repository_free(repo); }
void test_status_worktree__bracket_in_filename(void) { git_repository *repo; git_index *index; status_entry_single result; unsigned int status_flags; int error; #define FILE_WITH_BRACKET "LICENSE[1].md" #define FILE_WITHOUT_BRACKET "LICENSE1.md" cl_git_pass(git_repository_init(&repo, "with_bracket", 0)); cl_git_mkfile("with_bracket/" FILE_WITH_BRACKET, "I have a bracket in my name\n"); /* file is new to working directory */ memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(1, result.count); cl_assert(result.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); cl_assert(status_flags == GIT_STATUS_WT_NEW); /* ignore the file */ cl_git_rewritefile("with_bracket/.gitignore", "*.md\n.gitignore\n"); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_IGNORED); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); cl_assert(status_flags == GIT_STATUS_IGNORED); /* don't ignore the file */ cl_git_rewritefile("with_bracket/.gitignore", ".gitignore\n"); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); cl_assert(status_flags == GIT_STATUS_WT_NEW); /* add the file to the index */ cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_from_workdir(index, FILE_WITH_BRACKET)); cl_git_pass(git_index_write(index)); memset(&result, 0, sizeof(result)); cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); cl_assert_equal_i(2, result.count); cl_assert(result.status == GIT_STATUS_INDEX_NEW); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); cl_assert(status_flags == GIT_STATUS_INDEX_NEW); /* Create file without bracket */ cl_git_mkfile("with_bracket/" FILE_WITHOUT_BRACKET, "I have no bracket in my name!\n"); cl_git_pass(git_status_file(&status_flags, repo, FILE_WITHOUT_BRACKET)); cl_assert(status_flags == GIT_STATUS_WT_NEW); cl_git_pass(git_status_file(&status_flags, repo, "LICENSE\\[1\\].md")); cl_assert(status_flags == GIT_STATUS_INDEX_NEW); error = git_status_file(&status_flags, repo, FILE_WITH_BRACKET); cl_git_fail(error); cl_assert_equal_i(GIT_EAMBIGUOUS, error); git_index_free(index); git_repository_free(repo); }