Removal of unused dependencies using "autoremove"
I thought running apt-get autoremove
without any following argument removes all unused dependencies left on the system, while running apt-get autoremove xxx
removes xxx and its unused dependencies.
However I discovered otherwise. Running apt-get autoremove xxx
not only removes xxx and its unused dependencies, it also removes all other unused dependencies.
I then tried running apt-get remove --auto-remove xxx
, thinking that this would remove only xxx and its unused dependencies. To my surprise, this also removed xxx, its unused dependencies, and all other unused dependencies.
This leads me to two related questions.
(1) Is this the intended behaviour of the commands?
(2) Is there an easy way to remove xxx and its unused dependencies without removing other unused dependencies?
(It appears that aptitude remove
also behaves in a similar way.)
Solution 1:
Looking in the file cmdline/apt-get.cc
from the source tarball at http://packages.ubuntu.com/source/maverick/apt, I can see that --auto-remove
is an argument which enables the APT::Get::AutomaticRemove
setting.
The commands autoremove
and remove
both calls the function DoInstall
.
The command "autoremove" sets APT::Get::AutomaticRemove
too and it does therefore the same thing as --auto-remove
.
Looking in the DoAutomaticRemove
function, it's clearly visible that enabling the APT::Get::AutomaticRemove
setting (--auto-remove
and autoremove
does this) causes Apt looping through all installed packages and marks unused packages for deletion.
From main()
:
CommandLine::Args Args[] = {
// ... stripped to save space
{0,"auto-remove","APT::Get::AutomaticRemove",0},
// ...
}
CommandLine::Dispatch Cmds[] = { // ...
{"remove",&DoInstall},
{"purge",&DoInstall},
{"autoremove",&DoInstall},
// ...
}
// ...
// Parse the command line and initialize the package library
CommandLine CmdL(Args,_config);
From DoInstall()
:
unsigned short fallback = MOD_INSTALL;
if (strcasecmp(CmdL.FileList[0],"remove") == 0)
fallback = MOD_REMOVE;
else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
{
_config->Set("APT::Get::Purge", true);
fallback = MOD_REMOVE;
}
else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
{
_config->Set("APT::Get::AutomaticRemove", "true");
fallback = MOD_REMOVE;
}
From function DoAutomaticRemove
:
bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
// ...
// look over the cache to see what can be removed
for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg) {
if (doAutoRemove) {
if(Pkg.CurrentVer() != 0 &&
Pkg->CurrentState != pkgCache::State::ConfigFiles)
Cache->MarkDelete(Pkg, purgePkgs);
else
Cache->MarkKeep(Pkg, false, false);
}
}
I cannot speak whether it's intended or not, you could fill a bug / ask a question at launchpad.net.
At the moment, it is not possible to exclude packages from deletion by apt-get autoremove
. If you want to keep packages, run apt-get -s autoremove
, copy the packages from the list and remove the packages from that list you want to keep. Finally, remove those packages: sudo apt-get purge [packages-to-be-removed]
(purge removes the configuration files too, if any)