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.

  1. We verify that all patches apply cleanly:

    quilt push -a
    
  2. We verify that all patches unapply cleanly:

    quilt pop -a
    
  3. (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

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

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

  1. Apply all patches until the patch we want to edit:

    quilt push PATCH-NAME
    
  2. 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):

      1. Check which files are already changed by the patch file:

        quilt files
        
      2. 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
        
      3. Save the changes to the patch file:

        quilt refresh
        
    • Delete the changes of a patch to specific file(s):

      quilt remove FILE-PATH ...
      
  3. (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.

Resources