summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-06-27 22:48:46 -0700
committerRussell Belfer <rb@github.com>2013-06-27 22:48:46 -0700
commitf2c41884c3082984f51743d557644cfa2136b878 (patch)
treeab8df0ec4dd40e6ffa623cb96affb1263bff3b02
parentc8a39f9ee3ce8aa73a489b72006f0e3c27cc5911 (diff)
parent1e9dd60f141cbe0c0eecf2628f7dd6f67d185b8d (diff)
downloadlibgit2-f2c41884c3082984f51743d557644cfa2136b878.tar.gz
Merge pull request #1688 from arrbee/submodule-load-ignore-orphaned-head
Test submodules with empty index or orphaned head
-rw-r--r--src/submodule.c7
-rw-r--r--tests-clar/submodule/lookup.c71
2 files changed, 76 insertions, 2 deletions
diff --git a/src/submodule.c b/src/submodule.c
index 89eba2aa4..dcd58d016 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1176,8 +1176,11 @@ static int load_submodule_config_from_head(
git_iterator *i;
const git_index_entry *entry;
- if ((error = git_repository_head_tree(&head, repo)) < 0)
- return error;
+ /* if we can't look up current head, then there's no submodule in it */
+ if (git_repository_head_tree(&head, repo) < 0) {
+ giterr_clear();
+ return 0;
+ }
if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0) {
git_tree_free(head);
diff --git a/tests-clar/submodule/lookup.c b/tests-clar/submodule/lookup.c
index acf8f6462..013bbdf96 100644
--- a/tests-clar/submodule/lookup.c
+++ b/tests-clar/submodule/lookup.c
@@ -1,6 +1,7 @@
#include "clar_libgit2.h"
#include "submodule_helpers.h"
#include "posix.h"
+#include "git2/sys/repository.h"
static git_repository *g_repo = NULL;
@@ -112,3 +113,73 @@ void test_submodule_lookup__foreach(void)
cl_git_pass(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
cl_assert_equal_i(8, data.count);
}
+
+void test_submodule_lookup__lookup_even_with_orphaned_head(void)
+{
+ git_reference *orphan;
+ git_submodule *sm;
+
+ /* orphan the head */
+ cl_git_pass(git_reference_symbolic_create(
+ &orphan, g_repo, "HEAD", "refs/heads/garbage", 1));
+ git_reference_free(orphan);
+
+ /* lookup existing */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged"));
+ cl_assert(sm);
+
+ /* lookup pending change in .gitmodules that is not in HEAD */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited"));
+ cl_assert(sm);
+
+ /* lookup pending change in .gitmodules that is neither in HEAD nor index */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only"));
+ cl_assert(sm);
+
+ /* lookup git repo subdir that is not added as submodule */
+ cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, g_repo, "not-submodule"));
+
+ /* lookup existing directory that is not a submodule */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "just_a_dir"));
+
+ /* lookup existing file that is not a submodule */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "just_a_file"));
+
+ /* lookup non-existent item */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "no_such_file"));
+}
+
+void test_submodule_lookup__lookup_even_with_missing_index(void)
+{
+ git_index *idx;
+ git_submodule *sm;
+
+ /* give the repo an empty index */
+ cl_git_pass(git_index_new(&idx));
+ git_repository_set_index(g_repo, idx);
+ git_index_free(idx);
+
+ /* lookup existing */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged"));
+ cl_assert(sm);
+
+ /* lookup pending change in .gitmodules that is not in HEAD */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited"));
+ cl_assert(sm);
+
+ /* lookup pending change in .gitmodules that is neither in HEAD nor index */
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only"));
+ cl_assert(sm);
+
+ /* lookup git repo subdir that is not added as submodule */
+ cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, g_repo, "not-submodule"));
+
+ /* lookup existing directory that is not a submodule */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "just_a_dir"));
+
+ /* lookup existing file that is not a submodule */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "just_a_file"));
+
+ /* lookup non-existent item */
+ cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, g_repo, "no_such_file"));
+}