Patch management¶
This article demonstrates how to manage the patches of a source package in the 3.0 (quilt)
format.
See the Patches 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 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 creates a .pc/
directory at the source package root directory. This is the location where Quilt stores 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
To avoid having to remove .pc
, add it to the .gitignore
.
Prerequisites¶
If you haven’t already, install quilt(1):
sudo apt install quilt
The following sample quilt(1) configuration file sets recommended useful defaults. It also instructs quilt
to look for patches in the debian/patches/
directory if the quilt
command is invoked within a source package directory. Save it as ~/.quiltrc
.
#!/usr/bin/env bash
set -euo pipefail
# find the root of a Debian source tree:
SrcPkgRoot="${PWD}"
while [ ! -s "$SrcPkgRoot/debian/source/format" ]; do
if [ "${SrcPkgRoot}" = '/' ]; then
echo -e "\033[1;33mWARNING\033[0m: You're not in a Debian source tree!"
exit 0
fi
SrcPkgRoot="$(readlink --canonicalize-existing "${SrcPkgRoot}/..")"
done
if ! grep --silent --fixed-strings '3.0 (quilt)' \
"${SrcPkgRoot}/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:="${SrcPkgRoot}/debian/patches"}"
# create the quilt control files directory at the root of the source package
: "${QUILT_PC:="${SrcPkgRoot}/.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"}"
Note
To undo this configuration, delete ~/.quiltrc
.
List patches¶
List all available patches:
quilt series
This also color-codes the output based on patch status:
applied (green)
latest applied patch (yellow)
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 you know how to apply and unapply patches you can verify if all patches apply and unapply cleanly. This is useful when you merge changes from Debian into an Ubuntu package and want to check if everything is still in order.
Verify that all patches apply cleanly:
quilt push -a
Verify that all patches unapply cleanly:
quilt pop -a
(optional) Remove the Quilt control file directory:
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 the -r
option 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 filenames 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 Edit a patch file section.
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
Use the
--dep3
flag to insert a DEP 3 patch header template:quilt header --dep3 -e
Tip
See DEP 3 - patch file headers, 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
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 that 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.