Selecting the right version can be quite complex as there are many conditions that need to be considered. The following paragraphs first link to the required basics, which are shared with Debian. Then each paragraph explains situationis that might occur in an upload to Ubuntu.
While Debian docs won't include Ubuntu specificities, it is helpful to fully read through Debian control field "Version" for overall topic awareness.
When Ubuntu adds a change or modification on top on what is in Debian, that change is expressed in the version number.
One can think of a version number consisting of three segments: [upstream_version]-[debian_revision]ubuntu[ubuntu_revision]
.
The -
splits the upstream version from the Debian packaging segment as you have seen in Debian control field "Version".
The ubuntu
string then marks that whatever follows it is related to changes added in Ubuntu.
This distinction allows each party involved in providing a package to the users — Upstream, Debian and Ubuntu — to modify and iterate on their section of the version number without interfering with others. When everyone abides by these conventions we can guarantee package upgradability, but also allow that one can derive a lot of the history by just looking at the package version.
As shown above [upstream_version]-[debian_revision]ubuntu[ubuntu_revision]
is the basic pattern.
Changes in the development release will always add or increment the number that directly follows the ubuntu
string.
Therefore, if this is the first Ubuntu change, one would append ubuntu1
as an Ubuntu suffix.
If there was already an Ubuntu change, one would increment the suffix like ubuntu1 -> ubuntu2
.
Finally if formerly there has already been one (or many) no change rebuilds there might be a buildX
suffix which is in this case replaced by ubuntu1
.
More about this in the later section about no change rebuilds.
Example in detail: Adding a change to
2.0-2
in the Ubuntu development release will use2.0-2ubuntu1
Example in detail: Adding another change to
2.0-2ubuntu1
in the Ubuntu development release will use2.0-2ubuntu2
List of these and further related examples:
Previous version | Recommended version |
---|---|
2.0-2 | 2.0-2ubuntu1 |
2.0-2ubuntu1 | 2.0-2ubuntu2 |
2.0-2ubuntu2 | 2.0-2ubuntu3 |
2.0-2build2 | 2.0-2ubuntu1 |
Note: While being the common case, please consider reading further about more special cases which can lead to different results.
If Ubuntu has delta to the package from Debian, it can not be automatically synced otherwise that delta would be lost. In that case an Ubuntu developer regularly merges the delta (usually at least once per Ubuntu release) that is in Ubuntu with the content from Debian and indirectly also with the changes by upstream.
The counter for Ubuntu increments resets to 1, therefore the version for the new upload to the Ubuntu development is the version from Debian with a suffix of ubuntu1
Example in detail: Uploading
3.1
to Ubuntu -Devel based on Debian3.1-2
retaining former Ubuntu delta of2.1-1ubuntu2
would become3.1-2ubuntu1
List of this and further related examples:
Old-Debian | Old-Ubuntu | New-Debian | Ubuntu Devel |
---|---|---|---|
2.1-1 | 2.1-1ubuntu2 | 3.1-2 | 3.1-2ubuntu1 |
1:7.0+dfsg-7 | 1:7.0+dfsg-7ubuntu14 | 1:8.0.4+dfsg-1 | 1:8.0.4+dfsg-1ubuntu1 |
The mentioned special case of an upstream merge is triggered when Ubuntu merges directly from upstream ahead of Debian upstream. In this case the new version shall:
- Reflect that it was not yet packaged in Debian (at this point in time) and thereby is not really based on a Debian version by using
-0
as the Debian version suffix. - Represent that there are Ubuntu changes via
ubuntu1
which also serves as a place increment for further uploads to the development release.
Example in detail: Uploading
3.1
to Ubuntu -Devel while Debian is not yet at3.1
so we pick3.1
followed by-0
representing it is not based on Debian andubuntu1
to index and iterate changes to Ubuntu to an overall3.1-0ubuntu1
.
List of this and further related examples:
Old-Debian | Old-Ubuntu | New-Debian | New-Upstream | Ubuntu Devel |
---|---|---|---|---|
2.1-1 | 2.1-1 | unchanged | 3.1 | 3.1-0ubuntu1 |
2.1-1 | 2.1-1ubuntu2 | unchanged | 3.1 | 3.1-0ubuntu1 |
2.1-1 | 2.1-1ubuntu2 | unchanged | 2.3 | 2.3-0ubuntu1 |
Version: Adding a change in Ubuntu as a stable release update
After a version of Ubuntu is released, changes to packages follow a slightly different versioning scheme which ensures upgradability to later releases and allows the history of changes to be recognized from just looking at the version.
The only change from the normal ubuntu version scheme is to the ubuntu revision section of [upstream_version]-[debian_revision]ubuntu[ubuntu_revision]
.
- Increment Y in the numeric
ubuntuX.Y
suffix, like:ubuntu3.1 -> ubuntu3.2
. - Never increment X in the numeric
ubuntuX.Y
suffix. An Ubuntu delta is always captured in Y. - If this is the first change via the SRU process, add the
.1
suffix, like:ubuntu3 -> ubuntu3.1
. - If no
ubuntuX
was present before, then setubuntu0.1
which will represent that there was no Ubuntu delta (0
) before this upload which is the first to add a change (.1
). - If two releases have the same version, then this would make the package non upgradeable and cause a version conflict (two builds, but not the same). To resolve this, add the numeric
YY.MM
release version in betweenubuntuX
and the increment.1
. For Jammy that might look like...ubuntu3.22.04.1
Compare these examples with the adding a change in the current Ubuntu development release section above to better see the subtle difference.
Example in detail: Adding a change to
2.0-2
in an Ubuntu stable release update will use2.0-2ubuntu0.1
.
Example in detail: Adding an Ubuntu delta to
2.0-2ubuntu2.4
in an Ubuntu stable release update will use2.0-2ubuntu2.5
.
List of these and further related examples:
Previous version | Recommended version |
---|---|
2.0-2 | 2.0-2ubuntu0.1 |
2.0-2ubuntu0.1 | 2.0-2ubuntu0.2 |
2.0-2ubuntu2 | 2.0-2ubuntu2.1 |
2.0-2ubuntu2.1 | 2.0-2ubuntu2.2 |
2.0-2build1 | 2.0-2ubuntu0.1 |
2.0 | 2.0ubuntu0.1 |
2.0-2ubuntu0.22.04.1 | 2.0-2ubuntu0.22.04.2 |
2.0-2 in two releases | 2.0-2ubuntu0.11.10.1 and 2.0-2ubuntu0.22.04.1 |
2.0-2ubuntu1 in two releases | 2.0-2ubuntu1.11.10.1 and 2.0-2ubuntu1.22.04.1 |
There exist packages in which Debian or Ubuntu are themselves the upstream.
This is due to the classification as native or non-native package as outlined by the referred Debian control field version and in more detail Debian source packages.
To quote "Presence of the debian_revision
part indicates this package is a non-native package. Absence indicates the package is a native package."
Due to that in a Debian native package, there is no -debian_revision
.
This continues into native Ubuntu packages, which have neither -debian_revision
nor ubuntu[ubuntu_revision]
.
Example in detail: _A package native to Debian
2.0
(no-
), getting an Ubuntu change in the devel release would use2.0ubuntu1
Furthermore native package versioning is package dependent; whether if it uses only major, or a major.minor, or any other version pattern is the maintainer's choice. Just as usually upstream can and will version software the way they consider the best. Due to that selecting the right subsequent version requires you to check the package history or confer with its maintainer.
Example in detail: A package native to Ubuntu
2.0
(no-
and noubuntuX
) getting an Ubuntu change in the devel release would use2.1
or3.0
Yes that means, from just the version, you can not differentiate between a native Debian package that was synced and a native package in Ubuntu.
List of these and further related examples:
Previous version | Devel upload | SRU upload |
---|---|---|
2.0 (native in Debian) | 2.0ubuntu1 | 2.0ubuntu0.1 |
2.0 (native in Ubuntu) | 2.1 or 3.0 | 2.0ubuntu0.1 |
2 (native in Debian) | 2ubuntu1 | 2ubuntu0.1 |
2 (native in Ubuntu) | 3 | 2ubuntu0.1 |
2.0ubuntu2 | 2.0ubuntu3 | 2.0ubuntu2.1 |
2.0build1 | 2.0ubuntu1 | 2.0ubuntu0.1 |
2.0build2 | 2.0ubuntu1 | 2.0ubuntu0.1 |
Note: The rule of multiple releases having the same version requiring to add also a per-release YY.MM to differentiate and ensure upgradability might apply here as well.
Ubuntu continuously syncs changes from Debian until the Debian import freeze date is met, then syncs are deactivated to stabilize the upcoming Ubuntu release. As outlined in these references there "will be automatically imported from Debian where they have not been customized for Ubuntu, that is when the version number of the package in the current Ubuntu development branch does not contain the substring ubuntu".
And as we learned in Adding a change in the current Ubuntu development release
above adding a change in Ubuntu will add a ubuntuX
suffix, which prevents the automatic synchronisation process, which thereby will ensure Ubuntu is not unintentionally losing these changes.
But what if one needs to rebuild a package as-is, for example due to a library transition to build against new versions of other packages, but does not want to prevent future automatic syncing of new versions from Debian? Well, just rebuilding is not considered a change that has to be retained, so in this special case one would:
- Not add
ubuntuX
and instead add abuildX
suffix. - If there is already one such
buildX
suffix present, increment it. - If there is already an
ubuntuX
suffix there would be no auto-sync anyway, so increment the existing suffix.
So far it is weakly defined if a no change rebuild for native packages shall be a version increment or adding a buildX
suffix.
Both styles are present in the archive and both will work just fine.
Until this is properly defined one should try to follow what the particular package used so far.
Example in detail: A Debian package
2.0-2
needs a rebuild in Ubuntu which would use2.0-2build1
List of this and further related examples:
Previous version | No change rebuild in devel |
---|---|
2.0-2 | 2.0-2build1 |
2.0-2ubuntu2 | 2.0-2ubuntu3 |
2.0-2build1 | 2.0-2build2 |
2.0 (native in Ubuntu) | 2.1 or 3 or 2.0build1 |
2 (native in Ubuntu) | 3 or 2build1 |
2.0 (native in Debian) | 2.0build1 |
2 (native in Debian) | 2build1 |
It is unlikely, but possible that one needs a no change rebuild as part of a Stable release update, but in this situation auto-syncing isn't active anyway and the need for upgradability applies. So a no-change-rebuild in regard to picking a version number in this case is identical to any other change (see the section (adding a change in Ubuntu as a stable release update)[VersionStrings.md#version-adding-a-change-in-ubuntu-as-a-stable-release-update] above).
There are more special cases, especially related to backports (as in backports of new versions via SRU, not as in https://wiki.ubuntu.com/UbuntuBackports).
In the rare case of a new upstream release being pushed to all stable releases it will lose all its former version suffixes. This is a common practice on some minor release exception processes, where we pick up the most recent upstream content, but avoid regressions/changes due to packaging changes like moving files, splitting or removing binary packages etc. To represent this the upload should:
- Signal that it is not based on a Debian packaging version by using
-0
as the Debian packaging revision. - Signal that it was not yet packaged before in this Ubuntu release before via
ubuntu0.
. - Add a suffix per Ubuntu release like
.22.04
. - Add an increment that can be used in subsequent individual per release SRU uploads like
.1
.
Example in detail: Uploading
3.1
but packaging-wise using what is already in LTS and LTS+1 -- not with all the Ubuntu changes that might be in3.1-1ubuntu2
.
List of this and further related examples:
Old | New | |
---|---|---|
LTS | 2.0-2 | 3.1-0ubuntu0.22.04.1 |
LTS+1 | 2.7-2ubuntu1 | 3.1-0ubuntu0.22.10.1 |
LTS+2 | 2.7-2ubuntu1 | 3.1-0ubuntu0.23.04.1 |
The new version is independent of the former version of the target release, here is a list of examples targeting 22.04:
Previous | New upstream | Upload for LTS |
---|---|---|
2.0-2 | 3.1 | 3.1-0ubuntu0.22.04.1 |
2.0-2ubuntu2 | 3.1 | 3.1-0ubuntu0.22.04.1 |
2.0-2ubuntu2.1 | 3.1 | 3.1-0ubuntu0.22.04.1 |
2.0-2build1 | 3.1 | 3.1-0ubuntu0.22.04.1 |
But if instead the backport is actually without meaningful differences to what is in the current Ubuntu development release (a common practice for some packages that keep the same version everywhere) with only minimal backporting adaptations it would instead:
- Signal that is it basically identical but backported by starting with the same version as the one in the development release.
- Add a
~
to ensure it sorts earlier than the version in -devel. - Add a suffix per Ubuntu release like
22.04
. - Add an increment that can be used in subsequent individual per release SRU uploads like
.1
.
Example in detail: Uploading
3.1
to LTS and LTS+1 being more or less identical to what is in -devel in3.1-1ubuntu2
.
List of this and further related examples:
Old | New | |
---|---|---|
LTS | 2.0-2 | 3.1-1ubuntu2~22.04.1 |
LTS+1 | 2.7-2ubuntu1 | 3.1-1ubuntu2~22.10.1 |
LTS+2 | 2.7-2ubuntu1 | 3.1-1ubuntu2~23.04.1 |
The new version is again independent of the former version that was present in the target release, here examples targeting 22.04:
Previous | New Dev | Upload for LTS |
---|---|---|
2.0-2 | 3.1-1ubuntu2 | 3.1-1ubuntu2~22.04.1 |
2.0-2ubuntu2 | 3.1-1ubuntu2 | 3.1-1ubuntu2~22.04.1 |
2.0-2ubuntu2.1 | 3.1-1ubuntu2 | 3.1-1ubuntu2~22.04.1 |
2.0-2build1 | 3.1-1ubuntu2 | 3.1-1ubuntu2~22.04.1 |
Note: If in this case the package in the Ubuntu development release is a native package one would still use the same version as in the development release.
Example in detail: Uploading
3.1
to LTS and LTS+1 being more or less identical to what is in -devel in3.1
.
List of this and further related examples:
Old | New | |
---|---|---|
LTS | 2.0-2 | 3.1~22.04.1 |
LTS+1 | 2.7-2ubuntu1 | 3.1~22.10.1 |
LTS+2 | 2.7-2ubuntu1 | 3.1~23.04.1 |
In a very rare case where an upgrade to a new upstream version of a package
caused major regression and the only way out is rolling back, the convention is
to insert +really
followed by the actual version number.
To be clear, both should be used sparingly and only if really needed. Please also have a look at +really in control fields.
Example in detail: Uploading
3.1
caused a regression, so rolling back to the previous version2.0-2ubuntu2
would use3.1+really2.0-2ubuntu2
List of this and further related examples:
Before | Current | Upload |
---|---|---|
2.0-2ubuntu2 | 3.1-2ubuntu1 | 3.1+really2.0-2ubuntu2 |
7.80+dfsg1-5 | 7.91+dfsg1-1 | 7.91+dfsg1+really7.80+dfsg1-1ubuntu1 (Ubuntu upload) |
7.80+dfsg1-5 | 7.91+dfsg1-1 | 7.91+dfsg1+really7.80+dfsg1-1 (Debian upload) |
7.80+dfsg1-5 | 7.91+dfsg1-1 | 7.91+dfsg1+really7.80+dfsg1-1ubuntu0.1 (Ubuntu SRU) |