An important rules that every package maintainer should follow is to avoid directly upstream code modification.

The Right Way is to create a set of patches to be applied to upstream code at package build-time; this will let diff.gz contains only changes inside debian/ directory, which is a Good Thing.

A common tool to manage patches for packaging is dpatch.

0. Basic tasks

First of all, you have to install dpatch:

# apt-get install dpatch

and add dpatch to Build-Depends in debian/control . Moreover, you have to create the directory debian/patches: that will be the place where all patches will be stored.

In the same directory, there will be a file, debian/patches/00list: this will include a list of <patch_file_names> and the patches will be applied with the same order which are in that file.

1. Create a patch

The previous installed package, contains a useful tool, dpatch-edit-patch:

  1. enter the package source directory
  2. execute dpatch-edit-patch <patch_name>

this will create a copy of source package, and will open a shell on that copy; do your changes and exit from the shell: file debian/patches/<patch_name> will be created with changes you’ve done.

Remember to update file debian/patches/00list.

A good practice is to add copyright note to patches: you can use a (example) policy where you put trivial patches on « public domain » and the program license for the ones you’d like to forward upstream.

2. Convert a patch

This script (thanks to Charles Plessy) takes modified and original file, creates a patch in unified format and then convert it to dpatch format.

diff -u source-tree-original/the-file source-tree/the-file | \
dpatch patch-template -p « <number>_<short_description> »   \
« <what the patch does> » > path/to/debian/patches/<number>_<short_description>.dpatch

(replace <tags> with meaningful thing).

Usually patch (mainly the one sent throu BTS) are sent as a file: to convert such a patch, replace diff -u … with cat /path/to/file.patch and that’s all.

3. Test a patch

Ok, you’ve just forged a patch, but how to test if it does what it needs to do? Apply it!

From inside the extracted source package (the working copy for package creation) execute

dpatch apply-all

and to revert

dpatch deapply-all

a

4. Use dpatch in debian/rules

Now, we have only left to instruct debian/rules to apply patches (in the order listed in debian/patches/00list) from debian/patches/ .

I think, the easiest way is to modify debian/rules this way:

include /usr/share/dpatch/dpatch.make

build: build-stamp
build-stamp: patch-stamp

build stuff here

clean: unpatch

clean stuff here

But if you want, you can explicitly include patch/unpatch target as in this example:

build-stamp: patch

build stuff here

clean: clean1 unpatch
clean1:

clean stuff here

patch: patch-stamp
patch-stamp:
dpatch apply-all -v
#dpatch call-all -a=pkg-info >patch-stamp

unpatch:
dpatch deapply-all
rm -rf patch-stamp debian/patched

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install patch unpatch \
clean1

Anyway, I suggest to follow the first way, which is cleaner a less error prone.

5. Restore pristine upstream code

The very first thing every Debian package maintainer has to rememeber is: NEVER change upstream code in your package, use patches. Even if you follow this Master Rule when packaging a tool by yourself, you may face upstream code changes when adopting a pacakge.

There is a way you can convert such changes (done by previous package maintainer) in a dpatch patch:

  1. obtain package source code, using apt-get source <pkg> or whatever you want; we suppose the source package is uncompressed in <pkg-ver> directory: go into that (note that source file are in the parent directory)
  2. change debian/rules as specified in the previous chapter of this article
  3. use dpatch-convert-diffgz: this tool takes .diff.gz, extract changes done on upstream files and convert them in a dpatch file, to be applied during package building

If you manage your packages the old way (no source code versioning system), you’ve done. I use Subversion to maintain my source packages, and that requires some additional steps:

  1. download source package from debian repository mirror
  2. extract to a temporary directory, <tempdir> (or let apt-get source do that for you)
  3. import into SVN repository (it will checkout <workdir>)
  4. go into <tempdir> and setup debian/rules as needed (do the same setup on debian/rules in <workdir>)
  5. execute dpatch-convert-diffgz 01 restore_pristine_code (you can choose whatever name you prefere); this will create files debian/patches/01_restore_pristine_code.dpatch and debian/patches/00list
  6. move both previous files into <workdir> and add them to repository
  7. revert back to pristine version source files modified by previous maintainer: this could mean copy the file by hand (cp -p ….) from an uncompressed upstream tarball or maybe executing fakeroot debian/rules patch ; fakeroot debian/rules unpatch (last way is NOT guaranteed).

It’s a little bit complex, but this way you can adopt a package and use dpatch: that’s good 🙂