June 5th, 2020

Hard Stare

Attempted answer to the FAQ: "Will `apt-get dist-upgrade` install a new Ubuntu release?"

In the context of the `apt` command, `update` means "refresh the database containing the current index of what versions are in the configured repositories". It does not install, remove, upgrade or change any installed software.

I wonder if this is because of people lacking historical context?

The important things to know are 3 concepts: dependencies, recursion, and resolution.

The first Linux distributions, like SLS and Yggrasil and so on, were built from source. You want a new program? Get the source and compile it.

Then package managers were invented. Someone else got the source, compiled it, bundled it up in a compressed archive with any config files it needed and instructions for where to put its contents on your computer.

As programs got more complex, they were built using other programs. So the concept of "dependencies" appeared. Let's say text editor "Superedit" can import RTF (Revisable Text Format) files, and save RTF (Rich Text Format) files. It does not read these formats itself: it uses another tool, rich_impex, and rich_impex needs rft_import and rtf_export.

(Note: RTF and RFT are real formats and they are totally different and unrelated. I picked them intentionally as their names are so similar.)

If you need a new version of Superedit, then you first need new version of rich_impex. But rich_impex needs rtf_import and rtf_export.

So in the early days of Linux with package managers, e.g. Red Hat Linux 4, if you tried to install superedit.2.rpm, it would fail, saying it needed rich_impex-1.1.rpm. This is called a dependency.

And if you tried to install rich_impex-1.1.rpm, it said you needed rft_import 1.5 and rtf_export 1.7.

So to install Superedit 2, you had to try, fail, note down the error, then go try to install rich_impex, which would fail, then note down the error, then go install rft_import 1.5, and rtf_export 1.7.

THEN you could install rich_impex 1.1.

THEN you would find that it was now possible to install superedit_2.rpm.

It was a lot of work. Installing something big, like KDE 1, would be almost impossible as you had to go find hundreds of these dependencies, by trial and error. It could take days.

Debian was the first to fix this. To its package manager, dpkg, it added another tool on top: apt.

Apt did automatic dependency resolution. So when you tried to install superedit 2, it would check and find that superedit-2 needed rich_impex-1.1 and install that for you.

This is no use if it does 1 level and stops. It would fail when it couldn't install rich_impex because that in turn had its own dependencies.

So what is needed is a tool that goes, installs your dependencies, and their dependencies, and their dependencies, all the way down, starting with the ends of each chain. This requires a  programming technique called recursion:

Now, let's imagine that superedit-2, which depends on rich_impex, which depends on rft_import and rtf_export.

But sadly, the maintainer of rft_import got run over by a bus and died. So, no new versions of rft_import. That means no new version of rich_impex which means no new version of superedit.

So someone comes along, reads the source code of rft_import, thinks they could do it better, and writes their own routine. They call it import_rft because they don't want to have to fix any bugs in rft_import.

The writer of rich_impex does a new version, rich_impex 2. They switch the import filter, so rich_impex 2 uses import_rtf 1.0 and rft_export 1.8.

Superedit 3 also comes out and it uses rich_impex 2. So if you want to upgrade from superedit 2 to superedit 3, you need to upgrade rich_impex 2 to v3. To get rich_impex 3, you need to remove rft_import and install a new dependency, import_rft.

When you start doing recursive solution to a problem, you don't know where it's going to go. You find out on the way.

So apt has 2 choices:

[1] recurse, install newer versions of anything needed, until you can upgrade the target package (which could be "all packages"), but don't add anything that isn't there


[2] recurse, install all newer versions of anything needed INCLUDING ADDING NEW PACKAGES, until the entire distribution has been upgraded

#1 is meant for 1 program at a time, but you can tell it to do all programs. But it won't add new packages.

So if you use `apt-get upgrade` you will not get superedit 3, because to install superedit 3, it will have to install rich_impex 2, and that means it would need to remove rft_import and install import_rft instead. `upgrade` won't do that -- it only installs newer versions. So your copy of superedit will be stuck at v2.

#2 is meant for upgrading the whole installed system to the latest version of all packages, including adding any new requirements it needs on the way.

If you do it, it will replace superedit 2 with superedit 3, because `dist-upgrade` has the authority to remove the rft_import module and install a different one, import_rft, in its place.

Neither of them will rewrite the sources listed in /etc/apt/sources.list. Neither of them will ever upgrade the entire distro to a new release. Neither of them will ever move from one major release of Ubuntu or Debian or Crunchbang or Mint or Bodhi or whatever to a new release.

All they do is update that version of the distribution to the newest version of that release.

"Ubuntu 20.04" is not a distribution. "Ubuntu" is the distribution. "20.04" is a release of the distribution. It's the 32nd so far. (W, H, B, D then through the alphabet from E to Z, then back to A. Now we're at F again.)

So `dist-upgrade` does not upgrade the release. It upgrades your whole DISTRO but only to the latest version of that release.

If you want a new release then you need `do-release-upgrade`.

Do not use `apt upgrade` for upgrading the whole distro; `apt dist-upgrade` does a more thorough job. `apt upgrade` will not install superedit 3 because it won't add new packages or remove obsolete ones.

In the old days, you should have used `apt-get dist-upgrade` because it will replace or remove obsoleted dependencies.

Now, you should use `apt full-upgrade` which does the same thing.

Relax. Rest assured, neither will ever, under any circumstances, upgrade to a new release.