Using dpatch
An important rule that every package maintainer should follow is to avoid direct 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 the diff.gz file only contain changes inside debian/ directory, which is a good thing.
A common tool to manage patches for packaging is dpatch.
Basic tasks
First of all, you have to install dpatch:
# sudo apt-get install dpatch
Next you need to add dpatch to Build-Depends in debian/control, and create the directory debian/patches, this is directory where all patches will be stored. In this directory, there will be a file, debian/patches/00list which will include a list of <patch_file_names> and this list will determine the order in which patches will be applied.
Create a patch
To create a patch we can use the 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. The file debian/patches/<patch_name> will be created with changes you did.
Remember: Update file debian/patches/00list with the patch name you created
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.
Convert a patch
This command (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 the <tags> with something meaningful.
Usually patches are sent as a file, to convert such a patch, replace diff -u with cat /path/to/file.patch and that's all.
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
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 is using dpatch.make
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.
Restore pristine upstream code
The very first thing every Debian package maintainer has to remember is: NEVER change upstream code in your package, use patches.
- If you adopt a package the previous maintainer may have made changes in the source code and you really want to remove these patches and convert them into a dpatch patch.
The steps to take:
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 without a source code managing system you're done. If you use a SCM, like Subversion, to maintain your source packages, you need to do 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 prefer); 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.
