Manage differences between a package you have created and the upstream project. For general packaging information, see Packaging.

{i} This page assumes you have specified the 3.0 (quilt) format in debian/source/format. If you are using the simplified 3.0 (native) or deprecated 1.0 format, please switch to 3.0 (quilt) before continuing.

The quilt patch system was first popularised by the package of the same name, but nowadays that program is only recommended for packages without a version control system. Use gbp-buildpackage instead for git-based projects.

If upstream has a /debian directory or file

In rare cases, your upstream's top-level directory might have a subdirectory (or even a file!) called debian. Debian uses that directory to store its data, so here are some possible solutions.

Politely ask upstream to move the directory (recommended)

Upstreams that release their own .deb packages often provide a debian/ directory in their repo or tarballs. It's up to you whether to use this as the basis of your own work, it just can't have the specific filename debian upstream. Most upstreams should respond to a polite request, and the relevant section of the upstream guide discusses alternative solutions.

Pretend it doesn't exist

3.0 (quilt) requires the removal of any pre-existing debian directory, so programs that import from a tarball (e.g. gbp import-orig) will do this automatically. Or if you import with git pull, adapt the following solution instead:

# Run the following commands in debian/latest:
git checkout -b debian/latest -t upstream/latest

# Delete the upstream directory in the debian branch:
git rm -r debian
git commit debian -m 'Delete upstream debian'

# Define a custom "ours" merge-driver that ignores upstream changes:
git config merge.ours.driver /usr/bin/true

# Use the custom merge-driver for files in debian/:
# See https://git-scm.com/docs/gitattributes#_performing_a_three_way_merge
echo '/debian/** merge=ours' > .git/info/attributes

{i} Document your solution in your debian/README.Debian

Move it before importing it

In very rare cases, an upstream could have a debian that has nothing to do with Debian packaging. For example, a program to detect the operating system of a network host might put heuristics to detect a Debian host in a file called /debian.

An actual upstream file called debian probably can't be ignored or deleted, so it needs to be be fixed the same way as an upstream with content that is disallowed (see next section).

If upstream has content that is disallowed

Some upstream tarballs contain files that needs to be modified before they can even go in an upstream tarball. For example, Debian will refuse to host an upstream tarball with contents that violate the Debian Free Software Guidelines, so those files need to be deleted altogether. This is quite rare - the vast majority of upstream issues can simply be patched.

If you import tarballs with uscan (or gbp import-orig --uscan) and just need to delete some files, you can use uscan to strip files from upstream tarballs.

If you import branches with git pull, the recommended solution is to pull into upstream/latest, clean data and commit to a dfsg_clean branch, then merge the clean branch into debian/latest. For details, see Handling non-DFSG clean upstream sources (also available in /usr/share/doc/git-buildpackage/manual-html/gbp.special.html).

If merging into a dfsg_clean branch generates merge conflicts, but the conflicts are the same every time, you might be able to automate the resolution process with git rerere.

If merging into a dfsg_clean branch generates merge conflicts that can't be fixed with git rerere, you may need to use git "plumbing" commands to automate your workflow. Adapt the following to suit your needs:

#!/bin/sh
#
# Skeleton script to pull and apply custom modifications
#
# Before resorting to this, please try:
# * recommended solution:
#   https://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.special.html#GBP.SPECIAL.DFSGFREE
# * reuse recorded resolutions:
#   https://git-scm.com/book/en/v2/Git-Tools-Rerere

set -e

UPSTREAM_BRANCH="$(gbp config DEFAULT.upstream-branch)"

# Download recent changes:
git fetch

# Switch to an anonymous branch based on upstream:
git checkout "$UPSTREAM_BRANCH"@{upstream}

# ... make your changes ...

# Add any changes you made:
git add -u

# Make a merge commit using low-level plumbing commands:
DFSG_CLEAN_COMMIT="$(
    git commit-tree "$(git write-tree)" \
        -p "$UPSTREAM_BRANCH" \
        -p "$UPSTREAM_BRANCH"@{upstream} \
        -m "Merge upstream into upstream/latest"
)"

# Merge the cleaned commit into upstream/latest:
git checkout "$UPSTREAM_BRANCH"
git merge "$DFSG_CLEAN_COMMIT"

If your .orig.tar.gz doesn't match the upstream tarball, you may need to use a special version number.

{i} Document your solution in your debian/README.Debian, and commit any scripts you create.

If upstream content needs patching

It's quite common to make changes in your debian branch but outside your debian/ directory. For example, lintian might complain about a spelling mistake in a man page, or you might have a build failure because of an outdated autoconf. Debian needs these changes to be accounted for, so people can replicate every step from the upstream source to the binary package.

If you have a good relationship with upstream, you might prefer to fix issues there and come back to Debian when your changes have been released. But you may well need to develop patches in Debian first and send them upstream when the time comes.

If the patches are small or temporary

Debian supports maintaining a small or temporary series of patches against upstream. For example, you might prefer to wait until your new package is ready before submitting fixes, or you might backport a security patch for your mature package.

Patches are stored using a patch system called quilt. A patch system is a minimal alternative to a version control system like git - it just manages a collection of patches (like individual commits in git) and an ordered patch-series (like a topic branch in git). The patch-series is always based on the current contents of the project, so changing the project implicitly rebases the patch-series.

quilt patches are stored in debian/patches/*.patch and the patch-series is stored in debian/patches/series. The format of individual patch files is defined in DEP-3, and resembles git-format-patch.

quilt can be easier than git for some simple problems - for example, you can reorganise patches by editing debian/patches/series in text editor. But if your changes are complicated enough to need a full version control system, you may need to fork the upstream project instead.

Managing debian/patches with git-buildpackage

git-buildpackage can convert a quilt patch-series to a git branch and back again using the gbp pq command. A typical workflow is to gbp pq import a patch-series into a branch, make your changes in the normal way, gbp pq export the branch back to quilt, then git add debian/patches. The first time you call gbp pq import, it will notice you don't have a debian/patches/series file and create a new branch with no extra commits.

A git branch that's associated with a quilt series is called a patch-queue branch, because its commits are queued up waiting to become patches.

To submit a patch (or a series of patches) to an upstream forge, create a normal branch and cherry-pick some commits from your patch-queue branch into it. Or to submit a patch (or a series of patches) to an upstream mailing list, copy the relevant files from debian/patches into a new directory, then send them with git-send-email. You may want to do a --dry-run or set --to=<your-address> first, to check you've got everything right. When your patches are accepted upstream, get rid of any patch-queue branches then delete the patches by editing debian/patches/series.

See the gbp pq command for a complete list of actions, and the official documentation for a more detailed explanation.

Maintaining packages with quilt

If your project doesn't use version control (very rare nowadays), you can manage patches with the original quilt program. For details, see UsingQuilt.

If the patches are large and permanent

If your upstream project has been abandoned or is unwilling to accept changes, and your changes are becoming hard to manage in Debian, you may need to fork the upstream project.

Before forking the project, reach out to the maintainer - they may be willing to officially hand the project over to you, and at minimum they deserve the opportunity to make their opinion known. Also reach out to anyone that might help, like maintainers for other distributions or contributors to open bug reports - they may have something useful to add, and at minimum they need to know your fork is available.

This document talks about "the upstream project", but you may want to make a so-called "downstream fork". That is, a project that is downstream from some other project (so you routinely accept changes from them), but upstream from distributions (so distributions routinely accept changes from you). That makes it easier to merge your project back upstream if the situation improves.

It's OK to remain the Debian maintainer of a project you fork, especially for an abandoned project. But consider asking someone else to take over if there's a potential conflict of interest. For example, if the maintainer is still active but taking the project in a direction you think is wrong, it's best to avoid the appearance that Debian is backing one side of a dispute.


CategoryPackaging