128

In accordance with man pages:

  • apt has parameter full-upgrade
  • apt-get has parameter dist-upgrade.

Are both the same command?

btw: which is officially the recommended command in Ubuntu 16.04? apt or apt-get?

1

6 Answers 6

77

apt full-upgrade performs the same function as apt-get dist-upgrade.

man apt

full-upgrade (apt-get(8)) performs the function of upgrade but will remove currently installed packages if this is needed to upgrade the system as a whole.

man apt-get

dist-upgrade in addition to performing the function of upgrade, also intelligently handles changing dependencies with new versions of packages; apt-get has a "smart" conflict resolution system, and it will attempt to upgrade the most important packages at the expense of less important ones if necessary. The dist-upgrade command may therefore remove some packages. The /etc/apt/sources.list file contains a list of locations from which to retrieve desired package files. See also apt_preferences(5) for a mechanism for overriding the general settings for individual packages.

9
  • 10
    Why create confusion with a new name that does the same thing? You can do either apt dist-upgrade (I just tried it) or you can do apt full-upgrade and you are saying they do the same thing.
    – Z boson
    Jan 24, 2017 at 20:56
  • 24
    "full-upgrade" is about removing installed packages when necessary, while "dist-upgrade" is about "intelligently handling changing dependencies with new versions of packages", how is it the same function ?
    – Tristan
    Jan 25, 2017 at 12:06
  • 5
    itsfoss.com/apt-vs-apt-get-difference
    – schod
    Jul 12, 2017 at 8:16
  • 14
    It's the same function. It's just an alias in apt for the apt-get command. sources.debian.org/src/apt/1.6.1/cmdline/apt.cc/?hl=74#L74 (the actual macro invoked seems to be missing from the repo though). May 14, 2018 at 0:44
  • 15
    @Zboson The reason for the new name is that the "dist-upgrade" name was itself extremely confusing for many users: while it was named that because it was something you needed when upgrading between distribution releases, it sounded too much as though it was only for use in that circumstance, whereas in fact it's much more broadly applicable. May 19, 2019 at 23:17
77

Yes they are the same command. This part of apt's cmdline/apt.cc proves it:

static std::vector<aptDispatchWithHelp> GetCommands()            /*{{{*/
{
   return {
      // [snip]
    
      // system wide stuff
      {"update", &DoUpdate, _("update list of available packages")},
      {"upgrade", &DoUpgrade, _("upgrade the system by installing/upgrading packages")},
      {"full-upgrade", &DoDistUpgrade, _("upgrade the system by removing/installing/upgrading packages")},
    
      // misc
      {"edit-sources", &EditSources, _("edit the source information file")},
      {"moo", &DoMoo, nullptr},
    
      // for compat with muscle memory
      {"dist-upgrade", &DoDistUpgrade, nullptr},
    
      // [snip]
   };
}

And for completeness, cmdline/apt-get.cc:

static std::vector<aptDispatchWithHelp> GetCommands()           /*{{{*/
{
   return {
      // [snip]
      {"dist-upgrade", &DoDistUpgrade, _("Distribution upgrade, see apt-get(8)")},
      {"full-upgrade", &DoDistUpgrade, nullptr},
      // [snip]
   };
}

For both apt and apt-get, full-upgrade and dist-upgrade both refer to the same DoDistUpgrade function and therefore do the same thing except that apt has a different default option here:

After packages are successfully installed by apt(8), the corresponding .deb package files will be removed from the /var/cache/apt/archives cache directory

APT::Keep-Downloaded-Packages can control this behavior for apt-get.

Bonus investigation

@Lii raised a good point that DoDistUpgrade could act differently based on the binary used (i.e. argv[0]). The code is much less straightforward than I expected because there are a number of layers to consider and global variables, but let's have a look.

The ParseCommandLine function is used for both binaries. The function does these steps where the command line could have an impact:

  1. InitLocale(Binary): same code for all cases.

  2. pkgInitConfig(**Cnf): all cases use the extern Configuration *_config global variable.

  3. BinarySpecificConfiguration(argv[0]): now this is interesting. apt has these meaningful default options that are different to apt-get:

    1. APT::Get::Upgrade-Allow-New = true. That's the --with-new-pkgs option to apt-get enabled by default. This is documented in apt's manual, but the impact here is only on the upgrade command.
    2. APT::Keep-Downloaded-Packages = false. This is an actual difference between apt and apt-get and is explained in the NEWS file:

    [ Automatic removal of debs after install ] After packages are successfully installed by apt(8), the corresponding .deb package files will be removed from the /var/cache/apt/archives cache directory.

    [...]

    Please note that the behavior of apt-get is unchanged. The downloaded debs will be kept in the cache directory after they are installed.

  4. BinaryCommandSpecificConfiguration(argv[0], CmdCalled) both binaries do the same thing for all these commands: "upgrade", "dist-upgrade", "full-upgrade".

  5. _config->MoveSubTree(conf.c_str(), nullptr) applies options prefixed by Binary::apt::apt or Binary::apt::apt-get depending on the binary used.

Other irrelevant steps omitted.

The DispatchCommandLine function then ends up calling the DoDistUpgrade handler.

Later in the callstack there's this interesting part in DoCacheManipulationFromCommandLine() line 681:

     bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;

     bool resolver_fail = false;
     if (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
        resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);

Here again, both binaries with either command perform the same steps.

Perhaps I missed something, but that's where I'm stopping this investigation.

5
  • Judging only from the given source code snippets it is not 100 % clear that they do the same thing. They could for example do mostly the same thing, but also contain if-statements that do different things depending on arguments to the function.
    – Lii
    Jan 17, 2023 at 10:09
  • That's true, but if you look further in private-cmndline.cc (salsa.debian.org/apt-team/apt/-/blob/1.6.12/apt-private/…), you can inspect how the std::vector<aptDispatchWithHelp> instance returned by GetCommands() is used and you'll see that the Handler function of aptDispatchWithHelp is called directly and can't know what it's called from (unless it checks the stack perhaps or uses some other unexpected operation).
    – bernie
    Jan 22, 2023 at 13:01
  • But it seems like DoDistUpgrade takes as an argument the list of command line argument? It could check the contents of the command line arguments and figure out if dist-upgrade or full-upgrade was used. It probably doesn't and I think your conclusion is correct, but it is a bit tricky to be 100 % sure...
    – Lii
    Jan 23, 2023 at 15:09
  • I investigated further and found a difference between apt and apt-get. I updated my answer to capture this.
    – bernie
    Jan 24, 2023 at 23:25
  • Ah, interesting! Code is tricky...
    – Lii
    Jan 25, 2023 at 7:55
6

Use apt as a first choice, but if you're scripting use apt-get. Apt-get has more stable output (meaning that the output format is left alone as much as possible so as not to break scripts which parse that output automatically). Apt-get also has some low-level commands not available in apt.

The manual pages for apt and apt-get describe full-upgrade and dist-upgrade a little differently, but they are probably the same command (apt accepts dist-upgrade as an alias of full-upgrade). This serves as a good example of apt-gets stability. In apt, the name was changed to be more user friendly, while in apt-get the name remains unchanged so as not to break compatibility with old scripts.

2

apt and apt-get are two different commands. apt is the newer command and should be used as default. You should change to using apt over apt-get as apt is better.

3
  • 10
    Why/how is it better?
    – mafrosis
    Jul 10, 2019 at 10:29
  • 5
    From apt man page: The apt(8) commandline is designed as an end-user tool and it may change behavior between versions. While it tries not to break backward compatibility this is not guaranteed either if a change seems beneficial for interactive use.
    – Lokesh
    Nov 29, 2019 at 5:56
  • 9
    I disagree, on should use apt if one uses it directly from the command line. But use apt-get in scripts. This because the latter has a stable command line interface, but the former might change as mentioned by Lokesh. Apt is not better it is just meant to be more user friendly Feb 11, 2020 at 15:25
1

Difference is output:

**apt

  • full-upgrade

**

root@eesti-ThinkPad-T420:/home/eesti/apollo11# apt full-upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following package was automatically installed and is no longer required:
  shim
Use 'sudo apt autoremove' to remove it.
0 uuendatud, 0 värskelt paigaldatud, 0 eemaldada ja 0 uuendamata.

**apt-get

  • dist-upgrade

**

root@eesti-ThinkPad-T420:/home/eesti/apollo11# apt-get dist-upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following package was automatically installed and is no longer required:
  shim
Use 'sudo apt autoremove' to remove it.

*The following packages could receive security updates with UA Infra: ESM service enabled:
  libpam0g libdjvulibre-text bluez libwebp5 libdns-export162 libqpdf21 gstreamer1.0-alsa libisccfg140 intel-microcode libnss3-tools linux-headers-generic linux-libc-dev php7.0-cli vim-common libx11-xcb-dev libnss3-nssdb libcurl3 python-avahi libxml2-utils libgrilo-0.2-1 gstreamer1.0-plugins-base-apps libpam-modules openssl ruby2.3 bluez-cups imagemagick ntfs-3g git-man libsystemd0 linux-image-generic libgd3 libavahi-glib1 nginx-core libicu55 binutils libmagickwand-6.q16-2 squashfs-tools bind9-host php7.0-opcache linux-signed-image-generic libavahi-common-data dnsutils libavahi-common3 libpython3.5 python3.5 php7.0-common git openssh-sftp-server python3.5-minimal libisc160 udev gstreamer1.0-plugins-base libpam-runtime isc-dhcp-common python3.5-dev apache2-data libx11-6 linux-signed-generic nginx-common libudev1 libwebpdemux1 libavahi-ui-gtk3-0 libaspell15 libapr1 apport imagemagick-6.q16 libmagickcore-6.q16-2-extra php7.0-json libisc-export160 libudev-dev libruby2.3 libcaca0 php7.0-readline python3-apport avahi-daemon systemd-sysv libcurl4-openssl-dev libavahi-core7 libgcrypt20 liblwres141 vim-runtime liblz4-1 vim libpam-systemd libgstreamer-plugins-base1.0-0 distro-info-data libsndfile1 avahi-dnsconfd gstreamer1.0-x systemd libpython3.5-dev gir1.2-gst-plugins-base-1.0 libssl-dev libssl-doc libwebpmux1 mysql-common libpam-modules-bin openssh-server libx11-data aspell libopenexr22 openssh-client libmagickcore-6.q16-2 python-libxml2 libmysqlclient20 avahi-autoipd libdns162 libx11-dev qpdf libx11-doc bluez-obexd libdjvulibre21 apport-gtk libxml2 libnss3 apache2-bin ca-certificates vim-tiny imagemagick-common libisccc140 avahi-utils libpython3.5-stdlib libbind9-140 libbluetooth3 libexiv2-14 libavahi-compat-libdnssd1 apache2 libpython3.5-minimal libavahi-client3 apache2-utils curl isc-dhcp-client avahi-discover rpcbind linux-generic libapache2-mod-php7.0 python3-problem-report libcurl3-gnutls libx11-xcb1 libssl1.0.0 tzdata docker.io nginx
Learn more about UA Infra: ESM service for Ubuntu 16.04 at https://ubuntu.com/16-04

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

0 uuendatud, 0 värskelt paigaldatud, 0 eemaldada ja 0 uuendamata.
root@eesti-ThinkPad-T420:/home/eesti/apollo11# 

So as You can See, it is not really "the same"

0

Apt is the newer version of the command. You should switch to using apt instead of apt-get. It's better and gives a better idea of what the command is doing.

As for apt full-upgrade and apt-get dist-upgrade it's the same command. But again apt is the newer command.

For example when using apt you get a progress bar to tell you how much of the install/update is done.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .