Differences between revisions 1 and 24 (spanning 23 versions)
Revision 1 as of 2006-06-03 15:50:07
Size: 1878
Editor: ?Andreas Fester
Comment:
Revision 24 as of 2011-02-21 12:29:57
Size: 4418
Editor: BenFinney
Comment: Be more straightforward about disadvantages of simple replacement
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Sometimes, it is necessary for a package to get a new name. Although this should rather seldom be the case, there are some situations when it makes sense, for example when the name of the upstream application changes. Of course an ''apt-get dist-upgrade'' should still seamlessly upgrade the package, best by completely removing the old package and installing the new one as a replacement.
Line 3: Line 4:
Sometimes, it is necessary for a package to get a new name. Although it should rather seldom be the case, there are some situations when this makes sense, for example when the name of the upstream application changes. Of course an ''apt-get dist-upgrade'' should seamless upgrade the package, best by completely removing the old package and installing the new one as a replacement. == Method 1 (only useful in very easy cases) ==
Line 5: Line 6:
One method is to just have the new package provide, replace and conflict the old
package.
Line 6: Line 9:
== Method A == This has disadvantages:

 * If there are versioned depends on the old package, they will break.
 * Most package managers (including APT, as of 2011-02-21) do not know to replace the old with the new one and will only use the new package if it is installed for some other reason.

== Method 2 ==

Basically, the solution is to define a binary dummy package with the same name as the old package in the control file of the new package. The new source package takes over the binary dummy package, and the old source package, which is then binaryless, will be cleaned up by {{{rene}}}, an archive cleanup tool.

Assume that the last upstream version of the old package "oldname" was 1.5 and the package was renamed to "newname" for version 2.0.

Then, the dummy package is defined like this in debian/control:
Line 8: Line 23:
 Package: oldpkg
 Depends: newpkg
 Version: 1.0
 Package: oldname
 Depends: newname
 Architecture: all
 Sect
ion: oldlibs
Line 13: Line 29:
This entry defines the binary dummy package. It will get version 2.0-1 and automatically be pulled in by an {{{apt-get dist-upgrade}}} if an earlier version of oldname was already installed.

The package only installs the mandatory files in /usr/share/doc/oldname
and possibly some compatibility symlinks, see below.

Since it depends on newname, it also installs the new package.

Note that the package does not contain any architecture specific files anymore and therefore the Architecture is set to "All", even if it was "Any" before.

If you set the section of the dummy package to oldlibs, tools like deborphan
will suggest removal of the package once there aren't any more reverse-dependencies installed.

The new package is defined like this:
Line 14: Line 44:
 Package: newpkg
 Replaces: oldpkg (<< 1.0)
 Package: newname
 Replaces: oldname (<< 2.0-1~)
 Conflicts: oldname (<< 2.0-1~)
Line 18: Line 49:
== Method B == You can also add a {{{Provides:}}} entry. But that will only help for unversioned depends anyway and there is the transitional package to
keep the reverse depends working.
Line 20: Line 52:
There is an even more elegant way which installs less files and effectively provides a real replacement mechanism. Please make sure that you use the proper version to conflict against.
You must make sure that you conflict against all versions which still
have the files in the old package. Especially if you split it between
two debian revisions, you must add a debian revision and not only conflict
against older upstream versions. (Or you will stumble across bugs like
[[DebianBug:397993|#397993]]).
Line 22: Line 59:
The dummy package is defined like this in {{{debian/control}}}: === compatibility symlinks ===
Line 24: Line 61:
{{{
 Package: oldpkg
 Depends: newpkg
}}}
If your new package also changes some interfaces to users or other packages,
for example the package name changed because the program name changed, you
might want to add compatiblity symlinks. Those can either be placed in the
old or the new package. If the symlink there there to stay, place it in the
new package (so users can remove the transitional package and still have it).
If the symlink is supposed to go away, placing it in the old package has the
advantage that users can choose to have it or not (of couse make sure to
give the old package a proper description stating that it contains that
compatibility) and that there is an easy way to see which other packages
still need to change (things depending on the old name may need the compatbility
symlink, while things depending on the new name must call it with the new name).
As packages that have been in a release will need to have the transitional
package in the next release, that extra information is especially useful if
the package never released so the transitional package can be removed soon
or if there are chances the transition to the new name will take more than
one release to have all reverse-dependencies fixed).
Line 29: Line 78:
The dummy package only installs a link (and nothing else!) like {{{/usr/share/doc/oldpkg -> /usr/share/doc/newpkg}}}, for example with the dh_link debhelper script.

The new package is defined like this in {{{debian/control}}}:

{{{
 Package: newpkg
 Replaces: oldpkg
 Provides: oldpkg
}}}

The new package installs all its necessary files and the same link as the dummy package, {{{/usr/share/doc/oldpkg -> /usr/share/doc/newpkg}}}

Now, when an earlier version of the oldPkg is installed and the system is upgraded with {{apt-get dist-upgrade}}, the new version of the dummy package is installed which pulls in the new package newPkg. The link is then taken over by newPkg, so that no installed files remain for the old dummy package oldPkg. {{{dpkg}}} is aware of this situation and notices that oldPkg is now completely replaced. However, through a bug in dpkg, it tries to configure the old dummy package at a later time, which fails because the package was already removed. Thus, at least for etch, this approach can not be used.
This page used to describe a method trying to get rid of the transitional
package automatically by removing all it files. If you are intrested why
this does not work at all, take a look at the history of this page.
 
 . CategoryDeveloper

Why?

Sometimes, it is necessary for a package to get a new name. Although this should rather seldom be the case, there are some situations when it makes sense, for example when the name of the upstream application changes. Of course an apt-get dist-upgrade should still seamlessly upgrade the package, best by completely removing the old package and installing the new one as a replacement.

Method 1 (only useful in very easy cases)

One method is to just have the new package provide, replace and conflict the old package.

This has disadvantages:

  • If there are versioned depends on the old package, they will break.
  • Most package managers (including APT, as of 2011-02-21) do not know to replace the old with the new one and will only use the new package if it is installed for some other reason.

Method 2

Basically, the solution is to define a binary dummy package with the same name as the old package in the control file of the new package. The new source package takes over the binary dummy package, and the old source package, which is then binaryless, will be cleaned up by rene, an archive cleanup tool.

Assume that the last upstream version of the old package "oldname" was 1.5 and the package was renamed to "newname" for version 2.0.

Then, the dummy package is defined like this in debian/control:

 Package: oldname
 Depends: newname
 Architecture: all
 Section: oldlibs
 Description: transitional dummy package

This entry defines the binary dummy package. It will get version 2.0-1 and automatically be pulled in by an apt-get dist-upgrade if an earlier version of oldname was already installed.

The package only installs the mandatory files in /usr/share/doc/oldname and possibly some compatibility symlinks, see below.

Since it depends on newname, it also installs the new package.

Note that the package does not contain any architecture specific files anymore and therefore the Architecture is set to "All", even if it was "Any" before.

If you set the section of the dummy package to oldlibs, tools like deborphan will suggest removal of the package once there aren't any more reverse-dependencies installed.

The new package is defined like this:

 Package: newname
 Replaces: oldname (<< 2.0-1~)
 Conflicts: oldname (<< 2.0-1~)

You can also add a Provides: entry. But that will only help for unversioned depends anyway and there is the transitional package to keep the reverse depends working.

Please make sure that you use the proper version to conflict against. You must make sure that you conflict against all versions which still have the files in the old package. Especially if you split it between two debian revisions, you must add a debian revision and not only conflict against older upstream versions. (Or you will stumble across bugs like #397993).

If your new package also changes some interfaces to users or other packages, for example the package name changed because the program name changed, you might want to add compatiblity symlinks. Those can either be placed in the old or the new package. If the symlink there there to stay, place it in the new package (so users can remove the transitional package and still have it). If the symlink is supposed to go away, placing it in the old package has the advantage that users can choose to have it or not (of couse make sure to give the old package a proper description stating that it contains that compatibility) and that there is an easy way to see which other packages still need to change (things depending on the old name may need the compatbility symlink, while things depending on the new name must call it with the new name). As packages that have been in a release will need to have the transitional package in the next release, that extra information is especially useful if the package never released so the transitional package can be removed soon or if there are chances the transition to the new name will take more than one release to have all reverse-dependencies fixed).

This page used to describe a method trying to get rid of the transitional package automatically by removing all it files. If you are intrested why this does not work at all, take a look at the history of this page.