Caution
The Packaging and Development guide is currently undergoing a major overhaul to bring it up to date. The current state you are seeing now is a preview of this effort.
The current version is unstable (changing URLs can occur at any time) and most content is not in properly reviewed yet. Proceed with caution and be aware of technical inaccuracies.
If you are an experienced packager and would like to contribute, we would love for you to be involved! See our contribution page for details of how to join in.
Patch management¶
This article demonstrates how to manage the patches of a
source package in the 3.0 (quilt)
format.
See the patches explanation article for more background information about patches in the context of Ubuntu.
Note
If the format is 3.0 (native)
, this article is not of interest for you and
simply write your changes to the files. There is no need to explicitly create
and track a patch for native packages.
See the package model article for more
information about package formats.
As the source package format implies, we will use the quilt(1) tool
to manage the patches of a source package. Quilt manages patches like a
Stack. It maintains a list of patches (also called “series”)
that get applied one after another from top to bottom in the order
they are listed in debian/patches/series
, excluding lines starting with #
.
Important
Quilt will create a .pc/
directory at the source package root
directory. This is the location where Quilt will store control files
similar to the .git/
folder of a Git repository.
Before you commit any changes (e.g., with git-ubuntu) or attempt to build the source package, do not forget to unapply all patches and delete the directory:
quilt pop -a && rm -r .pc
You can avoid removing .pc
if it exists in the
.gitignore
file, or if you can otherwise avoid it when running
git add
.
Prerequisites¶
If you haven’t already, install quilt(1):
sudo apt update && sudo apt install quilt
By running the following script once in a terminal you will configure quilt(1)
to look for patches in the debian/patches/
directory if the quilt
command
is invoked within a source package directory:
cat <<'EOF' > ~/.quiltrc
#!/usr/bin/env bash
set -euo pipefail
# find the root of a debian source tree:
SourcePackageRoot="${PWD}"
while [ ! -s "$SourcePackageRoot/debian/source/format" ]
do
if [ "${SourcePackageRoot}" = '/' ]
then
echo -e '\033[1;33mWARNING\033[0m: You are not in a debian source tree!'
exit 0
fi
SourcePackageRoot="$(readlink --canonicalize-existing "${SourcePackageRoot}/..")"
done
if ! grep --silent --fixed-strings '3.0 (quilt)' \
"${SourcePackageRoot}/debian/source/format"
then
echo -e '\033[1;33mWARNING\033[0m: This source package does \033[1mNOT\033[0m use the 3.0 (quilt) format. The corresponding defaults defined in ~/.quiltrc do not get applied.'
exit 0
fi
# tell quilt where to find patches for a 3.0 (quilt) source package
: "${QUILT_PATCHES:="${SourcePackageRoot}/debian/patches"}"
# create the quilt control files directory at the root of the source package
: "${QUILT_PC:="${SourcePackageRoot}/.pc"}"
# default options for the patch(1) tool
: "${QUILT_PATCH_OPTS:="--reject-format=unified"}"
# how quilt output should be colored
: "${QUILT_COLORS:="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"}"
# set default arguments for quilt commands:
: "${QUILT_DIFF_ARGS:="-p ab --no-timestamps --no-index --color=auto"}"
: "${QUILT_PATCHES_ARGS:="--color=auto"}"
: "${QUILT_PUSH_ARGS:="--color=auto"}"
: "${QUILT_REFRESH_ARGS:="-p ab --no-timestamps --no-index"}"
: "${QUILT_SERIES_ARGS:="--color=auto"}"
EOF
Note
If you later want to undo this configuration – simply delete ~/.quiltrc
:
rm ~/.quiltrc
List patches¶
List all available patches:
quilt series
This will also color code which patches are applied (green), which patch is the latest applied patch (yellow) and which patches are unapplied (white).
List applied patches:
quilt applied
Display the topmost applied patch:
quilt top
List unapplied patches:
quilt unapplied
Note
Quilt patches are applied from top to bottom in the order they are listed.
Apply patches¶
Apply the next patch:
quilt push
Apply all patches:
quilt push -a
Apply the next N
patches
quilt push N
Apply all patches until (including) a specific patch:
quilt push PATCH-NAME
This can also be the path of the patch (allowing for auto-completion):
quilt push debian/series/PATCH-NAME
Unapply patches¶
This works similar to applying patches.
Unapply the patch on top:
quilt pop
Unapply all patches:
quilt pop -a
Unapply the N
topmost applied patches
quilt pop N
Unapply all patches until (excluding) a specific patch:
quilt pop PATCH-NAME
This can also be the path of the patch (allowing for auto-completion):
quilt pop debian/series/PATCH-NAME
Verify patches¶
Now that we know how to apply and unapply patches we can verify if all patches apply and unapply cleanly. This can be useful when you merge changes from Debian into an Ubuntu package and want to check if everything is still in order.
We verify that all patches apply cleanly:
quilt push -a
We verify that all patches unapply cleanly:
quilt pop -a
(optional) We remove the Quilt control file folder:
rm -r .pc
Show details about a patch file¶
Print the header of the topmost applied or specified patch:
quilt header [PATCH-NAME]
Print the list of files that the topmost applied or specified patch changes:
quilt files [PATCH-NAME]
Print the changes by the topmost applied or specified patch to the specified file(s) in a diff format. If no files are specified, all files that are changes are included.
quilt diff [-P PATCH-NAME] [FILE-PATH ...]
Rename a patch file¶
Rename the topmost applied or specified patch:
quilt rename [-P PATCH-NAME] NEW-PATCH-NAME
Remove a patch file¶
Remove the topmost applied or specified patch from the debian/patches/series
file.
Use -r
to also delete the patch file from the debian/patches
directory:
quilt delete [-r] [PATCH-NAME]
Generate a patch file¶
Create a new patch after the topmost applied patch:
quilt new PATCH-NAME
Note
It is best practice to read the existing patch-file-names in
debian/patches
and ensure your new patch name is consistent with the existing ones.Edit files outside the
debian/
directory by following the same steps as outlined by the following section Edit a patch file.
Edit a patch file¶
Apply all patches until the patch we want to edit:
quilt push PATCH-NAME
There are multiple approaches how to edit the patch file:
Edit the patch header:
quilt header -e
Tip
If the patch does not already have a header and you want to add one; add the
--dep3
flag to insert a DEP 3 patch header template:quilt header --dep3 -e
Tip
See the DEP 3 – Patch file headers reference which lists and briefly explains standard DEP 3 compliant fields and shows sample DEP 3 compliant headers.
Edit specific file(s) with a text editor after adding the changes to the patch file:
quilt edit FILE-PATH ...
Note
Opens the files in
$EDITOR
– this is usually your default terminal editor.Edit specific file(s) manually (without immediately opening an editor):
Check which files are already changed by the patch file:
quilt files
If you want to edit file(s) that the patch currently does NOT change – add these files to the patch before editing them:
quilt add FILE-PATH ...
Note
You can directly edit files which are already changed by the patch.
Tip
To see the changes of the patch file to a specific file:
quilt diff FILE-PATH
To see the changes you made of the patch file:
quilt diff -z
Save the changes to the patch file:
quilt refresh
Delete the changes of a patch to specific file(s):
quilt remove FILE-PATH ...
(recommended) If there are patches after the patch you have edited – verify that all patches still apply cleanly.
Import a patch file¶
Insert patch files following the current topmost applied patch:
quilt import PATCH-FILE-PATH ...
Important
The patch files have to be outside the debian/patches/
directory.
Note
The imported patches do not get applied automatically. You must apply the patches after importing them.