summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/deb/dpkgpm.cc25
-rwxr-xr-xtest/integration/test-crossgrades32
2 files changed, 50 insertions, 7 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index abf91fe2a..d76b59449 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1525,11 +1525,30 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
continue;
auto const Grp = I->Pkg.Group();
- size_t installedInstances = 0;
+ size_t installedInstances = 0, wannabeInstances = 0;
+ bool multiArchInstances = false;
for (auto Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
- if (Pkg->CurrentVer != 0 || Cache[Pkg].Install())
+ {
+ if (Pkg->CurrentVer != 0)
+ {
++installedInstances;
- if (installedInstances == 2)
+ if (Cache[Pkg].Delete() == false)
+ ++wannabeInstances;
+ }
+ else if (PackageOps.find(Pkg.FullName()) != PackageOps.end())
+ ++wannabeInstances;
+ if (multiArchInstances == false)
+ {
+ auto const V = Cache[Pkg].InstVerIter(Cache);
+ if (V.end() == false && (Pkg->CurrentVer == 0 || V != Pkg.CurrentVer()))
+ multiArchInstances = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
+ }
+ }
+ /* theoretically the installed check would be enough as some wannabe will
+ be first and hence be the crossgrade we were looking for, but #844300
+ prevents this so we keep these situations explicit removes.
+ It is also the reason why neither of them can be a M-A:same package */
+ if (installedInstances == 1 && wannabeInstances == 1 && multiArchInstances == false)
{
auto const FirstInstall = std::find_if_not(I, List.end(),
[](Item const &i) { return i.Op == Item::Remove || i.Op == Item::Purge; });
diff --git a/test/integration/test-crossgrades b/test/integration/test-crossgrades
index 30195d30f..6398e7e7f 100755
--- a/test/integration/test-crossgrades
+++ b/test/integration/test-crossgrades
@@ -26,8 +26,24 @@ singleinstance() {
testdpkgnotinstalled 'crosser:i386' 'unrelated'
testdpkginstalled 'crosser:amd64'
- testsuccess apt purge crosser:amd64 -y --planner $1
- testdpkgnotinstalled 'crosser:amd64'
+ testsuccess apt install crosser:armel=3 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser:armel=3 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1
+ testdpkgnotinstalled 'crosser:i386' 'crosser:amd64' 'unrelated'
+ testdpkginstalled 'crosser:armel'
+
+ testsuccess apt install crosser=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ testdpkgnotinstalled 'crosser:armel' 'crosser:amd64' 'unrelated'
+ testdpkginstalled 'crosser:i386'
+
+ testsuccess apt purge crosser:i386 -y --planner $1
+ testdpkgnotinstalled 'crosser:i386'
}
singleinstance 'internal'
singleinstance 'apt'
@@ -52,7 +68,15 @@ multiinstance() {
testdpkgnotinstalled 'crosser:amd64' 'unrelated'
testdpkginstalled 'crosser:i386' 'crosser:armel'
- testsuccess apt purge crosser:i386 crosser:armel -y --planner $1
- testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'unrelated'
+ testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ cp -a rootdir/tmp/testsuccess.output crosser.output
+ testsuccess grep -- '--remove.*crosser.*' crosser.output
+ testsuccess grep -- '--purge' crosser.output
+ testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades
+ testdpkgnotinstalled 'crosser:amd64' 'crosser:i386' 'unrelated'
+ testdpkginstalled 'crosser:armel'
+
+ testsuccess apt purge crosser:armel -y --planner $1 -o Debug::pkgDPkgProgressReporting=1
+ testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'crosser:amd64' 'unrelated'
}
multiinstance 'internal'