The issue
When you must modify a file provided by a debian package, our version of the file will be overwrittent by default when updating the package (for files that aren't marked as "conffiles" that can be updated by the administrator).
To avoid overwriting our local changes, a diversion can be put in place to force the new version of the package to write the file to another location, thus preserving our changes to the original file.
Specific case
As an example, on a previous version of Debian testing, on systems using
systemd, the bind9
package had a bug (referenced as
bug #767798)
that prevented the named daemon from taking into account the options provided
by the administrator through variables defined in a configuration file.
Pending the correction of this bug, a simple workaround to the issue was
suggested by the person that opened the bug: adding a directive to the
systemd file /lib/systemd/system/bind9.service
responsible for starting the
named daemon to take into account the variables defined in the configuration
file that was previously ignored.
However, these changes to the bind9.service
file would be overwritten on each
update of the bind9
package which could, in some cases, prevent named from
restarting, and would make this workaround hazardous.
The solution
Installing a file diversion
The simpler solution to avoid a possible overwrite of the file was to install a diversion of the modified file until the bug was corrected in an upcoming version of the package, using the following command:
~# dpkg-divert --divert /lib/systemd/system/bind9.service.orig --rename /lib/systemd/system/bind9.service
Adding 'local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig'
Thanks to this diversion, the package writes its version of the file to
/lib/systemd/system/bind9.service.orig
, instead of overwriting the file
/lib/systemd/system/bind9.service
. (In our specific case, it's up to the
system administrator updating the package to check if the new version of the
file provides modifications worth applying to our own version of the file.)
Listing active file diversions
To see if a file diversion is indeed in action, the option --list
of the
dpkg-divert
command can be used to list the diversions in place for a file.
Its argument should be either the diverted file or the original file (which
could take the form of a glob parttern). For example:
~# dpkg-divert --list /lib/systemd/system/bind9.service.orig
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig
~# dpkg-divert --list /lib/systemd/system/bind9.service
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig
~# dpkg-divert --list *bind9.service
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig
Removing a file diversion
In our example of the bind9
package, once the bug was corrected by the
package, the diversion could be removed to once again use the version of the
file the package provides.
A file diversion can be removed using the --remove
option with the name of the
original file as argument.
In addition, either the option --rename
must be used to rename the file using
the diverted name to the original name (in which case the original file must
not exist or the removal will fail), or the option --no-rename
not to rename
the file.
~# dpkg-divert --remove --rename /lib/systemd/system/bind9.service
Removing 'local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig'