6.1 The File Diff

An upgrade replaces one installed version of a package with another. It is conceptually a single atomic operation combining an install of the new version with an uninstall of the old, arranged so that no moment leaves the system without the package's content.

The same procedure handles a downgrade. The two differ only in which version comparison applies; the format treats them identically.

6.1.1 The four categories #

An upgrade is computed as a diff between the old version's file set, read from the package database, and the new version's, read from the new package's files manifest.

CategoryMeaningAt commit
AddedIn the new set, not the oldStaged and renamed in
ReplacedIn both, with different contentOld renamed aside, staged renamed in
UntouchedIn both, with identical content hashLeft alone
RemovedIn the old set, not the newRenamed aside

An untouched file keeps its inode: nothing is staged for it and no rename runs. It still gets an ownership row under the new version, so the upgrade's file set is complete and a later uninstall removes it.

Two conditions narrow the category, both of them cases where a file's content is not the only thing being installed at that path:

  • The file must actually be present. One the operator deleted is not untouched, and an upgrade is the right moment to put it back.
  • A path carrying a signature sidecar or a §3.3.5 descriptor override is always rewritten. Both are applied to the staged inode, so the path needs one even when its content has not moved.

6.1.2 Ordering at commit #

Added files are renamed into place. Replaced files have their original renamed aside first, then the staged file renamed in. Removed files are renamed aside.

A directory the previous version owned that the new payload does not carry is released, and reclaimed after commit if it is then unowned and empty (§6.6).

Edit this page