From 4d87856b94dae1a40a1a8147a6dbcfe714cd05c7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 22 May 2020 19:52:26 +0200 Subject: Known-bad candidate versions are not an upgrade option If we have a negative dependency to deal with we prefer to install an upgrade rather than remove the current version. That is why we split the method rather explicitly in two in 57df273 but there is a case we didn't react to: If we have seen the candidate before as a "satisfier" of this negative dependency there is no point in trying to upgrade to it later on. We keep that info by candidate discard if we can, but even if we can't we can at least keep that info around locally. This "fixes" (or would hide) the problem described in 04a020d as well as you don't have to discard installations you never make. --- apt-pkg/depcache.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 02a80b2e8..39e30a38d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1221,6 +1221,7 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool If the candidate is effected try to keep current and discard candidate If the current is effected try upgrading to candidate or remove it */ bool failedToRemoveSomething = false; + APT::PackageVector badCandidate; for (auto const &D : toRemove) { for (auto const &Ver : getAllPossibleSolutions(Cache, D, D, APT::CacheSetHelper::CANDIDATE, true)) @@ -1241,6 +1242,8 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool if (Pkg->CurrentVer == 0) Cache.MarkProtected(Pkg); } + else + badCandidate.push_back(Pkg); } else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected)) { @@ -1249,11 +1252,14 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool break; } } + if (failedToRemoveSomething && not propagateProctected && not FromUser) + break; for (auto const &Ver : getAllPossibleSolutions(Cache, D, D, APT::CacheSetHelper::INSTALLED, true)) { auto const Pkg = Ver.ParentPkg(); auto &State = Cache[Pkg]; - if (State.CandidateVer != Ver && State.CandidateVer != nullptr) + if (State.CandidateVer != Ver && State.CandidateVer != nullptr && + std::find(badCandidate.cbegin(), badCandidate.cend(), Pkg) == badCandidate.end()) toUpgrade.push_back(Pkg); else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected)) { @@ -1262,6 +1268,8 @@ static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool break; } } + if (failedToRemoveSomething && not propagateProctected && not FromUser) + break; } toRemove.clear(); return not failedToRemoveSomething; -- cgit v1.2.3