Commit ee311907ee0299ff2c1d7fc37699dc3e4da20c52

Carlos Martín Nieto 2014-05-05T16:04:14

odb: ignore files in the objects dir We assume that everything under GIT_DIR/objects/ is a directory. This is not necessarily the case if some process left a stray file in there. Check beforehand if we do have a directory and ignore the entry otherwise.

diff --git a/src/odb_loose.c b/src/odb_loose.c
index 7b46a66..b2e8bed 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -755,6 +755,10 @@ static int foreach_cb(void *_state, git_buf *path)
 {
 	struct foreach_state *state = (struct foreach_state *) _state;
 
+	/* non-dir is some stray file, ignore it */
+	if (!git_path_isdir(git_buf_cstr(path)))
+		return 0;
+
 	return git_path_direach(path, 0, foreach_object_dir_cb, state);
 }
 
diff --git a/tests/odb/foreach.c b/tests/odb/foreach.c
index 256ae9c..ab3808b 100644
--- a/tests/odb/foreach.c
+++ b/tests/odb/foreach.c
@@ -2,6 +2,7 @@
 #include "odb.h"
 #include "git2/odb_backend.h"
 #include "pack.h"
+#include "buffer.h"
 
 static git_odb *_odb;
 static git_repository *_repo;
@@ -80,3 +81,26 @@ void test_odb_foreach__interrupt_foreach(void)
 	cl_assert_equal_i(-321, git_odb_foreach(_odb, foreach_stop_cb, &nobj));
 	cl_assert(nobj == 1000);
 }
+
+void test_odb_foreach__files_in_objects_dir(void)
+{
+	git_repository *repo;
+	git_odb *odb;
+	git_buf buf = GIT_BUF_INIT;
+	size_t nobj = 0;
+
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+	cl_git_pass(git_buf_printf(&buf, "%s/objects/somefile", git_repository_path(repo)));
+
+	cl_git_mkfile(buf.ptr, "");
+
+	cl_git_pass(git_repository_odb(&odb, repo));
+	cl_git_pass(git_odb_foreach(odb, foreach_cb, &nobj));
+	cl_assert_equal_i(47 + 1640, nobj); /* count + in-pack */
+
+	git_odb_free(odb);
+	git_repository_free(repo);
+	cl_fixture_cleanup("testrepo.git");
+}