Fix refdb iteration early termination bug

There was a problem found in the Rugged test suite where the
refdb_fs_backend__next function could exit too early in some
very specific hashing patterns for packed refs.  This ports
the Rugged test to libgit2 and then fixes the bug.
This commit is contained in:
Russell Belfer 2013-05-11 06:42:25 -07:00
parent 7b5bc8f498
commit 99d32707b9
46 changed files with 94 additions and 17 deletions

View File

@ -671,17 +671,20 @@ static int refdb_fs_backend__next(const char **out, git_reference_iterator *_ite
{
refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
/* First round of checks to make sure where we are */
if (!iter->loose && iter->k == kh_end(iter->h)) {
if (iter_loose_setup(iter) < 0)
return -1;
iter->loose = 1;
if (iter->loose)
return iter_loose(out, iter);
if (iter->k != kh_end(iter->h)) {
int error = iter_packed(out, iter);
if (error != GIT_ITEROVER)
return error;
}
if (!iter->loose)
return iter_packed(out, iter);
else
return iter_loose(out, iter);
if (iter_loose_setup(iter) < 0)
return -1;
iter->loose = 1;
return iter_loose(out, iter);
}
static int loose_write(refdb_fs_backend *backend, const git_reference *ref)

View File

@ -24,6 +24,8 @@ void test_refs_branches_foreach__cleanup(void)
repo = NULL;
cl_fixture_cleanup("testrepo.git");
cl_git_sandbox_cleanup();
}
static int count_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
@ -72,14 +74,11 @@ static void assert_branch_has_been_found(struct expectations *findings, const ch
{
int pos = 0;
while (findings[pos].branch_name)
{
for (pos = 0; findings[pos].branch_name; ++pos) {
if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
cl_assert_equal_i(1, findings[pos].encounters);
return;
}
pos++;
}
cl_fail("expected branch not found in list.");
@ -94,12 +93,9 @@ static int contains_branch_list_cb(const char *branch_name, git_branch_t branch_
exp = (struct expectations *)payload;
while (exp[pos].branch_name)
{
for (pos = 0; exp[pos].branch_name; ++pos) {
if (strcmp(branch_name, exp[pos].branch_name) == 0)
exp[pos].encounters++;
pos++;
}
return 0;
@ -153,3 +149,25 @@ void test_refs_branches_foreach__can_cancel(void)
cl_assert_equal_i(5, count);
}
void test_refs_branches_foreach__mix_of_packed_and_loose(void)
{
struct expectations exp[] = {
{ "master", 0 },
{ "origin/HEAD", 0 },
{ "origin/master", 0 },
{ "origin/packed", 0 },
{ NULL, 0 }
};
git_repository *r2;
r2 = cl_git_sandbox_init("testrepo2");
cl_git_pass(git_branch_foreach(r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
contains_branch_list_cb, &exp));
assert_branch_has_been_found(exp, "master");
assert_branch_has_been_found(exp, "origin/HEAD");
assert_branch_has_been_found(exp, "origin/master");
assert_branch_has_been_found(exp, "origin/packed");
}

View File

@ -0,0 +1 @@
ref: refs/heads/master

View File

@ -0,0 +1,14 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
[remote "origin"]
url = https://github.com/libgit2/false.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
rebase = true

View File

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

Binary file not shown.

View File

@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View File

@ -0,0 +1 @@
0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git

View File

@ -0,0 +1 @@
0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git

View File

@ -0,0 +1 @@
0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git

View File

@ -0,0 +1,2 @@
x<01><>Q
Β0ύΞ)re“έ΄ <0A>Α$Ϋ­-<2D>F<EFBFBD>νύ-Α<>Η00𸲨υΎ?i±L#»ΠHS<01><>SΧ#qΟ2²DΘζ“<CEB6>¬jC|HS†L8$ς)αΠa<CEA0>°#2iΧΉ6ϋδ<CF8B>jsβΊΪλΖ?ΈΏJZή®εf<CEB5>η<74>Α<03>ΓUώiΝ¶ηqiΒZΫ"›ω_/H6

View File

@ -0,0 +1,2 @@
x<01>ŽQ
Â0DýÎ)öÊ6ͦ "xO°‰‰-ØFb¼¿EoàÏ0 ¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3² âÙ<µåµGŽhYKÄèÒ8ÐDA<44>É)¿ÉÈ;gôݧÚàšjïp™4Õޝô-çû¢óã<C3B3>êrÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE

View File

@ -0,0 +1,2 @@
xťŽŰ 1EýNi@™Ék2 "X$ŮYW0Yc˙íŔżĂ…s¸ĄŐzďÚÚőMDĎś8!¶†ÉĚŢs‰ ŞgÚdí::@X0»P˘wŮ"F/‰‰śÍRŕ<>Uz÷ĄmúZZďú˛¤ŇV}|•/śo5݇ŇęIŁ!¬1z Ć:vůÇUim}ę/˘>
öF-

View File

@ -0,0 +1,3 @@
x<01><>[
Т0E§Ю*fЪфеЄ "ИW0<57><30>-иFтtџн<><EFBFBD>чpS[<5B>YР<59>x<EFBFBD>^
Dэb CLhu<18>}Ѕ8X*4ZэЌsYНЈ<D09D>UР<55>AУж ЬX3<>RЋMЕЖ) s6шМЂMІжс<D0B6><D181>м&Jm<4A>ѓ;}ЧѕБаќ<ЅЖ\@<40>р<EFBFBD>бо<D0B1><70>ЈvК?<3F>ђ<EFBFBD>ЋКL№ЋЈи?Hх

View File

@ -0,0 +1,2 @@
xťŹ;j1DëťmdÓú·Ŕ<C2B7>ÇŽ|M«µ3`ŤŚV{ >€łâQŻ ¸·vL0I?Í!š4Z=Ę! ×¦8˛F˘Ă!rÖsQßyČ9<C48C>]$DŽ&„l6AÇ>jFWüҵ IKNiűë§Z˘%ˇS<>Ś
Ň ­Ĺʉř<E280B0>U~Ě˝řä>'Ľď™ű Żwţ ×[ËÇ× ÷öÚDGÚˇ±đŚQ-şMůŹ«>dÜOŢáŇň}í\ŕ8g_ШÂoYr

View File

@ -0,0 +1,3 @@
x<01><>Kj1D³Ö)zçUBëÛ-0Á<30>uV9<56>¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨eµµÈ•KJ­«<C2AD>½S
ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC<>‡Î†”­œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
l}FW$Ds´Ç£©ÿÙšOW…e”]V8-Ã<>ÌÈ"U

View File

@ -0,0 +1,3 @@
x<01>ŽQ
Â0DýÎ)öʦ»I<'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz4yó”µ,\r 'SÂÄ-mI4
Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoUî<55>ƒ¶z;-<2D>a<E28098>Ñlt{ØË?®I«,:ÃoÚR̳cHK

View File

@ -0,0 +1,6 @@
# pack-refs with: peeled fully-peeled
36060c58702ed4c2a40832c51758d5344201d89a refs/remotes/origin/master
41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed
5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/tags/v0.9
0c37a5391bbff43c37f0d0371823a5509eed5b1d refs/tags/v1.0
^5b5b025afb0b4c913b4c338a42934a3863bf3644

View File

@ -0,0 +1 @@
36060c58702ed4c2a40832c51758d5344201d89a

View File

@ -0,0 +1 @@
ref: refs/remotes/origin/master

View File

@ -0,0 +1 @@
hey

View File

@ -0,0 +1 @@
new file

View File

@ -0,0 +1 @@
hey

View File

@ -0,0 +1 @@
new file

View File

@ -0,0 +1 @@
hey

View File

@ -0,0 +1 @@
new file