Blame tests/status/submodules.c

Packit Service 20376f
#include "clar_libgit2.h"
Packit Service 20376f
#include "fileops.h"
Packit Service 20376f
#include "status_helpers.h"
Packit Service 20376f
#include "../submodule/submodule_helpers.h"
Packit Service 20376f
Packit Service 20376f
static git_repository *g_repo = NULL;
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__initialize(void)
Packit Service 20376f
{
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__cleanup(void)
Packit Service 20376f
{
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__api(void)
Packit Service 20376f
{
Packit Service 20376f
	git_submodule *sm;
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	cl_assert(git_submodule_lookup(NULL, g_repo, "nonexistent") == GIT_ENOTFOUND);
Packit Service 20376f
Packit Service 20376f
	cl_assert(git_submodule_lookup(NULL, g_repo, "modified") == GIT_ENOTFOUND);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
Packit Service 20376f
	cl_assert(sm != NULL);
Packit Service 20376f
	cl_assert_equal_s("testrepo", git_submodule_name(sm));
Packit Service 20376f
	cl_assert_equal_s("testrepo", git_submodule_path(sm));
Packit Service 20376f
	git_submodule_free(sm);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__0(void)
Packit Service 20376f
{
Packit Service 20376f
	int counts = 0;
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	cl_assert(git_path_isdir("submodules/.git"));
Packit Service 20376f
	cl_assert(git_path_isdir("submodules/testrepo/.git"));
Packit Service 20376f
	cl_assert(git_path_isfile("submodules/.gitmodules"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach(g_repo, cb_status__count, &counts)
Packit Service 20376f
	);
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(6, counts);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static const char *expected_files[] = {
Packit Service 20376f
	".gitmodules",
Packit Service 20376f
	"added",
Packit Service 20376f
	"deleted",
Packit Service 20376f
	"ignored",
Packit Service 20376f
	"modified",
Packit Service 20376f
	"untracked"
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static unsigned int expected_status[] = {
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
	GIT_STATUS_INDEX_NEW,
Packit Service 20376f
	GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
	GIT_STATUS_IGNORED,
Packit Service 20376f
	GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
	GIT_STATUS_WT_NEW
Packit Service 20376f
};
Packit Service 20376f
Packit Service 20376f
static int cb_status__match(const char *p, unsigned int s, void *payload)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts *counts = payload;
Packit Service 20376f
	int idx = counts->entry_count++;
Packit Service 20376f
Packit Service 20376f
	clar__assert_equal(
Packit Service 20376f
		counts->file, counts->line,
Packit Service 20376f
		"Status path mismatch", 1,
Packit Service 20376f
		"%s", counts->expected_paths[idx], p);
Packit Service 20376f
Packit Service 20376f
	clar__assert_equal(
Packit Service 20376f
		counts->file, counts->line,
Packit Service 20376f
		"Status code mismatch", 1,
Packit Service 20376f
		"%o", counts->expected_statuses[idx], s);
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__1(void)
Packit Service 20376f
{
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	cl_assert(git_path_isdir("submodules/.git"));
Packit Service 20376f
	cl_assert(git_path_isdir("submodules/testrepo/.git"));
Packit Service 20376f
	cl_assert(git_path_isfile("submodules/.gitmodules"));
Packit Service 20376f
Packit Service 20376f
	status_counts_init(counts, expected_files, expected_status);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass( git_status_foreach(g_repo, cb_status__match, &counts) );
Packit Service 20376f
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__single_file(void)
Packit Service 20376f
{
Packit Service 20376f
	unsigned int status = 0;
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
	cl_git_pass( git_status_file(&status, g_repo, "testrepo") );
Packit Service 20376f
	cl_assert(!status);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__moved_head(void)
Packit Service 20376f
{
Packit Service 20376f
	git_submodule *sm;
Packit Service 20376f
	git_repository *smrepo;
Packit Service 20376f
	git_oid oid;
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	static const char *expected_files_with_sub[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"ignored",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"testrepo",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static unsigned int expected_status_with_sub[] = {
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
		GIT_STATUS_IGNORED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_NEW
Packit Service 20376f
	};
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
Packit Service 20376f
	cl_git_pass(git_submodule_open(&smrepo, sm));
Packit Service 20376f
	git_submodule_free(sm);
Packit Service 20376f
Packit Service 20376f
	/* move submodule HEAD to c47800c7266a2be04c571c04d5a6614691ea99bd */
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
Packit Service 20376f
	cl_git_pass(git_repository_set_head_detached(smrepo, &oid));
Packit Service 20376f
Packit Service 20376f
	/* first do a normal status, which should now include the submodule */
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_sub, expected_status_with_sub);
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* try again with EXCLUDE_SUBMODULES which should skip it */
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(counts, expected_files, expected_status);
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	git_repository_free(smrepo);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__dirty_workdir_only(void)
Packit Service 20376f
{
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	static const char *expected_files_with_sub[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"ignored",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"testrepo",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static unsigned int expected_status_with_sub[] = {
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
		GIT_STATUS_IGNORED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_NEW
Packit Service 20376f
	};
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
Packit Service 20376f
	cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
Packit Service 20376f
Packit Service 20376f
	/* first do a normal status, which should now include the submodule */
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_sub, expected_status_with_sub);
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* try again with EXCLUDE_SUBMODULES which should skip it */
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(counts, expected_files, expected_status);
Packit Service 20376f
	cl_git_pass(
Packit Service 20376f
		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__uninitialized(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *cloned_repo;
Packit Service 20376f
	git_status_list *statuslist;
Packit Service 20376f
Packit Service 20376f
	g_repo = cl_git_sandbox_init("submod2");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_clone(&cloned_repo, "submod2", "submod2-clone", NULL));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&statuslist, cloned_repo, NULL));
Packit Service 20376f
	cl_assert_equal_i(0, git_status_list_entrycount(statuslist));
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(statuslist);
Packit Service 20376f
	git_repository_free(cloned_repo);
Packit Service 20376f
	cl_git_sandbox_cleanup();
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__contained_untracked_repo(void)
Packit Service 20376f
{
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *contained;
Packit Service 20376f
	static const char *expected_files_not_ignored[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static unsigned int expected_status_not_ignored[] = {
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_NEW,
Packit Service 20376f
	};
Packit Service 20376f
	static const char *expected_files_with_untracked[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"dir/file.md",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static const char *expected_files_with_untracked_dir[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"dir/",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static unsigned int expected_status_with_untracked[] = {
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
		GIT_STATUS_WT_NEW,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_NEW
Packit Service 20376f
	};
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
Packit Service 20376f
Packit Service 20376f
	/* skip empty directory */
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("submodules/dir", 0777));
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_not_ignored, expected_status_not_ignored);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(5, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* still skipping because empty == ignored */
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
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_not_ignored, expected_status_not_ignored);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(5, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* find non-ignored contents of directory */
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile("submodules/dir/file.md", "hello");
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_untracked, expected_status_with_untracked);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* but skip if all content is ignored */
Packit Service 20376f
Packit Service 20376f
	cl_git_append2file("submodules/.git/info/exclude", "\n*.md\n\n");
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_not_ignored, expected_status_not_ignored);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(5, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* same is true if it contains a git link */
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile("submodules/dir/.git", "gitlink: ../.git");
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_not_ignored, expected_status_not_ignored);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(5, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* but if it contains tracked files, it should just show up as a
Packit Service 20376f
	 * directory and exclude the files in it
Packit Service 20376f
	 */
Packit Service 20376f
Packit Service 20376f
	cl_git_mkfile("submodules/dir/another_file", "hello");
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_untracked_dir,
Packit Service 20376f
		expected_status_with_untracked);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* that applies to a git repo with a .git directory too */
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_unlink("submodules/dir/.git"));
Packit Service 20376f
	cl_git_pass(git_repository_init(&contained, "submodules/dir", false));
Packit Service 20376f
	git_repository_free(contained);
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_untracked_dir,
Packit Service 20376f
		expected_status_with_untracked);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* same result even if we don't recurse into subdirectories */
Packit Service 20376f
Packit Service 20376f
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_untracked_dir,
Packit Service 20376f
		expected_status_with_untracked);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(6, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* and if we remove the untracked file, it goes back to ignored */
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_unlink("submodules/dir/another_file"));
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_not_ignored, expected_status_not_ignored);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(5, counts.entry_count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__broken_stuff_that_git_allows(void)
Packit Service 20376f
{
Packit Service 20376f
	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	status_entry_counts counts;
Packit Service 20376f
	git_repository *contained;
Packit Service 20376f
	static const char *expected_files_with_broken[] = {
Packit Service 20376f
		".gitmodules",
Packit Service 20376f
		"added",
Packit Service 20376f
		"broken/tracked",
Packit Service 20376f
		"deleted",
Packit Service 20376f
		"ignored",
Packit Service 20376f
		"modified",
Packit Service 20376f
		"untracked"
Packit Service 20376f
	};
Packit Service 20376f
	static unsigned int expected_status_with_broken[] = {
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_NEW,
Packit Service 20376f
		GIT_STATUS_INDEX_DELETED,
Packit Service 20376f
		GIT_STATUS_IGNORED,
Packit Service 20376f
		GIT_STATUS_WT_MODIFIED,
Packit Service 20376f
		GIT_STATUS_WT_NEW,
Packit Service 20376f
	};
Packit Service 20376f
Packit Service 20376f
	g_repo = setup_fixture_submodules();
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_INCLUDE_IGNORED;
Packit Service 20376f
Packit Service 20376f
	/* make a directory and stick a tracked item into the index */
Packit Service 20376f
	{
Packit Service 20376f
		git_index *idx;
Packit Service 20376f
		cl_must_pass(p_mkdir("submodules/broken", 0777));
Packit Service 20376f
		cl_git_mkfile("submodules/broken/tracked", "tracked content");
Packit Service 20376f
		cl_git_pass(git_repository_index(&idx, g_repo));
Packit Service 20376f
		cl_git_pass(git_index_add_bypath(idx, "broken/tracked"));
Packit Service 20376f
		cl_git_pass(git_index_write(idx));
Packit Service 20376f
		git_index_free(idx);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_broken, expected_status_with_broken);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* directory with tracked items that looks a little bit like a repo */
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("submodules/broken/.git", 0777));
Packit Service 20376f
	cl_must_pass(p_mkdir("submodules/broken/.git/info", 0777));
Packit Service 20376f
	cl_git_mkfile("submodules/broken/.git/info/exclude", "# bogus");
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_broken, expected_status_with_broken);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* directory with tracked items that is a repo */
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_futils_rmdir_r(
Packit Service 20376f
		"submodules/broken/.git", NULL, GIT_RMDIR_REMOVE_FILES));
Packit Service 20376f
	cl_git_pass(git_repository_init(&contained, "submodules/broken", false));
Packit Service 20376f
	git_repository_free(contained);
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_broken, expected_status_with_broken);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
Packit Service 20376f
	/* directory with tracked items that claims to be a submodule but is not */
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_futils_rmdir_r(
Packit Service 20376f
		"submodules/broken/.git", NULL, GIT_RMDIR_REMOVE_FILES));
Packit Service 20376f
	cl_git_append2file("submodules/.gitmodules",
Packit Service 20376f
		"\n[submodule \"broken\"]\n"
Packit Service 20376f
		"\tpath = broken\n"
Packit Service 20376f
		"\turl = https://github.com/not/used\n\n");
Packit Service 20376f
Packit Service 20376f
	status_counts_init(
Packit Service 20376f
		counts, expected_files_with_broken, expected_status_with_broken);
Packit Service 20376f
	cl_git_pass(git_status_foreach_ext(
Packit Service 20376f
		g_repo, &opts, cb_status__match, &counts));
Packit Service 20376f
	cl_assert_equal_i(7, counts.entry_count);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__entry_but_dir_tracked(void)
Packit Service 20376f
{
Packit Service 20376f
	git_repository *repo;
Packit Service 20376f
	git_status_list *status;
Packit Service 20376f
	git_diff *diff;
Packit Service 20376f
	git_index *index;
Packit Service 20376f
	git_tree *tree;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_init(&repo, "mixed-submodule", 0));
Packit Service 20376f
	cl_git_mkfile("mixed-submodule/.gitmodules", "[submodule \"sub\"]\n path = sub\n url = ../foo\n");
Packit Service 20376f
	cl_git_pass(p_mkdir("mixed-submodule/sub", 0777));
Packit Service 20376f
	cl_git_mkfile("mixed-submodule/sub/file", "");
Packit Service 20376f
Packit Service 20376f
	/* Create the commit with sub/file as a file, and an entry for sub in the modules list */
Packit Service 20376f
	{
Packit Service 20376f
		git_oid tree_id, commit_id;
Packit Service 20376f
		git_signature *sig;
Packit Service 20376f
		git_reference *ref;
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, ".gitmodules"));
Packit Service 20376f
		cl_git_pass(git_index_add_bypath(index, "sub/file"));
Packit Service 20376f
		cl_git_pass(git_index_write(index));
Packit Service 20376f
		cl_git_pass(git_index_write_tree(&tree_id, index));
Packit Service 20376f
		cl_git_pass(git_signature_now(&sig, "Sloppy Submoduler", "sloppy@example.com"));
Packit Service 20376f
		cl_git_pass(git_tree_lookup(&tree, repo, &tree_id));
Packit Service 20376f
		cl_git_pass(git_commit_create(&commit_id, repo, NULL, sig, sig, NULL, "message", tree, 0, NULL));
Packit Service 20376f
		cl_git_pass(git_reference_create(&ref, repo, "refs/heads/master", &commit_id, 1, "commit: foo"));
Packit Service 20376f
		git_reference_free(ref);
Packit Service 20376f
		git_signature_free(sig);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_diff_tree_to_index(&diff, repo, tree, index, NULL));
Packit Service 20376f
	cl_assert_equal_i(0, git_diff_num_deltas(diff));
Packit Service 20376f
	git_diff_free(diff);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_diff_index_to_workdir(&diff, repo, index, NULL));
Packit Service 20376f
	cl_assert_equal_i(0, git_diff_num_deltas(diff));
Packit Service 20376f
	git_diff_free(diff);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, repo, NULL));
Packit Service 20376f
	cl_assert_equal_i(0, git_status_list_entrycount(status));
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
	git_index_free(index);
Packit Service 20376f
	git_tree_free(tree);
Packit Service 20376f
	git_repository_free(repo);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_status_submodules__mixed_case(void)
Packit Service 20376f
{
Packit Service 20376f
	git_status_list *status;
Packit Service 20376f
	git_status_options status_opts = GIT_STATUS_OPTIONS_INIT;
Packit Service 20376f
	const git_status_entry *s;
Packit Service 20376f
	size_t i;
Packit Service 20376f
Packit Service 20376f
	status_opts.flags =
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNTRACKED |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_IGNORED |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNMODIFIED |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
Packit Service 20376f
		GIT_STATUS_OPT_RECURSE_IGNORED_DIRS |
Packit Service 20376f
		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
Packit Service 20376f
		GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR |
Packit Service 20376f
		GIT_STATUS_OPT_RENAMES_FROM_REWRITES |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNREADABLE |
Packit Service 20376f
		GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED;
Packit Service 20376f
Packit Service 20376f
    g_repo = setup_fixture_submod3();
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_status_list_new(&status, g_repo, &status_opts));
Packit Service 20376f
Packit Service 20376f
	for (i = 0; i < git_status_list_entrycount(status); i++) {
Packit Service 20376f
		s = git_status_byindex(status, i);
Packit Service 20376f
Packit Service 20376f
		if (s->head_to_index &&
Packit Service 20376f
			strcmp(s->head_to_index->old_file.path, ".gitmodules") == 0)
Packit Service 20376f
			continue;
Packit Service 20376f
Packit Service 20376f
		cl_assert_equal_i(0, s->status);
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	git_status_list_free(status);
Packit Service 20376f
}
Packit Service 20376f