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:
- enter the package source directory
- 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
and to revert
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:
build stuff here
clean stuff here
But if you want, you can explicitly include patch/unpatch target as in this example:
build stuff here
clean: clean1 unpatch
clean stuff here
dpatch apply-all -v
#dpatch call-all -a=pkg-info >patch-stamp
rm -rf patch-stamp debian/patched
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install patch unpatch \
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:
- 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)
- change debian/rules as specified in the previous chapter of this article
- 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:
- download source package from debian repository mirror
- extract to a temporary directory, <tempdir> (or let apt-get source do that for you)
- import into SVN repository (it will checkout <workdir>)
- go into <tempdir> and setup debian/rules as needed (do the same setup on debian/rules in <workdir>)
- 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
- move both previous files into <workdir> and add them to repository
- 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 🙂