In Debian and Ubuntu (and other Debian based distributions) you can use the /etc/apt/preferences file to maintain the various repositories. In the preferences file you can define whether packages should be installed from a certain repository defined in /etc/apt/sources.list and/or /etc/apt/sources.list.d/*.list. I will use Debian in my examples and will mention Ubuntu if it requires some extra attention.
Why would one use the preferences file?
Good question. I started using it when I wanted to install a teamspeak server on Debian Etch (the stable release back then) and the package was only available in Debian Lenny (testing). I do not download packages manually, I prefer apt to take care of it. But when I added the Lenny repositories I would upgrade my machine to testing, which is something I did not want to do. The preferences file allows you to mix your system, or to tell apt in which cases may be upgraded (or not).
How does it work?
Normally, without a preferences file all packages/repositories have a priority of 500, installed packages have a priority of a 100.
In Debian you can define a default/target release, eg lenny, APT::Default-Release “lenny”;. This will make sure packages from that release get a priority of 990. You can set the default release in /etc/apt/apt.conf. Doing this in Ubuntu is rather useless. The Ubuntu repositories are CODENAME-(updates|security|proposed|backports), and the default release doesn’t include these repositories. Because of this I don’t use this directive. I set the 990 priority in my preferences file (more on these numbers later).
You can look at the priorities of your repositories by running apt-cache policy or apt-cache policy packagename.
$ apt-cache policy hello
hello:
Installed: (none)
Candidate: 2.2-2
Version table:
2.4-3 0
500 ftp://ftp.nl.debian.org testing/main Packages
500 ftp://ftp.nl.debian.org unstable/main Packages
2.2-2 0
990 ftp://ftp.nl.debian.org lenny/main Packages
How does this influence package installations?
Apt determines normally based on the version of a package whether it should be installed. So if you have a repository which has an higher version of an installed package it will install that package. But now we have told apt what our default release is, apt will only update/install packages from that repository with the exception of packages which are not present on your default release repositories. If you track multiple repositories the default release alone will not be enough, and that is where the preferences files comes in. You can find the preferences file at /etc/apt/preferences, or not since it is doesn’t exist by default. In newer versions of apt you can also find the /etc/apt/preferences.d/ directory. The concept is similar to /etc/apt/sources.list and /etc/apt/sources.list.d. If you are using aptitude, please be aware that /etc/apt/preferences.d/* is ignored
In the preferences file you can tell apt how to deal with various repositories, eg mixing releases or using PPA’s with Ubuntu.
This would be my default preferences file if I would be running Debian stable. Please note that apt now supports # as comments, normally one would use Explanation: .
# Give preference to stable, then testing and finally unstable # a=stable,n=lenny could also be a=stable, but you don't want to upgrade # stable once testing becomes stable without you knowing about it. # If you use testing/unstable feel free to pick any# # Ubuntu users can use a=CODENAME, where codename is # dapper, hardy, intrepid, jaunty, karmic and all CODENAME-repos, # eg hardy-updates, hardy-security, hardy-backports and hardy-proposed # Package: * Pin: release a=stable,n=lenny Pin-Priority: 990 Package: * Pin: release a=testing Pin-Priority: 600 Package: * Pin: release a=unstable Pin-Priority: 300
When running testing, I would set lenny to 300, testing to 990 and unstable to 600. If you wonder what the numbers mean, I’ve copied this from the apt_preferences(5) man page
P > 1000 causes a version to be installed even if this constitutes a downgrade of the package
990 < P <=1000 causes a version to be installed even if it does not come from the target release, unless the installed version is more recent
500 < P <=990 causes a version to be installed unless there is a version available belonging to the target release or the installed version is more recent
100 < P <=500 causes a version to be installed unless there is a version available belonging to some other distribution or the installed version is more recent
0 < P <=100 causes a version to be installed only if there is no installed version of the package
P < 0 prevents the version from being installed
Pinning packages
You can also pin packages from specific releases or versions.
Package: hello Pin: release n=lenny Pin-Priority: 995 # Or to a specific version Package: hello Pin: version 2.2-2 Pin-Priority: 990 # Or to anything in version 2.2, eg 2.2-4 Package: hello Pin: version 2.2* Pin-Priority: 990
You can see this here:
hello:
Installed: (none)
Candidate: 2.2-2
Package pin: 2.2-2
Version table:
2.4-3 990
600 ftp://ftp.nl.debian.org testing/main Packages
990 ftp://ftp.nl.debian.org unstable/main Packages
2.2-2 990
990 ftp://ftp.nl.debian.org lenny/main Packages
Setting a package to a Pin-Priority above 1000 you will force a downgrade of a package when the version you want to be installed has a lower version then the currently installed package. If you do this, please execute aptitude -s install PACKAGENAME to see the consequences of that action. Please note that the package version pin preference is present on all versions, see this debian bug comment for more information.
Third-party repositories
Third party repositories could interfere with your regular preferences file, it will update packages which you don’t want to update. To remedy this, you can use apt-cache policy to determine some information about the repository.
$ apt-cache policy
# truncated for readability
500 http://ppa.launchpad.net jaunty/main Packages
release v=9.04,o=LP-PPA-ultrafredde,a=jaunty,n=jaunty,l=Ubuntu,c=main
origin ppa.launchpad.net
# Everything from launchpad Package: * Pin: origin ppa.launchpad.net Pin-Priority: 600 # One particular PPA Package: * Pin: release o=LP-PPA-ultrafredde Pin-Priority: 600
You can now install packages and be sure they are not upgraded when you don’t want them to. Just fiddle with your preferences file and you can mix and match your system to your liking.
If you want to install packages which would normally not be installed, you can force aptitude to install other versions:
# Based on version, will install regardless of preferences file (assume prio 999) aptitude install hello=2.4-3 # Based on release, will install with prio 990 aptitude install -t stable hello # Based on release, will install regardless of preferences file (assume prio 999) aptitude install hello/testing
We are now going to deny package installations from all launchpad origins but allow task to be installed. Task comes from a launchpad PPA.
# Deny everything from launchpad Package: * Pin: origin ppa.launchpad.net Pin-Priority: -10 # Allow task Package: task Pin: origin ppa.launchpad.net Pin-priority: 990 # Or based on the PPA itself: Package: task Pin: release o=LP-PPA-ultrafredde Pin-priority: 990
With 3 small lines you can maintain a mixed system, Ubuntu 8.10 mixed with some 9.04 or Debian testing with unstable, or the otherway around. You can add PPA’s without having to worry about if it will update packages that you don’t want to be upgraded.



Great blog post! Thanks. It would help me get started using apt/preferences if you gave a specific example for Ubuntu. My task atm is to use eclipse from karmic (9.10) on my jaunty box without upgrading jaunty.
From your article, I understand that I will need to create /etc/apt/preferences. Will the contents of that file look like this?
# Allow Eclipse from Karmic on my Jaunty system
Package: eclipse
Pin: release a=karmic
Pin-priority: 990
I have also added the following line in /etc/apt/apt.conf.d/01ubuntu
APT::Default-Release “jaunty”;
And finally, I have created /etc/apt/sources.list.d/eclipse-repos.list with these 3 lines:
deb http://ppa.launchpad.net/eclipse-team/ppa/ubuntu karmic main
deb-src http://ppa.launchpad.net/eclipse-team/ppa/ubuntu karmic main
deb http://ppa.launchpad.net/yogarine/eclipse/ubuntu karmic main
How close am I to having this correct?
Hi,
you are very close, the only thing you still need to do is to deny the Karmic repo’s not to update other applications. See http://ubuntuforums.org/showthread.php?p=8494501#post8494501
The example is based on using the official repo’s and not the PPA’s. The task example in the article shows what you need to implement.