Commit b7107131 by Russell Belfer

git_reference_next_name must match git_reference_next

The git_reference_next API silently skips invalid references when
scanning the loose refs.  The git_reference_next_name API should
skip the same ones even though it isn't creating the reference
object.

This adds a test with a an invalid loose reference and makes sure
that both APIs skip the same entries and generate the same results.
parent 1cd9dc29
...@@ -452,6 +452,9 @@ static int loose_lookup( ...@@ -452,6 +452,9 @@ static int loose_lookup(
git_buf ref_file = GIT_BUF_INIT; git_buf ref_file = GIT_BUF_INIT;
int error = 0; int error = 0;
if (out)
*out = NULL;
error = reference_read(&ref_file, NULL, backend->path, ref_name, NULL); error = reference_read(&ref_file, NULL, backend->path, ref_name, NULL);
if (error < 0) if (error < 0)
...@@ -465,15 +468,17 @@ static int loose_lookup( ...@@ -465,15 +468,17 @@ static int loose_lookup(
goto done; goto done;
} }
*out = git_reference__alloc_symbolic(ref_name, target); if (out)
*out = git_reference__alloc_symbolic(ref_name, target);
} else { } else {
if ((error = loose_parse_oid(&oid, ref_name, &ref_file)) < 0) if ((error = loose_parse_oid(&oid, ref_name, &ref_file)) < 0)
goto done; goto done;
*out = git_reference__alloc(ref_name, &oid, NULL); if (out)
*out = git_reference__alloc(ref_name, &oid, NULL);
} }
if (*out == NULL) if (out && *out == NULL)
error = -1; error = -1;
done: done:
...@@ -679,6 +684,11 @@ static int refdb_fs_backend__iterator_next_name( ...@@ -679,6 +684,11 @@ static int refdb_fs_backend__iterator_next_name(
if (git_strmap_exists(packfile, path)) if (git_strmap_exists(packfile, path))
continue; continue;
if (loose_lookup(NULL, backend, path) != 0) {
giterr_clear();
continue;
}
*out = path; *out = path;
return 0; return 0;
} }
......
...@@ -142,6 +142,28 @@ void test_revwalk_basic__glob_heads(void) ...@@ -142,6 +142,28 @@ void test_revwalk_basic__glob_heads(void)
cl_assert(i == 14); cl_assert(i == 14);
} }
void test_revwalk_basic__glob_heads_with_invalid(void)
{
int i;
git_oid oid;
test_revwalk_basic__cleanup();
_repo = cl_git_sandbox_init("testrepo");
cl_git_mkfile("testrepo/.git/refs/heads/garbage", "not-a-ref");
cl_git_pass(git_revwalk_new(&_walk, _repo));
cl_git_pass(git_revwalk_push_glob(_walk, "heads"));
for (i = 0; !git_revwalk_next(&oid, _walk); ++i)
/* walking */;
/* git log --branches --oneline | wc -l => 16 */
cl_assert_equal_i(16, i);
cl_fixture_cleanup("testrepo");
}
void test_revwalk_basic__push_head(void) void test_revwalk_basic__push_head(void)
{ {
int i = 0; int i = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment