summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/index.c4
-rw-r--r--tests/submodule/lookup.c91
-rw-r--r--tests/submodule/submodule_helpers.c36
-rw-r--r--tests/submodule/submodule_helpers.h15
4 files changed, 132 insertions, 14 deletions
diff --git a/src/index.c b/src/index.c
index 6cc8ea1a3..24e447928 100644
--- a/src/index.c
+++ b/src/index.c
@@ -524,7 +524,9 @@ int git_index__changed_relative_to(
if (git_index_read(index, false) < 0)
giterr_clear();
- return (memcmp(&index->stamp, fs, sizeof(index->stamp)) == 0);
+ return (index->stamp.mtime != fs->mtime ||
+ index->stamp.size != fs->size ||
+ index->stamp.ino != fs->ino);
}
int git_index_write(git_index *index)
diff --git a/tests/submodule/lookup.c b/tests/submodule/lookup.c
index 86ba25c3a..34de5923e 100644
--- a/tests/submodule/lookup.c
+++ b/tests/submodule/lookup.c
@@ -130,18 +130,63 @@ void test_submodule_lookup__lookup_even_with_missing_index(void)
test_submodule_lookup__simple_lookup(); /* baseline should still pass */
}
+static void baseline_tests(void)
+{
+ /* small baseline that should work even if we change the index or make
+ * commits from the index
+ */
+ assert_submodule_exists(g_repo, "sm_unchanged");
+ assert_submodule_exists(g_repo, "sm_gitmodules_only");
+ refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+}
+
+static void add_submodule_with_commit(const char *name)
+{
+ git_submodule *sm;
+ git_repository *smrepo;
+ git_index *idx;
+ git_buf p = GIT_BUF_INIT;
+
+ cl_git_pass(git_submodule_add_setup(&sm, g_repo,
+ "https://github.com/libgit2/libgit2.git", name, 1));
+
+ assert_submodule_exists(g_repo, name);
+
+ cl_git_pass(git_submodule_open(&smrepo, sm));
+ cl_git_pass(git_repository_index(&idx, smrepo));
+
+ cl_git_pass(git_buf_joinpath(&p, git_repository_workdir(smrepo), "file"));
+ cl_git_mkfile(p.ptr, "new file");
+ git_buf_free(&p);
+
+ cl_git_pass(git_index_add_bypath(idx, "file"));
+ cl_git_pass(git_index_write(idx));
+ git_index_free(idx);
+
+ cl_repo_commit_from_index(NULL, smrepo, NULL, 0, "initial commit");
+ git_repository_free(smrepo);
+
+ cl_git_pass(git_submodule_add_finalize(sm));
+
+ git_submodule_free(sm);
+}
+
void test_submodule_lookup__just_added(void)
{
git_submodule *sm;
git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT;
+ git_reference *original_head = NULL;
refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND);
+ refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND);
+ refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
- test_submodule_lookup__simple_lookup(); /* baseline */
+ baseline_tests();
cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules"));
+ cl_git_pass(git_repository_head(&original_head, g_repo));
cl_git_pass(git_submodule_add_setup(&sm, g_repo,
"https://github.com/libgit2/libgit2.git", "sm_just_added", 1));
@@ -151,8 +196,16 @@ void test_submodule_lookup__just_added(void)
cl_git_pass(git_submodule_add_setup(&sm, g_repo,
"https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1));
assert_submodule_exists(g_repo, "sm_just_added_2");
+ cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */
git_submodule_free(sm);
+ add_submodule_with_commit("sm_just_added_head");
+ cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head");
+ assert_submodule_exists(g_repo, "sm_just_added_head");
+
+ add_submodule_with_commit("sm_just_added_idx");
+ assert_submodule_exists(g_repo, "sm_just_added_idx");
+
cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules"));
cl_git_append2file(
@@ -165,7 +218,9 @@ void test_submodule_lookup__just_added(void)
assert_submodule_exists(g_repo, "mismatch_path");
assert_submodule_exists(g_repo, "sm_just_added");
assert_submodule_exists(g_repo, "sm_just_added_2");
- test_submodule_lookup__simple_lookup();
+ assert_submodule_exists(g_repo, "sm_just_added_idx");
+ assert_submodule_exists(g_repo, "sm_just_added_head");
+ baseline_tests();
cl_git_rewritefile("submod2/.gitmodules", snap2.ptr);
git_buf_free(&snap2);
@@ -174,7 +229,9 @@ void test_submodule_lookup__just_added(void)
refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
assert_submodule_exists(g_repo, "sm_just_added");
assert_submodule_exists(g_repo, "sm_just_added_2");
- test_submodule_lookup__simple_lookup();
+ assert_submodule_exists(g_repo, "sm_just_added_idx");
+ assert_submodule_exists(g_repo, "sm_just_added_head");
+ baseline_tests();
cl_git_rewritefile("submod2/.gitmodules", snap1.ptr);
git_buf_free(&snap1);
@@ -184,5 +241,31 @@ void test_submodule_lookup__just_added(void)
/* note error code change, because add_setup made a repo in the workdir */
refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS);
refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS);
- test_submodule_lookup__simple_lookup();
+ /* these still exist in index and head respectively */
+ assert_submodule_exists(g_repo, "sm_just_added_idx");
+ assert_submodule_exists(g_repo, "sm_just_added_head");
+ baseline_tests();
+
+ {
+ git_index *idx;
+ cl_git_pass(git_repository_index(&idx, g_repo));
+ cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx"));
+ cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head"));
+ cl_git_pass(git_index_write(idx));
+ git_index_free(idx);
+ }
+
+ refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS);
+ assert_submodule_exists(g_repo, "sm_just_added_head");
+
+ {
+ git_signature *sig;
+ cl_git_pass(git_signature_now(&sig, "resetter", "resetter@email.com"));
+ cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, sig, "move head back"));
+ git_signature_free(sig);
+ git_reference_free(original_head);
+ }
+
+ refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS);
}
+
diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c
index 546f0913a..50aa97568 100644
--- a/tests/submodule/submodule_helpers.c
+++ b/tests/submodule/submodule_helpers.c
@@ -126,20 +126,26 @@ git_repository *setup_fixture_submod2(void)
return repo;
}
-void assert_submodule_exists(git_repository *repo, const char *name)
+void assert__submodule_exists(
+ git_repository *repo, const char *name,
+ const char *msg, const char *file, int line)
{
git_submodule *sm;
- cl_git_pass(git_submodule_lookup(&sm, repo, name));
- cl_assert(sm);
+ int error = git_submodule_lookup(&sm, repo, name);
+ if (error)
+ cl_git_report_failure(error, file, line, msg);
+ cl_assert_at_line(sm != NULL, file, line);
git_submodule_free(sm);
}
-void refute_submodule_exists(
- git_repository *repo, const char *name, int expected_error)
+void refute__submodule_exists(
+ git_repository *repo, const char *name, int expected_error,
+ const char *msg, const char *file, int line)
{
git_submodule *sm;
- cl_assert_equal_i(
- expected_error, git_submodule_lookup(&sm, repo, name));
+ clar__assert_equal(
+ file, line, msg, 1, "%i",
+ expected_error, (int)(git_submodule_lookup(&sm, repo, name)));
}
unsigned int get_submodule_status(git_repository *repo, const char *name)
@@ -154,3 +160,19 @@ unsigned int get_submodule_status(git_repository *repo, const char *name)
return status;
}
+
+static int print_submodules(git_submodule *sm, const char *name, void *p)
+{
+ unsigned int loc = 0;
+ GIT_UNUSED(p);
+ git_submodule_location(&loc, sm);
+ fprintf(stderr, "# submodule %s (at %s) flags %x\n",
+ name, git_submodule_path(sm), loc);
+ return 0;
+}
+
+void dump_submodules(git_repository *repo)
+{
+ git_submodule_foreach(repo, print_submodules, NULL);
+}
+
diff --git a/tests/submodule/submodule_helpers.h b/tests/submodule/submodule_helpers.h
index ec5510e3c..4b2620bfa 100644
--- a/tests/submodule/submodule_helpers.h
+++ b/tests/submodule/submodule_helpers.h
@@ -6,5 +6,16 @@ extern git_repository *setup_fixture_submod2(void);
extern unsigned int get_submodule_status(git_repository *, const char *);
-extern void assert_submodule_exists(git_repository *, const char *);
-extern void refute_submodule_exists(git_repository *, const char *, int err);
+extern void assert__submodule_exists(
+ git_repository *, const char *, const char *, const char *, int);
+
+#define assert_submodule_exists(repo,name) \
+ assert__submodule_exists(repo, name, "git_submodule_lookup(" #name ") failed", __FILE__, __LINE__)
+
+extern void refute__submodule_exists(
+ git_repository *, const char *, int err, const char *, const char *, int);
+
+#define refute_submodule_exists(repo,name,code) \
+ refute__submodule_exists(repo, name, code, "expected git_submodule_lookup(" #name ") to fail with error " #code, __FILE__, __LINE__)
+
+extern void dump_submodules(git_repository *repo);