Commit 4535f044 by Russell Belfer

More diff submodule tests for cache issues

The submodules code caches data about submodules in a way that
can cause problems.  This adds some tests that try making various
modifications to the state of a submodule to see where we can
catch out problems in the submodule caching.

Right now, I've put in an extra git_submodule_reload_all so that
the test will pass, but with that commented out, the test fails.
I'm working on fixing the broken version of the test at which
point I'll commit the fix and delete the extra reload that makes
the test pass.
parent 3e7d7100
...@@ -234,3 +234,153 @@ void test_diff_submodules__submod2_head_to_index(void) ...@@ -234,3 +234,153 @@ void test_diff_submodules__submod2_head_to_index(void)
git_tree_free(head); git_tree_free(head);
} }
void test_diff_submodules__invalid_cache(void)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
git_submodule *sm;
char *smpath = "sm_changed_head";
git_repository *smrepo;
git_index *smindex;
static const char *expected_baseline[] = {
"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
"<END>"
};
static const char *expected_unchanged[] = { "<END>" };
static const char *expected_dirty[] = {
"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247-dirty\n",
"<END>"
};
static const char *expected_moved[] = {
"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..0910a13 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 0910a13dfa2210496f6c590d75bc360dd11b2a1b\n",
"<END>"
};
static const char *expected_moved_dirty[] = {
"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..0910a13 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 0910a13dfa2210496f6c590d75bc360dd11b2a1b-dirty\n",
"<END>"
};
setup_submodules2();
opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
opts.old_prefix = "a"; opts.new_prefix = "b";
opts.pathspec.count = 1;
opts.pathspec.strings = &smpath;
/* baseline */
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_baseline);
git_diff_list_free(diff);
/* update index with new HEAD */
cl_git_pass(git_submodule_lookup(&sm, g_repo, smpath));
cl_git_pass(git_submodule_add_to_index(sm, 1));
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_list_free(diff);
/* create untracked file in submodule working directory */
cl_git_mkfile("submod2/sm_changed_head/new_around_here", "hello");
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_list_free(diff);
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_list_free(diff);
/* modify tracked file in submodule working directory */
cl_git_append2file(
"submod2/sm_changed_head/file_to_modify", "\nmore stuff\n");
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_list_free(diff);
cl_git_pass(git_submodule_reload_all(g_repo));
cl_git_pass(git_submodule_lookup(&sm, g_repo, smpath));
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_list_free(diff);
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_list_free(diff);
/* add file to index in submodule */
cl_git_pass(git_submodule_open(&smrepo, sm));
cl_git_pass(git_repository_index(&smindex, smrepo));
cl_git_pass(git_index_add_bypath(smindex, "file_to_modify"));
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_list_free(diff);
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_list_free(diff);
/* commit changed index of submodule */
{
git_object *parent;
git_oid tree_id, commit_id;
git_tree *tree;
git_signature *sig;
cl_git_pass(git_revparse_single(&parent, smrepo, "HEAD"));
cl_git_pass(git_index_write_tree(&tree_id, smindex));
cl_git_pass(git_index_write(smindex));
cl_git_pass(git_tree_lookup(&tree, smrepo, &tree_id));
cl_git_pass(git_signature_new(&sig, "Sm Test", "sm@tester.test", 1372350000, 480));
cl_git_pass(git_commit_create_v(
&commit_id, smrepo, "HEAD", sig, sig, NULL,
"Move it", tree, 1, parent));
git_object_free(parent);
git_tree_free(tree);
git_signature_free(sig);
}
/* THIS RELOAD SHOULD NOT BE REQUIRED */
cl_git_pass(git_submodule_reload_all(g_repo));
cl_git_pass(git_submodule_lookup(&sm, g_repo, smpath));
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_moved);
git_diff_list_free(diff);
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_ALL);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_list_free(diff);
git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_moved_dirty);
git_diff_list_free(diff);
p_unlink("submod2/sm_changed_head/new_around_here");
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_moved);
git_diff_list_free(diff);
git_index_free(smindex);
git_repository_free(smrepo);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment