deb-changelog(5)

πŸ’– deb-changelog(5) β€” the changelog glow-up guide πŸ’–

okay bestie, so this is a page from the dpkg suite manual, and it's literally the blueprint for deb-changelog(5) β€” like, the whole entire changelog file format for dpkg source packages. buckle up, it's giving "paper trail but make it cute" πŸŽ€


✨ NAME ✨

deb-changelog β€” the changelog file format for dpkg source packages, periodt.

🌸 SYNOPSIS 🌸

debian/changelog

that's it. that's the whole vibe. one file, so much lore. πŸ¦‹

πŸ’… DESCRIPTION πŸ’…

So every change in the packaged version of a project gets explained in the changelog file debian/changelog. And like β€” that includes the modifications made in the source package compared to the upstream one, plus all the other changes and updates to the package. no cap, it's all in there.

Why do we even care? Because the format of debian/changelog lets the package building tools discover which version of the package is being built, and find out other release-specific info. it's lowkey the receipts of the whole build. 🧾

The format is a series of entries, like this:

package (version) distributions; metadata
         [optional blank line(s), stripped]
 * change-details
   more-change-details
         [blank line(s), included in dpkg-parsechangelog(1) output]
 * even-more-change-details
         [optional blank line(s), stripped]
 -- maintainer-name <email-address>  date

Okay so breaking that down, because there's a lot going on bestie:

package and version are the source package name and version number. version is delimited by parenthesis U+00028 β€˜(’ and U+0029 β€˜)’.

distributions lists one or more space-separated distributions where this version should be installed when it's uploaded β€” and it gets copied to the Distribution field in the .changes file. Also distributions must be terminated by a semicolon (U+003B β€˜;’). don't forget the semicolon, i'm begging 😭

metadata lists zero or more comma-separated keyword=value items. Each keyword can contain only minus and case insensitive alphanumeric characters, because they need to be mapped to deb822(5) field names. The only keywords currently supported by dpkg are:

  • urgency β€” its value is used for the Urgency field in the .changes file for the upload. ⚑
  • binary-only β€” with a yes value, it's used to denote that this changelog entry is for a binary-only non-maintainer upload (an automatic binary rebuild with the only change being the changelog entry). iconic behavior honestly.

🫢 the change details section

The change details may be any series of lines starting with at least two spaces (U+0020 SPACE), but conventionally each change starts with an asterisk and a separating space, and continuation lines are indented so as to bring them in line with the start of the text above. Blank lines may be used here to separate groups of changes, if desired. do with that what you will πŸ’

πŸ› closing bugs (the fun part)

If this upload resolves bugs recorded in the distribution bug tracking system, they may be automatically closed on the inclusion of this package into the distribution archive by including this string:

Closes: #nnnnn

in the change details, where #nnnnn is the bug number. The exact Perl regular expression is:

/closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/i

That is, the string should consist of the word closes: followed by a comma-separated list of bug numbers. Bug numbers may be preceded by the word bug and/or a # sign, as in "Closes: 42, bug#43, #44, bug 45". The words closes: and bug are not case sensitive. And the list of bug numbers may span multiple lines. multi-line slay 🌈

This info is conveyed via the Closes field in the .changes file. Where, depending on the archive maintenance software, all the bug numbers listed might get automatically closed. (might! no promises, it's giving "depends on the vibes of the archive software")

πŸ‘‘ the maintainer + date trailer

The maintainer name and email address used in the changelog should be the details of the person who prepared this release of the package. They are not necessarily those of the uploader or usual package maintainer β€” main character energy, not necessarily the same main character. The format for the name and email address is described in deb-email(7). This info here will be copied to the Changed-By field in the .changes file, and then later might be used to send an acknowledgment when the upload has been installed in the distribution archive. cute, right? πŸ’Œ

The date has the following format (compatible and with the same semantics of RFC2822 and RFC5322, or what date -R generates):

    day-of-week, dd month yyyy hh:mm:ss +zzzz

where:

  • day-of-week β€” is one of: Mon, Tue, Wed, Thu, Fri, Sat, Sun.
  • dd β€” is a one- or two-digit day of the month (01-31), where the leading zero is optional, but conventionally does not get omitted.
  • month β€” is one of: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec.
  • yyyy β€” is the four-digit year (e.g. 2010).
  • hh β€” is the two-digit hour (00-23).
  • mm β€” is the two-digit minutes (00-59).
  • ss β€” is the two-digit seconds (00-60).
  • [+-]zzzz β€” is the time zone offset from Coordinated Universal Time (UTC). β€˜+’ indicates that the time is ahead of (i.e., east of) UTC and β€˜-’ indicates that the time is behind (i.e., west of) UTC. The first two digits indicate the hour difference from UTC and the last two digits indicate the number of additional minutes difference from UTC. The last two digits must be in the range 00-59.

⭐ the spacing rules (yes, they're strict)

The first β€œtitle” line with the package name must start at the left hand margin. The β€œtrailer” line with the maintainer and date details must be preceded by exactly one space (U+0020 SPACE). The maintainer details and the date must be separated by exactly two spaces (U+0020 SPACE). Each part of the date can be separated by one or more spaces (U+0020 SPACE), except after the comma where it can be separated by zero or more spaces (U+0020 SPACE). the way the spacing is doing the absolute most πŸ’€ but also valid.

πŸ™ˆ comments, modelines, and other oddities

Any line that consists entirely (i.e., no leading whitespace) of # or /* */ style comments or RCS keywords should be ignored.

Vim modelines or Emacs local variables, and ancient changelog entries with other formats at the end of the file should be accepted and preserved on output, but their contents might be otherwise ignored and parsing stopped at that point. it's giving "we keep it for the memories but we're not reading it" πŸ’œ

heads up bestie: the entire changelog must be encoded in UTF-8. no exceptions, no weird encodings, we don't do that here.

πŸŽ€ FILES πŸŽ€

  • debian/changelog

πŸ¦‹ EXAMPLES πŸ¦‹

dpkg (1.17.18) unstable; urgency=low

 [ Guillem Jover ]
 * Handle empty minimum versions when initializing dependency versions,
   as the code is mapping the minimum version 0 to '' to avoid outputting
   useless versions. Regression introduced in dpkg 1.17.17. Closes: #764929

 [ Updated programs translations ]
 * Catalan (Guillem Jover).

 [ Updated dselect translations ]
 * Catalan (Guillem Jover).
 * German (Sven Joachim).

 -- Guillem Jover <guillem@debian.org>  Sun, 12 Oct 2014 15:47:44 +0200

see how pretty that is? perfect indentation, bug closed, translators credited, date in the exact right format. ate and left no crumbs πŸ”₯

🌸 SEE ALSO 🌸

deb822(5), deb-changes(5), deb-email(7), deb-version(7), dpkg-parsechangelog(1).


sign-off szn: this page is from dpkg suite version 1.23.11-dirty, dated 2026-09-09. go forth and write changelogs that pass the vibe check πŸ’–βœ¨πŸŽ€
πŸ“¦ where this page comes from