Bug#547788: apt: apt-get install <virtual> gets confused with multiple available versions
Package: apt
Version: 0.7.23.1
Severity: normal
Tags: patch
When giving a virtual package to "apt-get install", apt-get tries to
select a real package instead of the virtual package when it is obvious
which real package to select.
This doesn't work when there is more than one version of a real package
available. The attached patch fixes this by ignoring package versions
that are not candidates.
-- apt-config dump --
APT "";
APT::Architecture "i386";
APT::Build-Essential "";
APT::Build-Essential:: "build-essential";
APT::Install-Recommends "1";
APT::Install-Suggests "0";
APT::Acquire "";
APT::Acquire::Translation "environment";
APT::Authentication "";
APT::Authentication::TrustCDROM "true";
APT::NeverAutoRemove "";
APT::NeverAutoRemove:: "^linux-image.*";
APT::NeverAutoRemove:: "^linux-restricted-modules.*";
APT::Periodic "";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Update "";
APT::Update::Post-Invoke-Success "";
APT::Update::Post-Invoke-Success:::: "touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";
APT::Archives "";
APT::Archives::MaxAge "30";
APT::Archives::MinAge "2";
APT::Archives::MaxSize "500";
Dir "/";
Dir::State "var/lib/apt/";
Dir::State::lists "lists/";
Dir::State::cdroms "cdroms.list";
Dir::State::userstatus "status.user";
Dir::State::status "/var/lib/dpkg/status";
Dir::Cache "var/cache/apt/";
Dir::Cache::archives "archives/";
Dir::Cache::srcpkgcache "srcpkgcache.bin";
Dir::Cache::pkgcache "pkgcache.bin";
Dir::Etc "etc/apt/";
Dir::Etc::sourcelist "sources.list";
Dir::Etc::sourceparts "sources.list.d";
Dir::Etc::vendorlist "vendors.list";
Dir::Etc::vendorparts "vendors.list.d";
Dir::Etc::main "apt.conf";
Dir::Etc::parts "apt.conf.d";
Dir::Etc::preferences "preferences";
Dir::Etc::preferencesparts "preferences.d";
Dir::Bin "";
Dir::Bin::methods "/usr/lib/apt/methods";
Dir::Bin::dpkg "/usr/bin/dpkg";
Dir::Log "var/log/apt";
Dir::Log::Terminal "term.log";
Unattended-Upgrade "";
Unattended-Upgrade::Allowed-Origins "";
Unattended-Upgrade::Allowed-Origins:: "Debian stable";
DPkg "";
DPkg::Pre-Install-Pkgs "";
DPkg::Pre-Install-Pkgs:: "/usr/sbin/dpkg-preconfigure --apt || true";
DPkg::Post-Invoke "";
DPkg::Post-Invoke:: "if [ -x /usr/bin/debsums ]; then /usr/bin/debsums --generate=nocheck -sp /var/cache/apt/archives; fi";
DPkg::Post-Invoke:: "if [ -d /var/lib/update-notifier ]; then touch /var/lib/update-notifier/dpkg-run-stamp; fi";
-- (no /etc/apt/preferences present) --
-- /etc/apt/sources.list --
deb http://ftp.de.debian.org/debian/ unstable main non-free contrib
deb-src http://ftp.de.debian.org/debian/ unstable main non-free contrib
deb http://ftp.de.debian.org/debian/ testing main non-free contrib
deb-src http://ftp.de.debian.org/debian/ testing main non-free contrib
deb-src http://ftp.de.debian.org/debian/ stable main non-free contrib
deb http://ftp.de.debian.org/debian/ experimental main non-free contrib
#deb-src http://ftp.de.debian.org/debian/ experimental main non-free contrib
deb http://emacs.orebokech.com sid main
deb-src http://emacs.orebokech.com sid main
deb http://scratchbox.org/debian/ apophis main
deb http://maemo.research.nokia.com/repository/project/host_tools host_tools tools
deb http://maemo-sdk.garage.maemo.org/download/host ubuntu-hardy free
deb-src http://maemo-sdk.garage.maemo.org/download/host ubuntu-hardy free
#deb http://security.debian.org/ lenny/updates main contrib
#deb-src http://security.debian.org/ lenny/updates main contrib
deb http://linux.nokia.com/ftp/nokia/MagicDraw/ubuntu binary-i386/
-- System Information:
Debian Release: squeeze/sid
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'testing'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.30-1-686 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages apt depends on:
ii debian-archive-keyring 2009.01.31 GnuPG archive keys of the Debian a
ii libc6 2.9-26 GNU C Library: Shared libraries
ii libgcc1 1:4.4.1-4 GCC support library
ii libstdc++6 4.4.1-4 The GNU Standard C++ Library v3
apt recommends no packages.
Versions of packages apt suggests:
pn apt-doc <none> (no description available)
ii aptitude 0.4.11.11-1+b2 terminal-based package manager
ii bzip2 1.0.5-3 high-quality block-sorting file co
ii dpkg-dev 1.15.4 Debian package development tools
ii lzma 4.43-14 Compression method of 7z format in
ii python-apt 0.7.13.2 Python interface to libapt-pkg
ii synaptic 0.62.9 Graphical package manager
-- no debconf information
>From bde13f7a5099e1238b86e242bc8d59765366187a Mon Sep 17 00:00:00 2001
From: Marius Vollmer <marius.vollmer@nokia.com>
Date: Tue, 22 Sep 2009 11:21:01 +0300
Subject: [PATCH] Be smarter when installing virtual packages.
* cmdline/apt-get.cc (TryToInstall): When selecting a real package
instead of a virtual one, ignore versions that are not candidates.
This allows us to survive repositories that contain more than one
version of a package.
---
cmdline/apt-get.cc | 45 ++++++++++++++++++++++++++++++++++++---------
1 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index a7221d4..c1981c8 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -1045,15 +1045,42 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
unsigned int &ExpectedInst,bool AllowFail = true)
{
/* This is a pure virtual package and there is a single available
- provides */
- if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
- Pkg.ProvidesList()->NextProvides == 0)
- {
- pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
- ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
- Tmp.Name(),Pkg.Name());
- Pkg = Tmp;
- }
+ candidate providing it. */
+ if (Cache[Pkg].CandidateVer == 0)
+ {
+ pkgCache::PkgIterator Prov;
+ bool found_one = false, found_more_than_one = false;
+
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
+ {
+ pkgCache::VerIterator PVer = P.OwnerVer();
+ pkgCache::PkgIterator PPkg = PVer.ParentPkg();
+
+ if (Cache[PPkg].CandidateVer != PVer)
+ {
+ /* Ignore versions that are not a candidate. */
+ continue;
+ }
+
+ if (!found_one)
+ {
+ Prov = PPkg;
+ found_one = true;
+ }
+ else if (PPkg != Prov)
+ {
+ found_more_than_one = true;
+ break;
+ }
+ }
+
+ if (found_one && !found_more_than_one)
+ {
+ ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
+ Prov.Name(),Pkg.Name());
+ Pkg = Prov;
+ }
+ }
// Handle the no-upgrade case
if (_config->FindB("APT::Get::upgrade",true) == false &&
--
1.6.3.3
Reply to: