Blame tests/status/worktree.c

Packit Service 20376f
#include "clar_libgit2.h"
Packit Service 20376f
#include "fileops.h"
Packit Service 20376f
#include "ignore.h"
Packit Service 20376f
#include "status_data.h"
Packit Service 20376f
#include "posix.h"
Packit Service 20376f
#include "util.h"
Packit Service 20376f
#include "path.h"
Packit Service 20376f
#include "../diff/diff_helpers.h"
Packit Service 20376f
#include "../checkout/checkout_helpers.h"
Packit Service 20376f
#include "git2/sys/diff.h"
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Cleanup
Packit Service 20376f
 *
Packit Service 20376f
 * This will be called once after each test finishes, even
Packit Service 20376f
 * if the test failed
Packit Service 20376f
 */
Packit Service 20376f
void test_status_worktree__cleanup(void)
Packit Service 20376f
{
Packit Service 20376f
	cl_git_sandbox_cleanup();
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Tests - Status determination on a working tree
Packit Service 20376f
 */
Packit Service 20376f
/* this test is equivalent to t18-status.c:statuscb0 */
Packit Service 20376f
void test_status_worktree__whole_repository(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_count0;
Packit Service 20376f
	counts.expected_paths = entry_paths0;
Packit Service 20376f
	counts.expected_statuses = entry_statuses0;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach(repo, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void assert_show(
Packit Service 20376f
	const int entry_counts,
Packit Service 20376f
	const char *entry_paths[],
Packit Service 20376f
	const unsigned int entry_statuses[],
Packit Service 20376f
	git_repository *repo,
Packit Service 20376f
	git_status_show_t show,
Packit Service 20376f
	unsigned int extra_flags)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_counts;
Packit Service 20376f
	counts.expected_paths = entry_paths;
Packit Service 20376f
	counts.expected_statuses = entry_statuses;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS | extra_flags;
Packit Service 20376f
	opts.show = show;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__show_index_and_workdir(void)
Packit Service 20376f
{
Packit Service 20376f
	assert_show(entry_count0, entry_paths0, entry_statuses0,
Packit Service 20376f
		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_INDEX_AND_WORKDIR, 0);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__show_index_only(void)
Packit Service 20376f
{
Packit Service 20376f
	assert_show(entry_count5, entry_paths5, entry_statuses5,
Packit Service 20376f
		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_INDEX_ONLY, 0);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__show_workdir_only(void)
Packit Service 20376f
{
Packit Service 20376f
	assert_show(entry_count6, entry_paths6, entry_statuses6,
Packit Service 20376f
		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_WORKDIR_ONLY, 0);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:statuscb1 */
Packit Service 20376f
void test_status_worktree__empty_repository(void)
Packit Service 20376f
{
Packit Service 20376f
	int count = 0;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(0, count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static int remove_file_cb(void *data, git_buf *file)
Packit Service 20376f
{
Packit Service 20376f
	const char *filename = git_buf_cstr(file);
Packit Service 20376f
Packit Service 20376f
	GIT_UNUSED(data);
Packit Service 20376f
Packit Service 20376f
	if (git__suffixcmp(filename, ".git") == 0)
Packit Service 20376f
		return 0;
Packit Service 20376f
Packit Service 20376f
	if (git_path_isdir(filename))
Packit Service 20376f
		cl_git_pass(git_futils_rmdir_r(filename, NULL, GIT_RMDIR_REMOVE_FILES));
Packit Service 20376f
	else
Packit Service 20376f
		cl_git_pass(p_unlink(git_buf_cstr(file)));
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:statuscb2 */
Packit Service 20376f
void test_status_worktree__purged_worktree(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_buf workdir = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	/* first purge the contents of the worktree */
Packit Service 20376f
	cl_git_pass(git_buf_sets(&workdir, git_repository_workdir(repo)));
Packit Service 20376f
	cl_git_pass(git_path_direach(&workdir, 0, remove_file_cb, NULL));
Packit Service 20376f
	git_buf_free(&workdir);
Packit Service 20376f
Packit Service 20376f
	/* now get status */
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_count2;
Packit Service 20376f
	counts.expected_paths = entry_paths2;
Packit Service 20376f
	counts.expected_statuses = entry_statuses2;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach(repo, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is similar to t18-status.c:statuscb3 */
Packit Service 20376f
void test_status_worktree__swap_subdir_and_file(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	bool ignore_case;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	ignore_case = (git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
Packit Service 20376f
	/* first alter the contents of the worktree */
Packit Service 20376f
	cl_git_pass(p_rename("status/current_file", "status/swap"));
Packit Service 20376f
	cl_git_pass(p_rename("status/subdir", "status/current_file"));
Packit Service 20376f
	cl_git_pass(p_rename("status/swap", "status/subdir"));
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile("status/.HEADER", "dummy");
Packit Service 20376f
	cl_git_mkfile("status/42-is-not-prime.sigh", "dummy");
Packit Service 20376f
	cl_git_mkfile("status/README.md", "dummy");
Packit Service 20376f
Packit Service 20376f
	/* now get status */
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_count3;
Packit Service 20376f
	counts.expected_paths = ignore_case ? entry_paths3_icase : entry_paths3;
Packit Service 20376f
	counts.expected_statuses = ignore_case ? entry_statuses3_icase : entry_statuses3;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_IGNORED;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__swap_subdir_with_recurse_and_pathspec(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
Packit Service 20376f
	/* first alter the contents of the worktree */
Packit Service 20376f
	cl_git_pass(p_rename("status/current_file", "status/swap"));
Packit Service 20376f
	cl_git_pass(p_rename("status/subdir", "status/current_file"));
Packit Service 20376f
	cl_git_pass(p_rename("status/swap", "status/subdir"));
Packit Service 20376f
	cl_git_mkfile("status/.new_file", "dummy");
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r("status/zzz_new_dir", 0777));
Packit Service 20376f
	cl_git_mkfile("status/zzz_new_dir/new_file", "dummy");
Packit Service 20376f
	cl_git_mkfile("status/zzz_new_file", "dummy");
Packit Service 20376f
Packit Service 20376f
	/* now get status */
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_count4;
Packit Service 20376f
	counts.expected_paths = entry_paths4;
Packit Service 20376f
	counts.expected_statuses = entry_statuses4;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
	/* TODO: set pathspec to "current_file" eventually */
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void stage_and_commit(git_repository *repo, const char *path)
Packit Service 20376f
{
Packit Service 20376f
	git_index *index;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	cl_git_pass(git_index_add_bypath(index, path));
Packit Service 20376f
	cl_repo_commit_from_index(NULL, repo, NULL, 1323847743, "Initial commit\n");
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__within_subdir(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	char *paths[] = { "zzz_new_dir" };
Packit Service 20376f
	git_strarray pathsArray;
Packit Service 20376f
Packit Service 20376f
	/* first alter the contents of the worktree */
Packit Service 20376f
	cl_git_mkfile("status/.new_file", "dummy");
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r("status/zzz_new_dir", 0777));
Packit Service 20376f
	cl_git_mkfile("status/zzz_new_dir/new_file", "dummy");
Packit Service 20376f
	cl_git_mkfile("status/zzz_new_file", "dummy");
Packit Service 20376f
	cl_git_mkfile("status/wut", "dummy");
Packit Service 20376f
Packit Service 20376f
	stage_and_commit(repo, "zzz_new_dir/new_file");
Packit Service 20376f
Packit Service 20376f
	/* now get status */
Packit Service 20376f
	memset(&counts, 0x0, sizeof(status_entry_counts));
Packit Service 20376f
	counts.expected_entry_count = entry_count4;
Packit Service 20376f
	counts.expected_paths = entry_paths4;
Packit Service 20376f
	counts.expected_statuses = entry_statuses4;
Packit Service 20376f
	counts.debug = true;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
Packit Service 20376f
		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
Packit Service 20376f
Packit Service 20376f
	pathsArray.count = 1;
Packit Service 20376f
	pathsArray.strings = paths;
Packit Service 20376f
	opts.pathspec = pathsArray;
Packit Service 20376f
Packit Service 20376f
	// We committed zzz_new_dir/new_file above. It shouldn't be reported.
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(0, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:singlestatus0 */
Packit Service 20376f
void test_status_worktree__single_file(void)
Packit Service 20376f
{
Packit Service 20376f
	int i;
Packit Service 20376f
	unsigned int status_flags;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < (int)entry_count0; i++) {
Packit Service 20376f
		cl_git_pass(
Packit Service 20376f
			git_status_file(&status_flags, repo, entry_paths0[i])
Packit Service 20376f
		);
Packit Service 20376f
		cl_assert(entry_statuses0[i] == status_flags);
Packit Service 20376f
	}
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:singlestatus1 */
Packit Service 20376f
void test_status_worktree__single_nonexistent_file(void)
Packit Service 20376f
{
Packit Service 20376f
	int error;
Packit Service 20376f
	unsigned int status_flags;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	error = git_status_file(&status_flags, repo, "nonexistent");
Packit Service 20376f
	cl_git_fail(error);
Packit Service 20376f
	cl_assert(error == GIT_ENOTFOUND);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:singlestatus2 */
Packit Service 20376f
void test_status_worktree__single_nonexistent_file_empty_repo(void)
Packit Service 20376f
{
Packit Service 20376f
	int error;
Packit Service 20376f
	unsigned int status_flags;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
Packit Service 20376f
	error = git_status_file(&status_flags, repo, "nonexistent");
Packit Service 20376f
	cl_git_fail(error);
Packit Service 20376f
	cl_assert(error == GIT_ENOTFOUND);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:singlestatus3 */
Packit Service 20376f
void test_status_worktree__single_file_empty_repo(void)
Packit Service 20376f
{
Packit Service 20376f
	unsigned int status_flags;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile("empty_standard_repo/new_file", "new_file\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status_flags, repo, "new_file"));
Packit Service 20376f
	cl_assert(status_flags == GIT_STATUS_WT_NEW);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* this test is equivalent to t18-status.c:singlestatus4 */
Packit Service 20376f
void test_status_worktree__single_folder(void)
Packit Service 20376f
{
Packit Service 20376f
	int error;
Packit Service 20376f
	unsigned int status_flags;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	error = git_status_file(&status_flags, repo, "subdir");
Packit Service 20376f
	cl_git_fail(error);
Packit Service 20376f
	cl_assert(error != GIT_ENOTFOUND);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__ignores(void)
Packit Service 20376f
{
Packit Service 20376f
	int i, ignored;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < (int)entry_count0; i++) {
Packit Service 20376f
		cl_git_pass(
Packit Service 20376f
			git_status_should_ignore(&ignored, repo, entry_paths0[i])
Packit Service 20376f
		);
Packit Service 20376f
		cl_assert(ignored == (entry_statuses0[i] == GIT_STATUS_IGNORED));
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_should_ignore(&ignored, repo, "nonexistent_file")
Packit Service 20376f
	);
Packit Service 20376f
	cl_assert(!ignored);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_should_ignore(&ignored, repo, "ignored_nonexistent_file")
Packit Service 20376f
	);
Packit Service 20376f
	cl_assert(ignored);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static int cb_status__check_592(const char *p, unsigned int s, void *payload)
Packit Service 20376f
{
Packit Service 20376f
	if (s != GIT_STATUS_WT_DELETED ||
Packit Service 20376f
		(payload != NULL && strcmp(p, (const char *)payload) != 0))
Packit Service 20376f
		return -1;
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_buf path = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "l.txt"));
Packit Service 20376f
	cl_git_pass(p_unlink(git_buf_cstr(&path)));
Packit Service 20376f
	cl_assert(!git_path_exists("issue_592/l.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt"));
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_2(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_buf path = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c/a.txt"));
Packit Service 20376f
	cl_git_pass(p_unlink(git_buf_cstr(&path)));
Packit Service 20376f
	cl_assert(!git_path_exists("issue_592/c/a.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_3(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_buf path = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c"));
Packit Service 20376f
	cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES));
Packit Service 20376f
	cl_assert(!git_path_exists("issue_592/c/a.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_4(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_buf path = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t/b.txt"));
Packit Service 20376f
	cl_git_pass(p_unlink(git_buf_cstr(&path)));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "t/b.txt"));
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_5(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_buf path = GIT_BUF_INIT;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t"));
Packit Service 20376f
	cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES));
Packit Service 20376f
	cl_git_pass(p_mkdir(git_buf_cstr(&path), 0777));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__check_592, NULL));
Packit Service 20376f
Packit Service 20376f
	git_buf_free(&path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_ignores_0(void)
Packit Service 20376f
{
Packit Service 20376f
	int count = 0;
Packit Service 20376f
	status_entry_single st;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("issue_592");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
Packit Service 20376f
	cl_assert_equal_i(0, count);
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("issue_592/.gitignore",
Packit Service 20376f
		".gitignore\n*.txt\nc/\n[tT]*/\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
Packit Service 20376f
	cl_assert_equal_i(1, count);
Packit Service 20376f
Packit Service 20376f
	/* This is a situation where the behavior of libgit2 is
Packit Service 20376f
	 * different from core git.  Core git will show ignored.txt
Packit Service 20376f
	 * in the list of ignored files, even though the directory
Packit Service 20376f
	 * "t" is ignored and the file is untracked because we have
Packit Service 20376f
	 * the explicit "*.txt" ignore rule.  Libgit2 just excludes
Packit Service 20376f
	 * all untracked files that are contained within ignored
Packit Service 20376f
	 * directories without explicitly listing them.
Packit Service 20376f
	 */
Packit Service 20376f
	cl_git_rewritefile("issue_592/t/ignored.txt", "ping");
Packit Service 20376f
Packit Service 20376f
	memset(&st, 0, sizeof(st));
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__single, &st);;
Packit Service 20376f
	cl_assert_equal_i(1, st.count);
Packit Service 20376f
	cl_assert(st.status == GIT_STATUS_IGNORED);
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("issue_592/c/ignored_by_dir", "ping");
Packit Service 20376f
Packit Service 20376f
	memset(&st, 0, sizeof(st));
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__single, &st);;
Packit Service 20376f
	cl_assert_equal_i(1, st.count);
Packit Service 20376f
	cl_assert(st.status == GIT_STATUS_IGNORED);
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("issue_592/t/ignored_by_dir_pattern", "ping");
Packit Service 20376f
Packit Service 20376f
	memset(&st, 0, sizeof(st));
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__single, &st);;
Packit Service 20376f
	cl_assert_equal_i(1, st.count);
Packit Service 20376f
	cl_assert(st.status == GIT_STATUS_IGNORED);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__issue_592_ignored_dirs_with_tracked_content(void)
Packit Service 20376f
{
Packit Service 20376f
	int count = 0;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("issue_592b");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
Packit Service 20376f
	cl_assert_equal_i(1, count);
Packit Service 20376f
Packit Service 20376f
	/* if we are really mimicking core git, then only ignored1.txt
Packit Service 20376f
	 * at the top level will show up in the ignores list here.
Packit Service 20376f
	 * everything else will be unmodified or skipped completely.
Packit Service 20376f
	 */
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__conflict_with_diff3(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	unsigned int status;
Packit Service 20376f
	git_index_entry ancestor_entry, our_entry, their_entry;
Packit Service 20376f
Packit Service 20376f
	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
	memset(&our_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
	memset(&their_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
Packit Service 20376f
	ancestor_entry.path = "modified_file";
Packit Service 20376f
	ancestor_entry.mode = 0100644;
Packit Service 20376f
	git_oid_fromstr(&ancestor_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	our_entry.path = "modified_file";
Packit Service 20376f
	our_entry.mode = 0100644;
Packit Service 20376f
	git_oid_fromstr(&our_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	their_entry.path = "modified_file";
Packit Service 20376f
	their_entry.mode = 0100644;
Packit Service 20376f
	git_oid_fromstr(&their_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "modified_file"));
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	cl_git_pass(git_index_remove(index, "modified_file", 0));
Packit Service 20376f
	cl_git_pass(git_index_conflict_add(
Packit Service 20376f
		index, &ancestor_entry, &our_entry, &their_entry));
Packit Service 20376f
	cl_git_pass(git_index_write(index));
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "modified_file"));
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static const char *filemode_paths[] = {
Packit Service 20376f
	"exec_off",
Packit Service 20376f
	"exec_off2on_staged",
Packit Service 20376f
	"exec_off2on_workdir",
Packit Service 20376f
	"exec_off_untracked",
Packit Service 20376f
	"exec_on",
Packit Service 20376f
	"exec_on2off_staged",
Packit Service 20376f
	"exec_on2off_workdir",
Packit Service 20376f
	"exec_on_untracked",
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static unsigned int filemode_statuses[] = {
Packit Service 20376f
	GIT_STATUS_CURRENT,
Packit Service 20376f
	GIT_STATUS_INDEX_MODIFIED,
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
	GIT_STATUS_WT_NEW,
Packit Service 20376f
	GIT_STATUS_CURRENT,
Packit Service 20376f
	GIT_STATUS_INDEX_MODIFIED,
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
	GIT_STATUS_WT_NEW
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static const int filemode_count = 8;
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__filemode_changes(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("filemodes");
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
Packit Service 20376f
	/* overwrite stored filemode with platform appropriate value */
Packit Service 20376f
	if (cl_is_chmod_supported())
Packit Service 20376f
		cl_repo_set_bool(repo, "core.filemode", true);
Packit Service 20376f
	else {
Packit Service 20376f
		int i;
Packit Service 20376f
Packit Service 20376f
		cl_repo_set_bool(repo, "core.filemode", false);
Packit Service 20376f
Packit Service 20376f
		/* won't trust filesystem mode diffs, so these will appear unchanged */
Packit Service 20376f
		for (i = 0; i < filemode_count; ++i)
Packit Service 20376f
			if (filemode_statuses[i] == GIT_STATUS_WT_MODIFIED)
Packit Service 20376f
				filemode_statuses[i] = GIT_STATUS_CURRENT;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_IGNORED |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0, sizeof(counts));
Packit Service 20376f
	counts.expected_entry_count = filemode_count;
Packit Service 20376f
	counts.expected_paths = filemode_paths;
Packit Service 20376f
	counts.expected_statuses = filemode_statuses;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static int cb_status__interrupt(const char *p, unsigned int s, void *payload)
Packit Service 20376f
{
Packit Service 20376f
	volatile int *count = (int *)payload;
Packit Service 20376f
Packit Service 20376f
	GIT_UNUSED(p);
Packit Service 20376f
	GIT_UNUSED(s);
Packit Service 20376f
Packit Service 20376f
	(*count)++;
Packit Service 20376f
Packit Service 20376f
	return (*count == 8) ? -111 : 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__interruptable_foreach(void)
Packit Service 20376f
{
Packit Service 20376f
	int count = 0;
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(
Packit Service 20376f
		-111, git_status_foreach(repo, cb_status__interrupt, &count)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(8, count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__line_endings_dont_count_as_changes_with_autocrlf(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	unsigned int status;
Packit Service 20376f
Packit Service 20376f
	cl_repo_set_bool(repo, "core.autocrlf", true);
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("status/current_file", "current_file\r\n");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "current_file"));
Packit Service 20376f
Packit Service 20376f
	/* stat data on file should no longer match stat cache, even though
Packit Service 20376f
	 * file diff will be empty because of line-ending conversion - matches
Packit Service 20376f
	 * the Git command-line behavior here.
Packit Service 20376f
	 */
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__line_endings_dont_count_as_changes_with_autocrlf_issue_1397(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("issue_1397");
Packit Service 20376f
	unsigned int status;
Packit Service 20376f
Packit Service 20376f
	cl_repo_set_bool(repo, "core.autocrlf", true);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "crlf_file.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_CURRENT, status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__conflicted_item(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	unsigned int status;
Packit Service 20376f
	git_index_entry ancestor_entry, our_entry, their_entry;
Packit Service 20376f
Packit Service 20376f
	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
	memset(&our_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
	memset(&their_entry, 0x0, sizeof(git_index_entry));
Packit Service 20376f
Packit Service 20376f
	ancestor_entry.mode = 0100644;
Packit Service 20376f
	ancestor_entry.path = "modified_file";
Packit Service 20376f
	git_oid_fromstr(&ancestor_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	our_entry.mode = 0100644;
Packit Service 20376f
	our_entry.path = "modified_file";
Packit Service 20376f
	git_oid_fromstr(&our_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	their_entry.mode = 0100644;
Packit Service 20376f
	their_entry.path = "modified_file";
Packit Service 20376f
	git_oid_fromstr(&their_entry.id,
Packit Service 20376f
		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "modified_file"));
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	cl_git_pass(git_index_conflict_add(index, &ancestor_entry,
Packit Service 20376f
		&our_entry, &their_entry));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo, "modified_file"));
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status);
Packit Service 20376f
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__conflict_has_no_oid(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_index_entry entry = {{0}};
Packit Service 20376f
	git_status_list *statuslist;
Packit Service 20376f
	const git_status_entry *status;
Packit Service 20376f
	git_oid zero_id = {{0}};
Packit Service 20376f
Packit Service 20376f
	entry.mode = 0100644;
Packit Service 20376f
	entry.path = "modified_file";
Packit Service 20376f
	git_oid_fromstr(&entry.id, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	cl_git_pass(git_index_conflict_add(index, &entry, &entry, &entry));
Packit Service 20376f
Packit Service 20376f
	git_status_list_new(&statuslist, repo, NULL);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(16, git_status_list_entrycount(statuslist));
Packit Service 20376f
Packit Service 20376f
	status = git_status_byindex(statuslist, 2);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status->status);
Packit Service 20376f
	cl_assert_equal_s("modified_file", status->head_to_index->old_file.path);
Packit Service 20376f
	cl_assert(!git_oid_equal(&zero_id, &status->head_to_index->old_file.id));
Packit Service 20376f
	cl_assert(0 != status->head_to_index->old_file.mode);
Packit Service 20376f
	cl_assert_equal_s("modified_file", status->head_to_index->new_file.path);
Packit Service 20376f
	cl_assert_equal_oid(&zero_id, &status->head_to_index->new_file.id);
Packit Service 20376f
	cl_assert_equal_i(0, status->head_to_index->new_file.mode);
Packit Service 20376f
	cl_assert_equal_i(0, status->head_to_index->new_file.size);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_s("modified_file", status->index_to_workdir->old_file.path);
Packit Service 20376f
	cl_assert_equal_oid(&zero_id, &status->index_to_workdir->old_file.id);
Packit Service 20376f
	cl_assert_equal_i(0, status->index_to_workdir->old_file.mode);
Packit Service 20376f
	cl_assert_equal_i(0, status->index_to_workdir->old_file.size);
Packit Service 20376f
	cl_assert_equal_s("modified_file", status->index_to_workdir->new_file.path);
Packit Service 20376f
	cl_assert(
Packit Service 20376f
		!git_oid_equal(&zero_id, &status->index_to_workdir->new_file.id) ||
Packit Service 20376f
		!(status->index_to_workdir->new_file.flags & GIT_DIFF_FLAG_VALID_ID));
Packit Service 20376f
	cl_assert(0 != status->index_to_workdir->new_file.mode);
Packit Service 20376f
	cl_assert(0 != status->index_to_workdir->new_file.size);
Packit Service 20376f
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
	git_status_list_free(statuslist);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void assert_ignore_case(
Packit Service 20376f
	bool should_ignore_case,
Packit Service 20376f
	int expected_lower_cased_file_status,
Packit Service 20376f
	int expected_camel_cased_file_status)
Packit Service 20376f
{
Packit Service 20376f
	unsigned int status;
Packit Service 20376f
	git_buf lower_case_path = GIT_BUF_INIT, camel_case_path = GIT_BUF_INIT;
Packit Service 20376f
	git_repository *repo, *repo2;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
	cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt");
Packit Service 20376f
Packit Service 20376f
	cl_repo_set_bool(repo, "core.ignorecase", should_ignore_case);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&lower_case_path,
Packit Service 20376f
		git_repository_workdir(repo), "plop"));
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile(git_buf_cstr(&lower_case_path), "");
Packit Service 20376f
Packit Service 20376f
	stage_and_commit(repo, "plop");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_open(&repo2, "./empty_standard_repo"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo2, "plop"));
Packit Service 20376f
	cl_assert_equal_i(GIT_STATUS_CURRENT, status);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_buf_joinpath(&camel_case_path,
Packit Service 20376f
		git_repository_workdir(repo), "Plop"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(p_rename(git_buf_cstr(&lower_case_path), git_buf_cstr(&camel_case_path)));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo2, "plop"));
Packit Service 20376f
	cl_assert_equal_i(expected_lower_cased_file_status, status);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_file(&status, repo2, "Plop"));
Packit Service 20376f
	cl_assert_equal_i(expected_camel_cased_file_status, status);
Packit Service 20376f
Packit Service 20376f
	git_repository_free(repo2);
Packit Service 20376f
	git_buf_free(&lower_case_path);
Packit Service 20376f
	git_buf_free(&camel_case_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__file_status_honors_core_ignorecase_true(void)
Packit Service 20376f
{
Packit Service 20376f
	assert_ignore_case(true, GIT_STATUS_CURRENT, GIT_STATUS_CURRENT);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__file_status_honors_core_ignorecase_false(void)
Packit Service 20376f
{
Packit Service 20376f
	assert_ignore_case(false, GIT_STATUS_WT_DELETED, GIT_STATUS_WT_NEW);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__file_status_honors_case_ignorecase_regarding_untracked_files(void)
Packit Service 20376f
{
Packit Service 20376f
    git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
    unsigned int status;
Packit Service 20376f
    git_index *index;
Packit Service 20376f
Packit Service 20376f
    cl_repo_set_bool(repo, "core.ignorecase", false);
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_reopen();
Packit Service 20376f
Packit Service 20376f
    /* Actually returns GIT_STATUS_IGNORED on Windows */
Packit Service 20376f
    cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
Packit Service 20376f
Packit Service 20376f
    cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
Packit Service 20376f
    cl_git_pass(git_index_add_bypath(index, "new_file"));
Packit Service 20376f
    cl_git_pass(git_index_write(index));
Packit Service 20376f
    git_index_free(index);
Packit Service 20376f
Packit Service 20376f
    /* Actually returns GIT_STATUS_IGNORED on Windows */
Packit Service 20376f
    cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__simple_delete(void)
Packit Service 20376f
{
Packit Service 20376f
    git_repository *repo = cl_git_sandbox_init("renames");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	int count;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH |
Packit Service 20376f
		GIT_STATUS_OPT_EXCLUDE_SUBMODULES |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	count = 0;
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__count, &count) );
Packit Service 20376f
	cl_assert_equal_i(0, count);
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_unlink("renames/untimely.txt"));
Packit Service 20376f
Packit Service 20376f
	count = 0;
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__count, &count) );
Packit Service 20376f
	cl_assert_equal_i(1, count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__simple_delete_indexed(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("renames");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	git_status_list *status;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH |
Packit Service 20376f
		GIT_STATUS_OPT_EXCLUDE_SUBMODULES |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, &opts));
Packit Service 20376f
	cl_assert_equal_sz(0, git_status_list_entrycount(status));
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_unlink("renames/untimely.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, &opts));
Packit Service 20376f
	cl_assert_equal_sz(1, git_status_list_entrycount(status));
Packit Service 20376f
	cl_assert_equal_i(
Packit Service 20376f
		GIT_STATUS_WT_DELETED, git_status_byindex(status, 0)->status);
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static const char *icase_paths[] = { "B", "c", "g", "H" };
Packit Service 20376f
static unsigned int icase_statuses[] = {
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static const char *case_paths[] = { "B", "H", "c", "g" };
Packit Service 20376f
static unsigned int case_statuses[] = {
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
Packit Service 20376f
	GIT_STATUS_WT_DELETED, GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__sorting_by_case(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("icase");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	bool native_ignore_case;
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	native_ignore_case =
Packit Service 20376f
		(git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0, sizeof(counts));
Packit Service 20376f
	counts.expected_entry_count = 0;
Packit Service 20376f
	counts.expected_paths = NULL;
Packit Service 20376f
	counts.expected_statuses = NULL;
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("icase/B", "new stuff");
Packit Service 20376f
	cl_must_pass(p_unlink("icase/c"));
Packit Service 20376f
	cl_git_rewritefile("icase/g", "new stuff");
Packit Service 20376f
	cl_must_pass(p_unlink("icase/H"));
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0, sizeof(counts));
Packit Service 20376f
	counts.expected_entry_count = 4;
Packit Service 20376f
	if (native_ignore_case) {
Packit Service 20376f
		counts.expected_paths = icase_paths;
Packit Service 20376f
		counts.expected_statuses = icase_statuses;
Packit Service 20376f
	} else {
Packit Service 20376f
		counts.expected_paths = case_paths;
Packit Service 20376f
		counts.expected_statuses = case_statuses;
Packit Service 20376f
	}
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0, sizeof(counts));
Packit Service 20376f
	counts.expected_entry_count = 4;
Packit Service 20376f
	counts.expected_paths = case_paths;
Packit Service 20376f
	counts.expected_statuses = case_statuses;
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY;
Packit Service 20376f
Packit Service 20376f
	memset(&counts, 0, sizeof(counts));
Packit Service 20376f
	counts.expected_entry_count = 4;
Packit Service 20376f
	counts.expected_paths = icase_paths;
Packit Service 20376f
	counts.expected_statuses = icase_statuses;
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__long_filenames(void)
Packit Service 20376f
{
Packit Service 20376f
	char path[260*4+1];
Packit Service 20376f
	const char *expected_paths[] = {path};
Packit Service 20376f
	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
Packit Service 20376f
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts = {0};
Packit Service 20376f
Packit Service 20376f
	// Create directory with amazingly long filename
Packit Service 20376f
	sprintf(path, "empty_standard_repo/%s", longname);
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r(path, 0777));
Packit Service 20376f
	sprintf(path, "empty_standard_repo/%s/foo", longname);
Packit Service 20376f
	cl_git_mkfile(path, "dummy");
Packit Service 20376f
Packit Service 20376f
	sprintf(path, "%s/foo", longname);
Packit Service 20376f
	counts.expected_entry_count = 1;
Packit Service 20376f
	counts.expected_paths = expected_paths;
Packit Service 20376f
	counts.expected_statuses = expected_statuses;
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* The update stat cache tests mostly just mirror other tests and try
Packit Service 20376f
 * to make sure that updating the stat cache doesn't change the results
Packit Service 20376f
 * while reducing the amount of work that needs to be done
Packit Service 20376f
 */
Packit Service 20376f
Packit Service 20376f
static void check_status0(git_status_list *status)
Packit Service 20376f
{
Packit Service 20376f
	size_t i, max_i = git_status_list_entrycount(status);
Packit Service 20376f
	cl_assert_equal_sz(entry_count0, max_i);
Packit Service 20376f
	for (i = 0; i < max_i; ++i) {
Packit Service 20376f
		const git_status_entry *entry = git_status_byindex(status, i);
Packit Service 20376f
		cl_assert_equal_i(entry_statuses0[i], entry->status);
Packit Service 20376f
	}
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__update_stat_cache_0(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("status");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	git_status_list *status;
Packit Service 20376f
	git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
Packit Service 20376f
	git_index *index;
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, &opts));
Packit Service 20376f
	check_status0(status);
Packit Service 20376f
	cl_git_pass(git_status_list_get_perfdata(&perf, status));
Packit Service 20376f
	cl_assert_equal_sz(13 + 3, perf.stat_calls);
Packit Service 20376f
	cl_assert_equal_sz(5, perf.oid_calculations);
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
Packit Service 20376f
	/* tick the index so we avoid recalculating racily-clean entries */
Packit Service 20376f
	cl_git_pass(git_repository_index__weakptr(&index, repo));
Packit Service 20376f
	tick_index(index);
Packit Service 20376f
Packit Service 20376f
	opts.flags |= GIT_STATUS_OPT_UPDATE_INDEX;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, &opts));
Packit Service 20376f
	check_status0(status);
Packit Service 20376f
	cl_git_pass(git_status_list_get_perfdata(&perf, status));
Packit Service 20376f
	cl_assert_equal_sz(13 + 3, perf.stat_calls);
Packit Service 20376f
	cl_assert_equal_sz(5, perf.oid_calculations);
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
Packit Service 20376f
	opts.flags &= ~GIT_STATUS_OPT_UPDATE_INDEX;
Packit Service 20376f
Packit Service 20376f
	/* tick again as the index updating from the previous diff might have reset the timestamp */
Packit Service 20376f
	tick_index(index);
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, &opts));
Packit Service 20376f
	check_status0(status);
Packit Service 20376f
	cl_git_pass(git_status_list_get_perfdata(&perf, status));
Packit Service 20376f
	cl_assert_equal_sz(13 + 3, perf.stat_calls);
Packit Service 20376f
	cl_assert_equal_sz(0, perf.oid_calculations);
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__unreadable(void)
Packit Service 20376f
{
Packit Service 20376f
#ifndef GIT_WIN32
Packit Service 20376f
	const char *expected_paths[] = { "no_permission/foo" };
Packit Service 20376f
	const unsigned int expected_statuses[] = {GIT_STATUS_WT_UNREADABLE};
Packit Service 20376f
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts = {0};
Packit Service 20376f
Packit Service 20376f
	if (geteuid() == 0)
Packit Service 20376f
		cl_skip();
Packit Service 20376f
Packit Service 20376f
	/* Create directory with no read permission */
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", 0777));
Packit Service 20376f
	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0644);
Packit Service 20376f
Packit Service 20376f
	counts.expected_entry_count = 1;
Packit Service 20376f
	counts.expected_paths = expected_paths;
Packit Service 20376f
	counts.expected_statuses = expected_statuses;
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_INCLUDE_UNREADABLE;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
Packit Service 20376f
Packit Service 20376f
	/* Restore permissions so we can cleanup :) */
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0777);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
#else
Packit Service 20376f
	cl_skip();
Packit Service 20376f
#endif
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__unreadable_not_included(void)
Packit Service 20376f
{
Packit Service 20376f
#ifndef GIT_WIN32
Packit Service 20376f
	const char *expected_paths[] = { "no_permission/" };
Packit Service 20376f
	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
Packit Service 20376f
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts = {0};
Packit Service 20376f
Packit Service 20376f
	/* Create directory with no read permission */
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", 0777));
Packit Service 20376f
	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0644);
Packit Service 20376f
Packit Service 20376f
	counts.expected_entry_count = 1;
Packit Service 20376f
	counts.expected_paths = expected_paths;
Packit Service 20376f
	counts.expected_statuses = expected_statuses;
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
Packit Service 20376f
	opts.flags = (GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_INCLUDE_UNTRACKED);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
Packit Service 20376f
Packit Service 20376f
	/* Restore permissions so we can cleanup :) */
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0777);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
#else
Packit Service 20376f
	cl_skip();
Packit Service 20376f
#endif
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__unreadable_as_untracked(void)
Packit Service 20376f
{
Packit Service 20376f
	const char *expected_paths[] = { "no_permission/foo" };
Packit Service 20376f
	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
Packit Service 20376f
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts = {0};
Packit Service 20376f
Packit Service 20376f
	/* Create directory with no read permission */
Packit Service 20376f
	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", 0777));
Packit Service 20376f
	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0644);
Packit Service 20376f
Packit Service 20376f
	counts.expected_entry_count = 1;
Packit Service 20376f
	counts.expected_paths = expected_paths;
Packit Service 20376f
	counts.expected_statuses = expected_statuses;
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNREADABLE |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
Packit Service 20376f
Packit Service 20376f
	/* Restore permissions so we can cleanup :) */
Packit Service 20376f
	p_chmod("empty_standard_repo/no_permission", 0777);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_status_flags_count);
Packit Service 20376f
	cl_assert_equal_i(0, counts.wrong_sorted_path);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__update_index_with_symlink_doesnt_change_mode(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("testrepo");
Packit Service 20376f
	git_reference *head;
Packit Service 20376f
	git_object *head_object;
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	const git_index_entry *idx_entry;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts = {0};
Packit Service 20376f
	const char *expected_paths[] = { "README" };
Packit Service 20376f
	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_UPDATE_INDEX;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_head(&head, repo));
Packit Service 20376f
	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("testrepo/README", "This was rewritten.");
Packit Service 20376f
Packit Service 20376f
	/* this status rewrites the index because we have changed the
Packit Service 20376f
	 * contents of a tracked file
Packit Service 20376f
	 */
Packit Service 20376f
	counts.expected_entry_count = 1;
Packit Service 20376f
	counts.expected_paths = expected_paths;
Packit Service 20376f
	counts.expected_statuses = expected_statuses;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
Packit Service 20376f
	cl_assert_equal_i(1, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* now ensure that the status's rewrite of the index did not screw
Packit Service 20376f
	 * up the mode of the symlink `link_to_new.txt`, particularly
Packit Service 20376f
	 * on platforms that don't support symlinks
Packit Service 20376f
	 */
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	cl_git_pass(git_index_read(index, true));
Packit Service 20376f
Packit Service 20376f
	cl_assert(idx_entry = git_index_get_bypath(index, "link_to_new.txt", 0));
Packit Service 20376f
	cl_assert(S_ISLNK(idx_entry->mode));
Packit Service 20376f
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
	git_object_free(head_object);
Packit Service 20376f
	git_reference_free(head);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static const char *testrepo2_subdir_paths[] = {
Packit Service 20376f
		"subdir/README",
Packit Service 20376f
		"subdir/new.txt",
Packit Service 20376f
		"subdir/subdir2/README",
Packit Service 20376f
		"subdir/subdir2/new.txt",
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static const char *testrepo2_subdir_paths_icase[] = {
Packit Service 20376f
		"subdir/new.txt",
Packit Service 20376f
		"subdir/README",
Packit Service 20376f
		"subdir/subdir2/new.txt",
Packit Service 20376f
		"subdir/subdir2/README"
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
void test_status_worktree__with_directory_in_pathlist(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo = cl_git_sandbox_init("testrepo2");
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	git_status_list *statuslist;
Packit Service 20376f
	const git_status_entry *status;
Packit Service 20376f
	size_t i, entrycount;
Packit Service 20376f
	bool native_ignore_case;
Packit Service 20376f
	char *subdir_path = "subdir";
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_index(&index, repo));
Packit Service 20376f
	native_ignore_case =
Packit Service 20376f
			(git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
Packit Service 20376f
	opts.pathspec.strings = &subdir_path;
Packit Service 20376f
	opts.pathspec.count = 1;
Packit Service 20376f
	opts.flags =
Packit Service 20376f
			GIT_STATUS_OPT_DEFAULTS |
Packit Service 20376f
			GIT_STATUS_OPT_INCLUDE_UNMODIFIED |
Packit Service 20376f
			GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
Packit Service 20376f
	git_status_list_new(&statuslist, repo, &opts);
Packit Service 20376f
Packit Service 20376f
	entrycount = git_status_list_entrycount(statuslist);
Packit Service 20376f
	cl_assert_equal_i(4, entrycount);
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < entrycount; i++) {
Packit Service 20376f
		status = git_status_byindex(statuslist, i);
Packit Service 20376f
		cl_assert_equal_i(0, status->status);
Packit Service 20376f
		cl_assert_equal_s(native_ignore_case ?
Packit Service 20376f
			testrepo2_subdir_paths_icase[i] :
Packit Service 20376f
			testrepo2_subdir_paths[i],
Packit Service 20376f
			status->index_to_workdir->old_file.path);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(statuslist);
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_INDEX_ONLY;
Packit Service 20376f
	git_status_list_new(&statuslist, repo, &opts);
Packit Service 20376f
Packit Service 20376f
	entrycount = git_status_list_entrycount(statuslist);
Packit Service 20376f
	cl_assert_equal_i(4, entrycount);
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < entrycount; i++) {
Packit Service 20376f
		status = git_status_byindex(statuslist, i);
Packit Service 20376f
		cl_assert_equal_i(0, status->status);
Packit Service 20376f
		cl_assert_equal_s(native_ignore_case ?
Packit Service 20376f
			testrepo2_subdir_paths_icase[i] :
Packit Service 20376f
			testrepo2_subdir_paths[i],
Packit Service 20376f
			status->head_to_index->old_file.path);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(statuslist);
Packit Service 20376f
Packit Service 20376f
	opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
Packit Service 20376f
	git_status_list_new(&statuslist, repo, &opts);
Packit Service 20376f
Packit Service 20376f
	entrycount = git_status_list_entrycount(statuslist);
Packit Service 20376f
	cl_assert_equal_i(4, entrycount);
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < entrycount; i++) {
Packit Service 20376f
		status = git_status_byindex(statuslist, i);
Packit Service 20376f
		cl_assert_equal_i(0, status->status);
Packit Service 20376f
		cl_assert_equal_s(native_ignore_case ?
Packit Service 20376f
			testrepo2_subdir_paths_icase[i] :
Packit Service 20376f
			testrepo2_subdir_paths[i],
Packit Service 20376f
			status->index_to_workdir->old_file.path);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(statuslist);
Packit Service 20376f
}
Packit Service 20376f