Debian Packaging Handbook/ PatchSystems

https://wiki.ubuntu.com/PackagingGuide/PatchSystems

Patch System

What is the need for patch systems

An important rule 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”. An we all know you want to be a “good” maintainer.

Common used patch Systems

Here below you can find some common used patch systems; every developer has his own preferred, so try them out and choose one. If the package you are editing already uses a patch system, use that one.

apt-cache showsrc thepackage | grep Build-Depends

look for dbs, dpatch, quilt, cdbs.

CDBS + Simple patch

TODO

dbs

Deprecated, use dpatch, cdbs, or quilt.

dpatch

Getting started with dpatch

The first thing you need to do is install dpatch:

# apt-get install dpatch

Then start modifying the package code to include dpatch. First, add to debian/control:

Build-Depends: …, dpatch, …

since you need it to build the package (it will apply patches at buildtime).

The directory debian/patches is where the patches and configuration files for dpatch are: the special file debian/patches/00list contains a list of <patch_file_names> (the same filenames in debian/patches), and the patches will be applied with the same order which are in that file.

Now you have to modify debian/rules to integrate dpatch; there are many ways to do that, the simplest is:

include /usr/share/dpatch/dpatch.make

<other targets>

build: build-stamp
build-stamp: $(DPATCH_STAMPFN)
        <do build stuff here>

clean: unpatch
        <do clean stuff here>

<other targets>

If you need to use the patched source code in the clean target too (usually you've patched upstream Makefile), then use:

include /usr/share/dpatch/dpatch.make

<other targets>

build: build-stamp
build-stamp: $(DPATCH_STAMPFN)
        <do build stuff here>

<other targets>

clean: clean-patched unpatch
clean-patched: $(DPATCH_STAMPFN)
        <do clean stuff here>

<other targets>

The trick is to patch before executing clean (needed since clean target is executed as the first thing during build time), then executing the patched clean target and at the end unapply patches (that will be reapplied executing build target).

The hardest/longest/not-encouraged is the following (it would allow some more flexibility):

build-stamp: patch-stamp
        <do build stuff here>

clean: clean1 unpatch
clean1:
        <do clean stuff here>

<other targets>

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

I would NOT suggest to use the latter way. Use one of the first two.

Create/Edit a 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: a file debian/patches/<patch_name> will be created with changes you've done. I can suggest to use a naming-convention like <number>_<patch_description> so that <number> is used to represent the patch application order and <patch_description> describes what the patch does.

Remember to update file debian/patches/00list, additionally you can use -0 option.

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 to dpatch

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 sensible things).

Usually patch (mainly the one sent through BTS) 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`
Restore Upstream Pristine Code

The very first thing every Debian package maintainer has to remember 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 package.

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 way 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. integrate dpatch into new package (as explained before);

  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. If you use a source code versioning system (like svn, cvs, git, etc), that requires some additional steps (this example is for svn):

  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 (this way could not work, try re-execute the command some times, if still not works, fall back to manual reversion).

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

quilt

Some info on quilt can be found on the Holger's wiki page.

debian-perl group kindly allow us to merge this page: http://pkg-perl.alioth.debian.org/quilt.html

from dpatch to quilt

http://blog.orebokech.com/2007/08/converting-debian-packages-from-dpatch.html

Patch copyright and licencing

TODO