Commit 8da44047050c16b563575cf973c1f33b6149f1cc

Carlos Martín Nieto 2015-06-06T03:55:28

path: error out if the callback returns an error When the callback returns an error, we should stop immediately. This broke when trying to make sure we pass specific errors up the chain. This broke cancelling out of the loose backend's foreach.

diff --git a/src/path.c b/src/path.c
index 81b4d51..8f861e6 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1066,8 +1066,10 @@ int git_path_direach(
 		git_buf_truncate(path, wd_len); /* restore path */
 
 		/* Only set our own error if the callback did not set one already */
-		if (error != 0 && !giterr_last()) {
-			giterr_set_after_callback(error);
+		if (error != 0) {
+			if (!giterr_last())
+				giterr_set_after_callback(error);
+
 			break;
 		}
 	}
diff --git a/tests/odb/foreach.c b/tests/odb/foreach.c
index 75448a2..12b81b4 100644
--- a/tests/odb/foreach.c
+++ b/tests/odb/foreach.c
@@ -71,15 +71,35 @@ static int foreach_stop_cb(const git_oid *oid, void *data)
 	return (*nobj == 1000) ? -321 : 0;
 }
 
+static int foreach_stop_first_cb(const git_oid *oid, void *data)
+{
+	int *nobj = data;
+	(*nobj)++;
+
+	GIT_UNUSED(oid);
+
+	return -123;
+}
+
 void test_odb_foreach__interrupt_foreach(void)
 {
 	int nobj = 0;
+	git_oid id;
 
 	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
 	git_repository_odb(&_odb, _repo);
 
 	cl_assert_equal_i(-321, git_odb_foreach(_odb, foreach_stop_cb, &nobj));
 	cl_assert(nobj == 1000);
+
+	git_odb_free(_odb);
+	git_repository_free(_repo);
+
+	cl_git_pass(git_repository_init(&_repo, "onlyloose.git", true));
+	git_repository_odb(&_odb, _repo);
+
+	cl_git_pass(git_odb_write(&id, _odb, "", 0, GIT_OBJ_BLOB));
+	cl_assert_equal_i(-123, git_odb_foreach(_odb, foreach_stop_first_cb, &nobj));
 }
 
 void test_odb_foreach__files_in_objects_dir(void)