# 8. Patches für Pakete

Sometimes, Ubuntu package maintainers have to change the upstream source code in order to make it work properly on Ubuntu. Examples include, patches to upstream that haven’t yet made it into a released version, or changes to the upstream’s build system needed only for building it on Ubuntu. We could change the upstream source code directly, but doing this makes it more difficult to remove the patches later when upstream has incorporated them, or extract the change to submit to the upstream project. Instead, we keep these changes as separate patches, in the form of diff files.

Man kann Patches in Debian-Paketen auf unterschiedliche Arten handhaben, glücklicherweise stellt sich Quilt als Standard heraus, weil es von den meisten Paketen verwendet wird.

Let’s look at an example package, `kamoso` in Trusty:

    $ bzr branch ubuntu:trusty/kamoso

The patches are kept in `debian/patches`. This package has one patch `kubuntu_01_fix_qmax_on_armel.diff` to fix a compile failure on ARM. The patch has been given a name to describe what it does, a number to keep the patches in order (two patches can overlap if they change the same file) and in this case the Kubuntu team adds their own prefix to show the patch comes from them rather than from Debian.

Die Reihenfolge in der Patches angewandt werden ist in `debian/patches/series` definiert.

## 8.1. Patches mit Quilt

Bevor Du mit Quilt arbeitest, musst Du spezifizieren, wo die Patches liegen. Füge dies in Deine `~/.bashrc` hinzu:

    export QUILT_PATCHES=debian/patches

Und verwende `source`, um die neuen Exports anzuwenden:

    $ . ~/.bashrc

Standardmäßig werden alle Patches angewandt, wenn Du UDD Checkouts or heruntergeladene Quellpakete benutzt. Du kannst dies folgendermaßen überprüfen:

    $ quilt applied
    kubuntu_01_fix_qmax_on_armel.diff

Wenn Du den Patch entfernen wolltest, würdest du `pop` ausführen:

    $ quilt pop
    Removing patch kubuntu_01_fix_qmax_on_armel.diff
    Restoring src/kamoso.cpp

    No patches applied

Und um einen Patch anzuwenden, verwendst du `push`:

    $ quilt push
    Applying patch kubuntu_01_fix_qmax_on_armel.diff
    patching file src/kamoso.cpp

    Now at patch kubuntu_01_fix_qmax_on_armel.diff

## 8.2. Einen neuen Patch hinzufügen

Um einen neuen Patch hinzuzufügen muss Quilt angewiesen werden, einen neuen Patch zu erstellen, sagen Sie ihm welche Dateien dieser Patch ändern soll, bearbeiten Sie die Dateien und aktualisieren Sie den Patch:

    $ quilt new kubuntu_02_program_description.diff
    Patch kubuntu_02_program_description.diff is now on top
    $ quilt add src/main.cpp
    File src/main.cpp added to patch kubuntu_02_program_description.diff
    $ sed -i "s,Webcam picture retriever,Webcam snapshot program,"
    src/main.cpp
    $ quilt refresh
    Refreshed patch kubuntu_02_program_description.diff

Der `quilt add` ist sehr wichtig, wenn du ihn vergisst, werden die Dateien nicht im Patch auftauchen.

Die Änderung wird jetzt in `debian/patches/kubuntu_02_program_description.diff` sein und die `series` Datei wird den Patch auflisten. Du solltest die neue Datei zur Paketierung hinzufügen:

    $ bzr add debian/patches/kubuntu_02_program_description.diff
    $ bzr add .pc/*
    $ dch -i "Add patch kubuntu_02_program_description.diff to improve the program description"
    $ bzr commit

Quilt behält seine Metadaten im `.pc/` Verzeichnis, sodass dieses momentan ebenfalls für das Paketieren hinzugefügt werden muss. In der Zukunft sollte das verbessert werden.

Im Allgemeinen sollten Sie vorsichtig sein, Patches zu Programmen hinzuzufügen sofern diese nicht von Upstream kommen, es gibt häufig einen guten Grund warum die Änderung noch nicht vorgenommen wurde. Das oben genannte Beispiel ändert einen Benutzerschnittstellen-String beispielswese und würde somit mit den gesamten Übersetzungen brechen. Wenn Zweifel bestehen, fragen Sie den Upstreamautor bevor ein Patch hinzugefügt wird.

## 8.3. Patch Headers

Wir empfehlen, dass du jeden Patch mit den DEP-3 Kopfzeilen versiehst. Hier sind einige Einträge, die du verwenden kannst:

Description: | Description of what the patch does. It is formatted like `Description` field in `debian/control`: first line is short description, starting with lowercase letter, the next lines are long description, indented with a space.
Author: | Autor des Patches (i.e. “Jane Doe <packager@example.com>”).
Origin: | Wo der Patch herkommt (z.B. “upstream”), wenn Author nicht verwendet wird.
Bug-Ubuntu: | Ein Link zu einem Launchpad-Bug, eine Kurzform wird vorgezogen (wie z.B. https://bugs.launchpad.net/bugs/XXXXXXX). Wenn es auch Bugs in Upstream-Bugtracker oder in Debian gibt, füge auch Bug oder Bug-Debian Einträge hinzu.
Forwarded: | Ob der Patch an Upstream weitergeleitet wurde. Entweder “yes”, “no” oder “not-needed”.
Last-Update: | Datum der letzten Revision (in der Form “YYYY-MM-DD”).

## 8.4. Auf neue Upstream Versionen aktualisieren

Um zur neuen Version zu upgraden, kannst du das `bzr merge-upstream` Kommando verwenden:

    $ bzr merge-upstream --version 2.0.2 https://launchpad.net/ubuntu/+archive/primary/+files/kamoso_2.0.2.orig.tar.bz2

Wenn Sie diesen Befehl starten, werden alle Patches nicht angewandt, da sie nicht mehr zu alt werden können. Sie müssen eventuell aktualisiert werden um der neuen Upstreamquelle zu entsprechen oder sie müssen eventuell in ihrer Gesamtheit entfernt werden. Um nach Problemen zu forschen, wenden Sie die Patches nacheinander an:

    $ quilt push
    Applying patch kubuntu_01_fix_qmax_on_armel.diff
    patching file src/kamoso.cpp
    Hunk #1 FAILED at 398.
    1 out of 1 hunk FAILED -- rejects in file src/kamoso.cpp
    Patch kubuntu_01_fix_qmax_on_armel.diff can be reverse-applied

Wenn er umgekehrt angewendet werden kann, bedeutet das, dass der Patch bereits von Upstream angewendet wurde, damit kann er gelöscht werden:

    $ quilt delete kubuntu_01_fix_qmax_on_armel
    Removed patch kubuntu_01_fix_qmax_on_armel.diff

Dann fahre fort:

    $ quilt push
    Applied kubuntu_02_program_description.diff

Es ist sinnvoll Refresh zu starten, dies wird den Patch entsprechend der veränderten Upstreamquelle aktualisieren:

    $ quilt refresh
    Refreshed patch kubuntu_02_program_description.diff

Dann committe wie ueblich:

    $ bzr commit -m "new upstream version"

## 8.5. Quilt im Paket verwenden

Moderne Pakete nutzen standardmäßig Quilt, welches in das Paketierungsformat eingebaut ist. Prüfen Sie `debian/source/format` um sich zu vergewissern, dass dort `3.0 (quilt)` steht.

Ältere Pakete, die das Quellformat 1.0 verwenden, werden explizit Quilt verwenden müssen, normalerweise in dem ein Makefile in `debian/rules` eingebunden wird.

## 8.6. Quilt konfigurieren

Die `~/.quiltrc` Datei kann verwendet werden um quilt zu konfigurieren. Hier sind einige Optionen, die nützlich sein können, für die Verwendung von quilt mit debian/packages:

    # Set the patches directory
    QUILT_PATCHES="debian/patches"
    # Remove all useless formatting from the patches
    QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
    # The same for quilt diff command, and use colored output
    QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"

## 8.7. Andere Patch-Systeme

Other patch systems used by packages include `dpatch` and `cdbs simple-patchsys`, these work similarly to Quilt by keeping patches in `debian/patches` but have different commands to apply, un-apply or create patches. You can find out which patch system is used by a package by using the `what-patch` command (from the `ubuntu-dev-tools` package). You can use `edit-patch`, shown in previous chapters, as a reliable way to work with all systems.

In even older packages changes will be included directly to sources and kept in the `diff.gz` source file. This makes it hard to upgrade to new upstream versions or differentiate between patches and is best avoided.

Ändere nicht das Patch-System eines Pakets ohne das mit dem Debian-Maintainer oder dem zuständigen Ubuntu-Team zu besprechen. Wenn derzeit keines existiert, ist es dir freigestellt Quilt hinzuzufügen.