如何在不删除其依赖项的情况下降级软件包?

我有一些Mesa软件包,我已经升级到PPA版本,然后清除了PPA以便升级我的系统。这些版本之间的差异很小(从技术上讲它们是相同的,只是一个库来自git,另一个是最终版本)。
如果我尝试通过Synaptic、apt-get或aptitude降级,我会陷入依赖地狱。
有没有办法手动降级软件包(也许逐个降级),并将它们的依赖软件包标记为不可移动(如果这样说得通的话),直到我完成为止?
附注:这个问题:如何通过apt-get降级软件包?有点不同,对于这种情况没有帮助。

为什么你不先使用ppa-purge呢? - landroni
你可以重新安装这个软件包。例如,如果你使用synaptic,当你选择xyz软件包时,默认情况下会选择所有依赖项。但是你也可以取消选择所有依赖项,只安装主要的软件包。之后你可以安装所有的依赖项。但是请注意,这只适用于你准备重新安装的情况。 - Registered User
@landroni 如果我进行清理,它会删除我不想删除的软件包。 - RolandiXor
3个回答

我以前从未玩过这个,但我建议你“保持”(或“锁定”)导致问题的依赖版本。这样一来,apt就有了更少的可能解决方案,也许在你尝试降级其他软件包时不会混淆。
如果其他方法都不起作用,你可以尝试本答案中建议的手动方法:如何通过apt-get降级软件包?。基本上,手动下载所需的.deb软件包,然后使用较低级别的dpkg和其强制参数之一逐个安装它们:--ignore-depends--force-depends--force-depends-version,甚至是--force-all
在与上述相同的精神下,你还有--force-downgrade参数。
          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.

但这假设你已经阅读了man dpkg,并且你明白自己在做什么:
          Warning: These options are mostly intended to be used  by
          experts  only.  Using  them  without  fully understanding
          their effects may break your whole system.

请参考以下示例:错误:版本号不以数字开头如何安装旧版Java如何安装类似liquid 2.2.2的旧版软件包?
sudo dpkg --force-downgrade -i your_mesa_package.deb

并参见如何在不安装某些依赖项的情况下安装软件包?以及相应的警告的示例。
sudo dpkg --force-all -i your_mesa_package.deb

另一种方法是使用equivs软件包创建一个虚拟的.deb软件包(可能使用稍微不同的名称)。然后安装这个虚拟软件包应该允许您删除“真正”的软件包,同时保留相关的依赖项,然后安装旧版本。我不确定具体的操作步骤,但可以查看这个相关主题以获取详细信息:如何在不删除其依赖项的情况下删除deb软件包

你可以先使用apt-mark命令将目标软件包的所有依赖关系(以及可能的推荐/建议的依赖关系)标记为手动安装。完成后,使用apt-get命令显式地安装先前版本的软件。
列出目标软件包的依赖关系、建议安装和推荐软件包: apt-cache show 将软件包标记为“手动安装”: sudo apt-mark manual (对所有依赖、建议和推荐都使用此命令)
删除目标软件包: sudo apt-get remove 查看可以降级/升级的软件包版本列表: apt-cache policy 安装所需软件包的目标版本: sudo apt-get install = 或者 sudo apt-get -t= install

附注:如果依赖项/推荐项/建议项包列表过长,即需要用apt-mark标记的包,请将所需的打包输出的目标包名称apt-cache show <target-package-name>保存到任何文件中,如/path/to/foo,并在组合中使用apt-mark,如下:

cat /path/to/foo | xargs -imarkthese sudo apt-mark manual markthese

这种方法可能有效,但是我选择了另一个答案,而不是标记100多个包裹。 - RolandiXor
1@RolandiXor,您可以使用“apt-cache policy <目标软件包名称>”获取可降级/升级的软件包版本列表。 - rusty
请参考对帖子所做的编辑;如果需要标记更多的文件,您可以使用包含的命令组合。 - rusty
我觉得你没有理解我的意思。不管怎样,现在问题已经解决了,我也已经发放了奖励(无法更改)。 - RolandiXor

我刚刚经历了升级软件包到上游版本然后决定降级的痛苦。这是通过维护人员的私有存储库完成的。在我的情况下,这一切都是为了尝试最新的systemd 233版本(尚未发布)。

关键是要理解您需要指定所有应该降级的软件包。如果您做得正确,apt将按照您的意愿执行操作。如果您漏掉了某些内容,apt会告诉您该操作将导致许多软件包被删除。为了确保安全,我们在实际执行降级操作之前使用“-s”标志进行测试。

您需要执行以下步骤:

1)列出所有升级到上游的依赖项(如果您的情况不同,请使用其他关键字):

dpkg -l|grep upstream

这将为您提供带有上游版本号的软件包列表。

2)列出每个软件包的正确稳定版本:

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)双重检查一切都没问题:

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.

(不确定是否需要使用--reinstall,但这是我所做的)
4)去掉-s并执行。
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

我使用了这种方法,还事先记录下了所有要从Synaptic(另一个软件包管理器)降级的软件包和版本,使用过滤器已安装(本地或过时)。我安装了一些开发包,它们比标准仓库中的版本更新。(Ubuntu Jammy。) - julian-alarcon