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:

  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. 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.

The steps to take:

  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 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:

  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 prefer); 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.

Building_Packages/TipsTricks/UsingDpatch (last edited 2008-03-11 23:58:20 by PeterDoes)