1

I have a bunch of packages "enhanced" by some Debian repository. Now I've disabled that repo from /etc/apt/sources.list.d and I want to re-install all packages that were "enhanced" to... whatever is available. I can get the list of packages just fine using grep, but

apt-get install --reinstall \ $(dpkg-query -Wf '${Version}\t${Package}\n' | grep SOMEREPO | awk '{print $2}' ) 

reports that those packages can't be downloaded. And of course they can't — not at their current version. --reinstall --downgrade is rejected by apt. It seems that the only way to downgrade is to name a specific version (which would require even more nasty scripting for a batch of packages).

Anything I'm overlooking? Maybe aptitude can do it?

Update: I know it can be done via pinning (thanks so much, mods!), but really, that's not a solution. It's laborious, and I don't care about which specific source the downgrade comes from. I want to downgrade to whatever is available from the currently-enabled sources.

Update 2: I'm using a Debian-derivative (MX Linux), so downgrades could come from

  • Debian buster
  • buster-backports
  • the distro-specific https://mirrors.*/mx/MX-Packages/mx/repo/
0

3 Answers 3

4

Pin-priorities are the solution; add this either to /etc/apt/preferences, or to a new file under /etc/apt/preferences.d:

Package: * Pin: release a=* Pin-Priority: 1001 

apt upgrade will install the latest version of any installed package that it knows about, even if it means downgrading. apt only knows about packages from the currently-configured repositories, after apt update, so this will have the desired effect.

1
  • This mostly worked wonders but for some reason it doesn't seem to downgrade all packages. Some were left at a version that's not available in any of the current repositories. I couldn't figure out why. Maybe something with dependencies. Commented Jul 5, 2024 at 2:42
2

This is what I came up with:

apt install $(apt-show-versions | grep newer | awk '{print $1}' | while read pkg; do ver="$(apt-cache madison "$pkg" | head -n1 | awk -F'|' '{gsub("\\s", "", $2); print $2}')"; printf "%s=%s\n" "$pkg" "$ver"; done) 

It works like this:

  1. Use apt-show-versions | grep newer | awk '{print $1}' to determine the list of packages that need to be downgraded:

    host ~ # apt-show-versions|grep newer libapache2-mod-php:all 2:8.3+94+0~20240205.51+debian11~1.gbp6faa2e newer than version in archive libapache2-mod-php8.2:amd64 8.2.18-1+0~20240411.52+debian11~1.gbp91aa2d newer than version in archive [...] 
  2. Use apt-cache madison (which seems to be an easier-to-parse alternative to apt-cache policy) to determine the most recent version of each package:

    host ~ # apt-cache madison libapache2-mod-php libapache2-mod-php | 2:8.2+93~iservbpo11+1 | https://update.iserv.eu/debian bullseye-stable/main amd64 Packages libapache2-mod-php | 2:7.4+76 | http://deb.debian.org/debian bullseye/main amd64 Packages 
  3. Construct a pkg=ver string for each package, ie libapache2-mod-php=2:8.2+93~iservbpo11+1 that instructs APT to install this specific version of the package, and pass all these strings to apt install.

1
  • awk '/ newer /{ print $1 }, the rest, I'd have to check, it's been a while. Cool though Commented Apr 18, 2024 at 19:56
1

For future reference, from the do as you're told, Debian department... After some furious scripting:

ps=$(for p in $(dpkg-query -Wf '${Version}\t${Package}\n' | grep REPO | awk '{print $2}'); do apt --quiet list $p | grep -v /now | grep / | awk '{print $1}' | head -1 done) # this still leaves some /oldstable,oldstable broken versions apt install --reinstall $(echo "$ps" | cut -f1 -d,) 

Not that I recommend it; it's just annoying when the system gets in the way of simple tasks.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.