Preventing Debian Package Upgrades

Posted by Steve on Fri 31 Dec 2004 at 22:45

The simple mechanism Debian has for performing package upgrades, apt-get, is often touted as a good thing and indeed it is. But sometimes you will have a package installed that you absolutely do not want to be upgraded.

There are two ways that you can achieve this, depending on what it is that you're trying to achieve.

If you have a locally modified package which you don't want to upgrade then you can put this on "hold". This means that even if a newer version of that package is available it will not be upgraded. Ever.

This does mean that you run the risk of being behind the curve, and missing out on a security fix, but that's something that you will have to deal with yourself.

If, for example, you don't wish to upgrade the package apache then you should run the following command as root:

echo "apache hold" | dpkg --set-selections

To remove the hold run this:

echo "apache install" | dpkg --set-selections

Rather than putting a package on hold, to prevent the whole thing from being upgraded, you might wish to make sure that a single binary contained within a package isn't upgraded.

This might be because you've made local changes and you can't investigate any diversions right now - you just want to keep your local version at the risk of losing out on future improvements to the Debian version.

The Debian packaging command, dpkg, has a system for diverting upgrades. With this system you can cause all upgrades which should happen to a file to be written elsewhere.

For example perhaps you've written a wrapper around gcc which applies some common options to all compilations, if you upgrade your copy of GCC then you'll lose this - so you wish to keep your local copy instead.

What you should do is divert the gcc script to another file, such as gcc.real :

dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc

Once you've done this you'll see that your installed version of GCC has been renamed, and any future upgrades of the GCC package will install to gcc.real instead.

Now you can place your wrapper in the file /usr/bin/gcc confident that it will be untouched on upgrade.

To remove the diversion you could run :

dpkg-divert --remove /usr/bin/gcc

This will rename the gcc.real back to gcc , and allow upgrades to occur as they would have done previously.