---
Debian package versioning
It always made me curious how the debian package versinoning works,
especially since I saw "odd" sorting behavior during the 20.05 RC1 yesterday,
where the 'plain rc1' was considered older than the rc0~750...
So with the first commit the output was as follows:
ubuntu@vpp-install:~$ apt-cache policy vpp
vpp:
Installed: (none)
Candidate: 20.05-rc1~1-g765ef3767~b3
Version table:
20.05-rc1~1-g765ef3767~b3 500
500 file:/home/ubuntu/repo ./ Packages
20.05-rc0~750-gb8e900940~b1 500
500 file:/home/ubuntu/repo ./ Packages
20.05-rc1~b2 500
500 file:/home/ubuntu/repo ./ Packages
ubuntu@vpp-install:~$
Installing apt-src and subsequent apt-src install apt reveals
the secret of how the versions are compared, as per the function
in apt-1.6.12ubuntu0.1/apt-pkg/deb/debversion.cc:
/* This fragments the version into E:V-R triples and compares each
portion separately. */
int debVersioningSystem::DoCmpVersion(const char *A,const char *AEnd,
const char *B,const char *BEnd)
{
// Strip off the epoch and compare it
const char *lhs = (const char*) memchr(A, ':', AEnd - A);
const char *rhs = (const char*) memchr(B, ':', BEnd - B);
if (lhs == NULL)
lhs = A;
if (rhs == NULL)
rhs = B;
// Special case: a zero epoch is the same as no epoch,
// so remove it.
if (lhs != A)
{
for (; *A == '0'; ++A);
if (A == lhs)
{
++A;
++lhs;
}
}
if (rhs != B)
{
for (; *B == '0'; ++B);
if (B == rhs)
{
++B;
++rhs;
}
}
// Compare the epoch
int Res = CmpFragment(A,lhs,B,rhs);
if (Res != 0)
return Res;
// Skip the :
if (lhs != A)
lhs++;
if (rhs != B)
rhs++;
// Find the last -
const char *dlhs = (const char*) memrchr(lhs, '-', AEnd - lhs);
const char *drhs = (const char*) memrchr(rhs, '-', BEnd - rhs);
if (dlhs == NULL)
dlhs = AEnd;
if (drhs == NULL)
drhs = BEnd;
// Compare the main version
Res = CmpFragment(lhs,dlhs,rhs,drhs);
if (Res != 0)
return Res;
// Skip the -
if (dlhs != lhs)
dlhs++;
if (drhs != rhs)
drhs++;
// no debian revision need to be treated like -0
if (*(dlhs-1) == '-' && *(drhs-1) == '-')
return CmpFragment(dlhs,AEnd,drhs,BEnd);
else if (*(dlhs-1) == '-')
{
const char* null = "0";
return CmpFragment(dlhs,AEnd,null, null+1);
}
else if (*(drhs-1) == '-')
{
const char* null = "0";
return CmpFragment(null, null+1, drhs, BEnd);
}
else
return 0;
}
Files in 2020-05-14-Debian-package-versioning:
../
HEADER.txt 01-Jul-2024 21:41 2708
(c) Andrew Yourtchenko