Fix workdir iterators on empty directories Creating a workdir iterator on a directory with absolutely no files was returning an error (GIT_ENOTFOUND) instead of an iterator for nothing. This fixes that and includes two new tests that cover that case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
diff --git a/src/iterator.c b/src/iterator.c
index 40ef016..819b0e2 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -660,6 +660,8 @@ int git_iterator_for_workdir_range(
int error;
workdir_iterator *wi;
+ assert(iter && repo);
+
if (git_repository_is_bare(repo)) {
giterr_set(GITERR_INVALID,
"Cannot scan working directory for bare repo");
@@ -680,10 +682,16 @@ int git_iterator_for_workdir_range(
wi->root_len = wi->path.size;
- if ((error = workdir_iterator__expand_dir(wi)) < 0)
- git_iterator_free((git_iterator *)wi);
- else
- *iter = (git_iterator *)wi;
+ if ((error = workdir_iterator__expand_dir(wi)) < 0) {
+ if (error == GIT_ENOTFOUND)
+ error = 0;
+ else {
+ git_iterator_free((git_iterator *)wi);
+ wi = NULL;
+ }
+ }
+
+ *iter = (git_iterator *)wi;
return error;
}
diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c
index d94f004..6cc6259 100644
--- a/tests-clar/status/worktree.c
+++ b/tests-clar/status/worktree.c
@@ -447,3 +447,72 @@ void test_status_worktree__first_commit_in_progress(void)
git_index_free(index);
git_repository_free(repo);
}
+
+
+
+void test_status_worktree__status_file_without_index_or_workdir(void)
+{
+ git_repository *repo;
+ unsigned int status = 0;
+ git_index *index;
+
+ cl_git_pass(p_mkdir("wd", 0777));
+
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+ cl_git_pass(git_repository_set_workdir(repo, "wd"));
+
+ cl_git_pass(git_index_open(&index, "empty-index"));
+ cl_assert_equal_i(0, git_index_entrycount(index));
+ git_repository_set_index(repo, index);
+
+ cl_git_pass(git_status_file(&status, repo, "branch_file.txt"));
+
+ cl_assert_equal_i(GIT_STATUS_INDEX_DELETED, status);
+
+ git_repository_free(repo);
+ git_index_free(index);
+ cl_git_pass(p_rmdir("wd"));
+}
+
+static void fill_index_wth_head_entries(git_repository *repo, git_index *index)
+{
+ git_oid oid;
+ git_commit *commit;
+ git_tree *tree;
+
+ cl_git_pass(git_reference_name_to_oid(&oid, repo, "HEAD"));
+ cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+ cl_git_pass(git_commit_tree(&tree, commit));
+
+ cl_git_pass(git_index_read_tree(index, tree));
+ cl_git_pass(git_index_write(index));
+
+ git_tree_free(tree);
+ git_commit_free(commit);
+}
+
+void test_status_worktree__status_file_with_clean_index_and_empty_workdir(void)
+{
+ git_repository *repo;
+ unsigned int status = 0;
+ git_index *index;
+
+ cl_git_pass(p_mkdir("wd", 0777));
+
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+ cl_git_pass(git_repository_set_workdir(repo, "wd"));
+
+ cl_git_pass(git_index_open(&index, "my-index"));
+ fill_index_wth_head_entries(repo, index);
+
+ git_repository_set_index(repo, index);
+
+ cl_git_pass(git_status_file(&status, repo, "branch_file.txt"));
+
+ cl_assert_equal_i(GIT_STATUS_WT_DELETED, status);
+
+ git_repository_free(repo);
+ git_index_free(index);
+ cl_git_pass(p_rmdir("wd"));
+ cl_git_pass(p_unlink("my-index"));
+}