How can I downgrade packages without removing their dependants?
I have a number of mesa packages that I had upgraded to a PPA version, before purging the PPA so I could upgrade my system. The differences in the versions are minor (they are technically the same, just one set of libraries were from git and the others are the final versions).
If I try to downgrade via Synaptic, apt-get, or aptitude, I get thrown into dependency hell.
Is there a way to downgrade the packages manually (perhaps one by one) and mark their dependant packages as immovable (if that makes sense) until I am done?
P.S. this question: How to Downgrade a Package via apt-get? is a bit different and doesn't help this situation.
I never played with this before, but I would suggest that you hold
(or lock
) the version of the dependencies that cause you trouble. This way apt
has a more limited number of possible solutions, and perhaps doesn't get confused when you attempt to downgrade the other packages.
If nothing else works, you could take the manual approach suggested in this answer: How to Downgrade a Package via apt-get?. Basically, download the necessary .deb
packages manually, then install them one by one using the lower-level dpkg
and one of its forceful arguments: --ignore-depends
, --force-depends
, --force-depends-version
, or even --force-all
.
In the same spirit as the above, you have the --force-downgrade
argument:
downgrade(*): Install a package, even if newer version of
it is already installed.
Warning: At present dpkg does not do any dependency
checking on downgrades and therefore will not warn you if
the downgrade breaks the dependency of some other pack‐
age. This can have serious side effects, downgrading
essential system components can even make your whole sys‐
tem unusable. Use with care.
But this assumes that you've read man dpkg
, and that you understand what you do:
Warning: These options are mostly intended to be used by
experts only. Using them without fully understanding
their effects may break your whole system.
See Error: version number does not start with digit and How to install an older version of Java and How to install a older version of package like liquid 2.2.2? for examples of:
sudo dpkg --force-downgrade -i your_mesa_package.deb
And see How can I install a package without installing some dependencies? for an example (along with the appropriate warning) of:
sudo dpkg --force-all -i your_mesa_package.deb
Yet another approach would be to create a dummy .deb
package using the equivs
package (and perhaps a slightly different name). Then installing the dummy package should allow you to remove the "true" package while keeping the relevant deps, and then install the older version. I'm not sure how exactly this would work, but check this relevant thread for details: How to remove a deb without removing its dependencies.
You could first use apt-mark
to mark all the target package's dependencies (and maybe the recommended/suggested ones too) installed in the system as manual installs. After doing that, install the preceding versions of the software with apt-get
mentioning the version explicitly.
-
To list the dependency, recommended and suggested packages for the target-package:
apt-cache show <target-package-name>
-
Marking packages as manually installed:
sudo apt-mark manual <package-name(s)>
(use this for all dependencies, recommends and suggested.)
-
Remove the target-package:
sudo apt-get remove <target-package-name>
-
To see a list of package versions that you may downgrade/upgrade to, use:
apt-cache policy <target-package-name>
-
Install the target version of the required package:
sudo apt-get install <target-package-name>=<target-package-version-number>
or
sudo apt-get -t=<target release> install <target-package-name>
PS. If the list of dependencies/recommended/suggested packages i.e. those which are to be marked with apt-mark
is large, save the intended list of the packaged output by apt-cache show <target-package-name>
to any file say /path/to/foo
and use the apt-mark
in a combo like this:
cat /path/to/foo | xargs -imarkthese sudo apt-mark manual markthese
I've just gone through the ball pain of upgrading to an upstream version of a package and then deciding to downgrade. This was via a maintainers private repository. In my case this was all about trying out the latest systemd 233 version (yet unreleased).
The key is to understand that you need to specify all the packages that should be downgraded. If you get this right, chances are apt will do what you want. If you miss something out, apt will tell you that the action will cause lots of packages to get removed. To make sure we use the '-s' flag to try out the downgrade before actually doing it.
The steps you need to take are thus:
1) List all dependencies that were upgraded to upstream (use some other keyword if your situation is different):
dpkg -l|grep upstream
This gives you a list of packages with an upstream version number.
2) List what the correct stable version is for each package:
for i in libnss-resolve:amd64 libsystemd0:amd64 libpam-systemd:amd64 libsystemd0:i386 libudev1:amd64 libudev1:i386 systemd systemd-sysv udev; do apt-cache show $i; done|grep Version
3) Double check all is good:
apt -s --allow-downgrades --no-remove --reinstall install libnss-resolve:amd64=232-21ubuntu5 libsystemd0:amd64=232-21ubuntu5 libpam-systemd:amd64=232-21ubuntu5 libsystemd0:i386=232-21ubuntu5 libudev1:amd64=232-21ubuntu5 libudev1:i386=232-21ubuntu5 systemd=232-21ubuntu5 systemd-sysv=232-21ubuntu5 udev=232-21ubuntu5
0 to upgrade, 0 to newly install, 9 to downgrade, 0 to remove and 0 not to upgrade.
(not sure if --reinstall was required btw, but this is what I did)
4) Remove the -s and do it.
apt --allow-downgrades --no-remove --reinstall install libnss-resolve:amd64=232-21ubuntu5 libsystemd0:amd64=232-21ubuntu5 libpam-systemd:amd64=232-21ubuntu5 libsystemd0:i386=232-21ubuntu5 libudev1:amd64=232-21ubuntu5 libudev1:i386=232-21ubuntu5 systemd=232-21ubuntu5 systemd-sysv=232-21ubuntu5 udev=232-21ubuntu5