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.

  1. Verify that all patches apply cleanly:

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

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

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

  2. Edit files outside the debian/ directory by following the same steps as outlined by the Edit a patch file section.

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

      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):

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

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

Further reading