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
Deprecated, use dpatch, cdbs, or quilt.
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
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: 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
and to revert
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:
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);
integrate dpatch into new package (as explained before);
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):
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 (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 :)
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
Patch copyright and licencing