diff --git a/src/refdb_fs.c b/src/refdb_fs.c index b9e283ac5..2f1a5b26c 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -452,6 +452,9 @@ static int loose_lookup( git_buf ref_file = GIT_BUF_INIT; int error = 0; + if (out) + *out = NULL; + error = reference_read(&ref_file, NULL, backend->path, ref_name, NULL); if (error < 0) @@ -465,15 +468,17 @@ static int loose_lookup( goto done; } - *out = git_reference__alloc_symbolic(ref_name, target); + if (out) + *out = git_reference__alloc_symbolic(ref_name, target); } else { if ((error = loose_parse_oid(&oid, ref_name, &ref_file)) < 0) 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; done: @@ -679,6 +684,11 @@ static int refdb_fs_backend__iterator_next_name( if (git_strmap_exists(packfile, path)) continue; + if (loose_lookup(NULL, backend, path) != 0) { + giterr_clear(); + continue; + } + *out = path; return 0; } diff --git a/tests-clar/revwalk/basic.c b/tests-clar/revwalk/basic.c index e82776260..7c2fc000d 100644 --- a/tests-clar/revwalk/basic.c +++ b/tests-clar/revwalk/basic.c @@ -142,6 +142,28 @@ void test_revwalk_basic__glob_heads(void) 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) { int i = 0;