I totally feel the pain of this guy!! Some answers were given, but as someone who is dealing with the same problems, I feel they are inadequate. To help anyone with similar issues, even though it is marked as solved, I would like to add some extra pointers, not mentioned here.
How to get Debian to do what you want, without breaking it?
He had 2 main issues:
1) no usable dependency tree can be printed
The answer was: "yeah, there is none, deal with it"
So what can be done?
already mentioned:
aptitude why <package>
aptitude why-not <package>
# 1-liner, shortened (omitted elements in the chain):
aptitude -v --show-summary=all-packages why <package>
# what depends on this package:
aptitude search '~i~D<package>'
# what would happen, if <package> is removed:
# -s : simulate mode
aptitude -s purge <package>
# the packages that are immediately dependent on this one:
apt-cache rdepends <package>
# build a recursive dependency tree, no pretty-formatting, no indication of installed/manual/auto/etc.
apt-cache rdepends --recurse <package>
# reverse dependency chain:
apt install apt-rdepends
# NOTE: it seems to be broken (did not generate any output for me)
#apt-rdepends -r <package> | less
# what depends on this
apt-cache depends <package>
# build a recursive dependency tree, no pretty-formatting, no indication of installed/manual/auto/etc.
apt-cache depends --recurse <package>
2) metapackages make uninstalling parts of the system impossible
So, you made the mistake of selecting metapackages - which was the easy choice at _install_ time -, now you want to upgrade a single package, but it has some weird dependency of some obscure component you have never used, but if you remove it, the whole gnome will go down with it! Bummer.
So, what can you do?
"gnome" is a metapackage, which pulls in stuff you need, and stuff you don't need, but other people may.
Why everything goes hellish, when you try to remove "gnome"?
The answer is the installed packages have a qualifier "manual" or "auto". To the package manager, manual means "this guy went the extra mile to manually type in the command to install this package, pretty sure s/he needs it badly, we should not touch it! - unless maybe if it is an apt dist-upgrade".
First, how to see what is installed manually?
apt-mark showmanual | sort
aptitude search '~i !~M' -F '%p' | sort
NOTE: Many of these obscure aptitude commands I pulled from answers on the net, without understanding them, their output seems ok, but I would not know, if they are broken after an upgrade. So I tend to use the apt stuff, at least I can easily look those args up in the manual.
Second, how to discard the "manual" flag?
apt-mark auto <package>
What do you do with this?
a) get the offending metapackage
b) mark it as "auto"
c) remove it - well, not. If you remove it now, all the packages installed because of it will be removed, as well! (or at least they will be vulnerable to "apt autoremove")
d) use "apt depends <metapackage>" or "apt(-cache) show <metapackage>" to find the packages that are immediately dependent on the metapackage, and mark them "manual":
apt install <dependent-package1> <dependent-package2> ...
-- there are likely more metapackages down the road, until you isolate the problem-branch enough, not to break stuff you use, so these steps are recursive, but they will get the job done of pinpointing the branch you don't need anymore, while leaving you with the stuff you actually want to use.
Alternatively, you can
aptitude install <package>
and keep typing "n<ENTER>" until a good solution turns up. The problem is, aptitude honors "manual" more than "auto", so with a package like "gnome", you will stuck with hundreds of weird options, and the outputs overflow the screen...
NOTE: There is a shiny new "apt" interface (no "-get" or "-cache" suffix), however, sometimes it sucks. They tried to make it more human readable, but it became less scriptable. The cases I encounter daily:
apt search <package>
-> every 3rd line of the output is an empty line
-> the package description is on a separate line
=> cannot use "apt search <some_generic_term_I_vaguely_remember_from_the_package_name> | grep <some_other_keyword_I_hope_is_in_the_description>"
solution: just use
apt-cache search <clue1> | grep <clue2> | less # then /clue1<ENTER> to highlight "clue1" for readability
e.g. ncurses-something-python, or python-something-ncurses, or python-something with a mention of curses?
apt-cache search python | grep curses | less # /curses<ENTER>
apt show <package>
-> this will output info on every single version available for this package, you may want exactly this
=> the problem is, you don't know which of these are installed / would be installed... sometimes it will overflow your screen... so you have to use the mouse, and another window with more commands to find the part of the output you are interested in, and actually see it on screen...
"just print that package info that is installed/would be installed":
apt-cache show <package>
APPENDIX 1)
You just need that software to be able to work, you don't care about the whole packaging / versioning, you know it won't harm your system, and you don't want to spend days getting the dependencies straight. Also, you don't want to install stuff out of the packaging system, because you want to be able to remove stuff cleanly. What to do?
apt install checkinstall
a) download source
b) check homepage / source README/BUILD guide for dependencies
c) ./configure && make
d) checkinstall -> this will call "make install" in a separated environment, create a .deb package AND install that package right away (as in "dpkg -i <package>)
A local repo for this stuff may be in order, so 3 weeks later you still have a clue, where this package came from, why is it there, etc.:
cat /etc/apt/sources.list <<END
### LOCAL ###
# local packages
# does not have a "Release" file, recent debian won't touch it
deb [trusted=yes] file:/usr/local/debs/ DEBS/
END
mkdir -p /usr/local/debs/DEBS
cp <package> /usr/local/debs/DEBS
cd /usr/local/debs
dpkg-scanpackages DEBS | gzip -9c > DEBS/Packages.gz
apt update
NOTE: I have never looked into it, if checkinstall detects conflicts. Like files overwriting each other in /usr/share, or something like that.
APPENDIX 2)
For stuff like nvidia-drivers: where the package branch is kinda separated, and also you just kinda want to see if it works at all, but you don't want to run "NVIDIA-....run" directly because you don't exactly trust them that they nailed the uninstalling, in case something goes wrong. While I am at the point of trying that, I did not quite finish with trying this method, you can try creating a custom package by gutting out the stable package you already have, and put the new content in there. This will cheat the dpkg system to believe everything is perfect version-wise, and you have the option to seriously mess up your system, or succeed where no path was shown before.
Here is how you create a backport:
https://wiki.debian.org/SimpleBackportCreation
On the downside, for a package-branch like nvidia's non-free, you may have to backport a bunch of packages...
Again, I am just researching this method now, so I don't know, in exactly which cases it may be helpful.
You used chroot, which is nice. When experimenting on your base system (because you don't mind reinstalling from scratch), you may want to do this:
First you should do a backup of your system. This is not a safe restore point, you need it to confirm that your system is indeed in a safe state after uninstalling the wreckages of the latest failed attempt - in case you don't want to reinstall everything right away, just in case. So don't do a compressed backup, do a backup you can easily "diff -rq / /path/to/backup" later.
APPENDIX 3)
apt-pinning: Don't do that. I said DON'T DO THAT!!! I had a few tries with it, had it for a long time, it is destined to end with an unupgradable system. Unupgradeable as in:
- obscure errors about "held" packages, "broken" packages, but you find none on your system...
- you want to return to stable, but it just does not work...
- you want to move up to sid, but it does not work, either
- there is a new stable version, but apt dist-upgrade fails
- aptitude cannot seem to solve the problem without uninstalling every single package you have
- you manually try to fix stuff, forcefully delete packages, cry in a corner
- until you realize doing a clean install is actually pretty quick (hope you have some notes on the packages you installed and loved, along with instructions how to configure everything to your taste...)
=> because of this, use the methods I mentioned previously, since those are more likely to do localized damage to your system, if any, while apt-pinning will nuke it into a tangled mess.
# a few methods to search for held packages:
dpkg --audit
dpkg --get-selections | grep hold
aptitude search "~ahold"
# find installed packages that have issues (like broken - "b", "rc" means it is apt remove-ed, but the config files are still there, use apt purge to get rid of those):
dpkg -l | grep -v '^ii'
# find orphaned packages, which are auto installed, but nothing depends on them anymore (useful after a dpkg --purge <package>)
deborphan
debsums
aptitude search ~b
# check for deviations from the original package contents
debsums_init
debsums -c
apt-get install reinstall <changed packages>