summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-09-10 19:52:11 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2016-11-02 09:36:49 +0100
commit952171787a0b865c17d5c9476e272106383ae93a (patch)
tree6625a911979a1dee2e1f73731e6898b21ae18f02 /apt-private
parent800bb9b8842e6651baa71f017d9d59e35c9312bb (diff)
don't install new deps of candidates for kept back pkgs
In effect this is an extension of the 6 years old commit a8dfff90aa740889eb99d00fde5d70908d9fd88a which uses the autoremover to remove packages again from the solution which are no longer needed to be there. Commonly these are dependencies of packages we end up not installed due to problem resolver decisions. Slightly less common is the situation we deal with here: a package which we wanted to upgrade sporting a new dependency, but ended up holding back. The problem is that all versions of an installed reverse dependencies can bring back a "garbage" package – we need to do this as there is nothing inherently wrong in having garbage packages installed or upgrade them, which itself would have garbage dependencies, so just blindly killing all new garbage packages would prevent the upgrade (and actually generate errors). What we should be doing is looking only at the version we will have on the system, disregarding all old/new reverse dependencies. Reported-By: Stuart Prescott (themill) on IRC
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/private-install.cc26
1 files changed, 21 insertions, 5 deletions
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index fab742dc7..761e4d175 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -426,11 +426,11 @@ bool DoAutomaticRemove(CacheFile &Cache)
{
if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
if(Debug)
- std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
+ std::cout << "We could delete " << APT::PrettyPkg(Cache, Pkg) << std::endl;
if (doAutoRemove)
{
- if(Pkg.CurrentVer() != 0 &&
+ if(Pkg.CurrentVer() != 0 &&
Pkg->CurrentState != pkgCache::State::ConfigFiles)
Cache->MarkDelete(Pkg, purgePkgs, 0, false);
else
@@ -475,11 +475,25 @@ bool DoAutomaticRemove(CacheFile &Cache)
if (R.IsNegative() == true ||
Cache->IsImportantDep(R) == false)
continue;
- pkgCache::PkgIterator N = R.ParentPkg();
- if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
+ auto const RV = R.ParentVer();
+ if (unlikely(RV.end() == true))
+ continue;
+ auto const RP = RV.ParentPkg();
+ // check if that dependency comes from an interesting version
+ if (RP.CurrentVer() == RV)
+ {
+ if ((*Cache)[RP].Keep() == false)
+ continue;
+ }
+ else if (Cache[RP].CandidateVerIter(Cache) == RV)
+ {
+ if ((*Cache)[RP].NewInstall() == false && (*Cache)[RP].Upgrade() == false)
+ continue;
+ }
+ else // ignore dependency from a non-candidate version
continue;
if (Debug == true)
- std::clog << "Save " << APT::PrettyPkg(Cache, Pkg) << " as another installed garbage package depends on it" << std::endl;
+ std::clog << "Save " << APT::PrettyPkg(Cache, Pkg) << " as another installed package depends on it: " << APT::PrettyPkg(Cache, RP) << std::endl;
Cache->MarkInstall(Pkg, false, 0, false);
if (hideAutoRemove == false)
++autoRemoveCount;
@@ -495,6 +509,8 @@ bool DoAutomaticRemove(CacheFile &Cache)
}
} while (Changed == true);
}
+ // trigger marking now so that the package list below is correct
+ group.release();
// Now see if we had destroyed anything (if we had done anything)
if (Cache->BrokenCount() != 0)