summaryrefslogtreecommitdiff
path: root/apt-pkg/upgrade.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/upgrade.cc')
-rw-r--r--apt-pkg/upgrade.cc47
1 files changed, 39 insertions, 8 deletions
diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc
index e3e98e5c6..994a05859 100644
--- a/apt-pkg/upgrade.cc
+++ b/apt-pkg/upgrade.cc
@@ -85,13 +85,13 @@ struct PhasedUpgrader
{
if (Pkg->CurrentVer == 0)
return false;
- if (Cache[Pkg].InstallVer == 0)
+ if (Cache[Pkg].CandidateVer == 0)
return false;
- if (Cache[Pkg].InstVerIter(Cache).PhasedUpdatePercentage() == 100)
+ if (Cache[Pkg].CandidateVerIter(Cache).PhasedUpdatePercentage() == 100)
return false;
- if (IsSecurityUpdate(Cache[Pkg].InstVerIter(Cache)))
+ if (IsSecurityUpdate(Cache[Pkg].CandidateVerIter(Cache)))
return false;
- if (!IsIgnoredPhasedUpdate(Cache[Pkg].InstVerIter(Cache)))
+ if (!IsIgnoredPhasedUpdate(Cache[Pkg].CandidateVerIter(Cache)))
return false;
return true;
@@ -133,15 +133,18 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
pkgDepCache::ActionGroup group(Cache);
-
- PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, nullptr);
+ PhasedUpgrader phasedUpgrader;
/* Upgrade all installed packages first without autoinst to help the resolver
in versioned or-groups to upgrade the old solver instead of installing
a new one (if the old solver is not the first one [anymore]) */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (phasedUpgrader.ShouldKeep(Cache, I))
+ continue;
if (I->CurrentVer != 0)
Cache.MarkInstall(I, false, 0, false);
+ }
if (Progress != NULL)
Progress->Progress(10);
@@ -149,8 +152,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
/* Auto upgrade all installed packages, this provides the basis
for the installation */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (phasedUpgrader.ShouldKeep(Cache, I))
+ continue;
if (I->CurrentVer != 0)
Cache.MarkInstall(I, true, 0, false);
+ }
if (Progress != NULL)
Progress->Progress(50);
@@ -178,13 +185,19 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
if (isEssential == false || instEssential == true)
continue;
pkgCache::PkgIterator P = G.FindPreferredPkg();
+ if (phasedUpgrader.ShouldKeep(Cache, P))
+ continue;
Cache.MarkInstall(P, true, 0, false);
}
}
else if (essential != "none")
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (phasedUpgrader.ShouldKeep(Cache, I))
+ continue;
if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
Cache.MarkInstall(I, true, 0, false);
+ }
if (Progress != NULL)
Progress->Progress(55);
@@ -192,8 +205,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
/* We do it again over all previously installed packages to force
conflict resolution on them all. */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (phasedUpgrader.ShouldKeep(Cache, I))
+ continue;
if (I->CurrentVer != 0)
Cache.MarkInstall(I, false, 0, false);
+ }
if (Progress != NULL)
Progress->Progress(65);
@@ -216,9 +233,23 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
}
}
- PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, &Fix);
+ bool success = Fix.ResolveInternal(false);
+ if (success)
+ {
+ // Revert phased updates using keeps. An issue with ResolveByKeep is
+ // that it also keeps back packages due to (new) broken Recommends,
+ // even if Upgrade already decided this is fine, so we will mark all
+ // packages that dist-upgrade decided may have a broken policy as allowed
+ // to do so such that we do not keep them back again.
+ pkgProblemResolver FixPhasing(&Cache);
+
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].InstPolicyBroken())
+ FixPhasing.AllowBrokenPolicy(I);
+ PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, &FixPhasing);
+ success = FixPhasing.ResolveByKeepInternal();
+ }
- bool const success = Fix.ResolveInternal(false);
if (Progress != NULL)
Progress->Done();
return success;