Home Wiki > openSUSE:Packaging Patches guidelines
Sign up | Login

openSUSE:Packaging Patches guidelines

tagline: From openSUSE

Packagers deal with lots of packages, and lots of patches inside those packages. These need to be marked in the .spec files with a well-known format to be able to run automatic tools on them, in order to generate reports, patch counts and other interesting information. They also need to be named consistently.

Patch life cycle

Patches need to be added to packages for various reasons and it is important that the life cycle of a patch is well-defined. This helps in preventing that patches get "lost" and nobody knows why and when it was removed. The life cycle is defined in these simple steps:

  • Patch added to the package
  • Patch is modified (functional/rebased)
  • Patch is disabled (but not deleted)
  • Patch removed from the package

The middle stages of the patch life cycle are optional and not every patch will live through them.

Any of those stages needs to be mentioned in the .changes file, including the file name of the patch. This is only for the benefit of human readers, so does not need to be in a strict machine-parseable format; here are some examples of the suggested format:

  • Add package-awesomeness.patch: Makes package awesome
  • Drop package-awesomeness.patch: Upstream made it even more awesome.
  • Disable package-awesomeness.patch: Testing if users can live without awesomeness
  • Rebase package-awesomeness.patch to apply to the new version.

Upstream policy

There are a handful of packages where the Build Service-level maintainer(s) is/are the same person or group that runs upstream, so that it makes more sense to just submit to upstream instead.

A BS-level package maintainer may request that patches not specific to building for openSUSE should always be sent upstream first for sanity checking and validation, before such patch is to be considered for inclusion in the Build Service package. A simple mention of Upstream First in the specfile will suffice; the proposed location would be right above the first "Patch:" line. If there is no Patch line yet, right below the last "Source:" line would be a good place, since Patches often follow Sources.

The benefit is that the maintainers will not need to extract patches out of the BS, which can a problem because some BS-level patches are often notoriously underdocumented, including description and/or metadata. With an upstream submission, this problem will be resolved upon contact. Since the maintainer is the same at both levels, they also know better of the potential caveats of an older version included in the BS.

Examples for packages where UF is desired are for example those that are "home" to (open)SUSE: yast, zypp, SuSEfirewall, and so on. But there are also packages that do not directly relate to SUSE and which still request UF.

Patch markup (also called "Tagging patches")

To facilitate the use of automatic tools — and to help future packagers —, we have agreed on using the following categories for our patches:

  • Fixes: these are normal fixes and are divided into two categories:
    • Fixes for openSUSE-specific things, that upstream maintainers will not be interested in.
    • Fixes for SLE-specific things, that upstream maintainers will not be interested in and that are not needed in openSUSE.
    • Fixes for the upstream sources that should be upstreamed.
  • Features: new features added to the packages, also divided into two categories:
    • Features for openSUSE-specific things (AppArmor integration, for instance) with no interest for upstream maintainers.
    • Features for SLE-specific things with no interest for upstream maintainers or openSUSE.
    • Features that should be upstreamed. Whenever we write this kind of new feature, it is important to coordinate with upstream maintainers. That way, we can develop something that will be accepted upstream without changes. Once a feature is finished, it is a lot of work to rework it to be acceptable to upstream maintainers. As such, it is better to know from the beginning exactly what upstream maintainers would expect.

Type 1: minimal single-line comment in spec file

To mark our patches to follow this convention, we have came up with a standard to mark them in the .spec file, following the format below:

# PATCH-FIX-OPENSUSE fix-for-opensuse-specific-things.patch bnc#123456
Patch1: fix-for-opensuse-specific-things.patch
# PATCH-FIX-SLE fix-for-sle-specific-things.patch bnc#123456
Patch2: fix-for-sle-specific-things.patch
# PATCH-FIX-UPSTREAM fix-for-upstream-sources.patch bnc#123456
Patch3: fix-for-upstream-sources.patch
# PATCH-FEATURE-OPENSUSE feature-for-opensuse-specific-things.patch bnc#123456
Patch4: feature-for-opensuse-specific-things.patch
# PATCH-FEATURE-SLE feature-for-sle-specific-things.patch bnc#123456
Patch5: feature-for-sle-specific-things.patch
# PATCH-FEATURE-UPSTREAM feature-for-upstream.patch bnc#123456
Patch6: feature-for-upstream.patch

Special case: we often have patches that get commented out temporarily because they failed to apply to the latest sources, and the patches need to be rebased. Do not comment out the patch's declaration, but do comment out its application. When marking a patch as needing a rebase, it is a good idea to preserve its old tag.

# PATCH-NEEDS-REBASE old-patch.patch bnc#123456 -- Does something old. Was: PATCH-FEATURE-OPENSUSE
Patch7: old-patch.patch
[...]
# %patch7


Finally, we include e-mail addresses so that it will be easier to figure out who wrote a patch if we have questions later, and free-form comments after " -- ".

That is:

# PATCH-{FIX|FEATURE}-{OPENSUSE|SLE|UPSTREAM} name-of-file.patch bnc#[0-9]* you@example.com -- this patch makes things totally awesome

If there are related bugs in Novell or other bugzillas, please add them, it will help us to get more accurate information. If there are two or more available then it's preferable to list both (or more).

In general, the bugzilla field is not required on new patches. For patches to released packages that will go out as updates, a bugzilla entry (BNC#) for the overall update in the changes file is required. If appropriate, the patch description should also include it.

The primary use case of the patch field should be references to upstream bug trackers in case of PATCH-*-UPSTREAM patches, such patches should be submitted upstream first and then referenced in the patch tag. That helps a lot to keep track of patches, it makes it easy to determine which patches are still needed on version updates if upstream references the bug numbers in their changelog or release notes. Of course if there is already a corresponding bnc# bug open it should be referenced as well.

You can find the current set of abbreviations at the end of this document. We can also define more abbreviations later if and when they prove necessary.

Some patches fix bugs that are not explicitly recorded anywhere. The right thing to do in this case requires some judgment on the part of the packager, but here are some ideas:

  • If a release is imminent, create a bug for it. This is usually a requirement, and even if it were not, it is still the right thing to do.
  • If a release is a long way off and the bug has already been fixed upstream, note in the comment that it is already fixed in the SVN (or wherever) and the patch will go away when we next upgrade.

Type 2: Complete Information provided in patch

The previous standard lacks the most important part of a patch: a description why it is needed or desired in the first place. Furthermore, the state of the patch (upstream or opensuse-specific, fix or feature, etc.) is disjoined from the actual patch.

The patches in the openSUSE kernel packages have traditionally used a form of tagging where metadata is directly attached to where it is needed — in the patch file itself. This facilitates submission of patches to upstream, as the description cannot be accidentally omitted, and the Git SCM (where used) knows to retain the metadata on import. Conversely, extraction of patches from Git repos also yields single files.

Patch files are to follow a scheme of "key: value" pairs and a description, optionally with a diffstat, prepended to the actual hunks. Example.

From: Random J Developer <email@address.de>
Date: 2012-07-28 01:28:22 +0200
Subject: input: add Acer Aspire 5710 to nomux blacklist
References: bnc#404881
Upstream: submitted

Acer Aspire needs to be added to nomux blacklist, otherwise the touchpad misbehaves.

---
 drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -371,6 +371,13 @@ static const struct dmi_system_id __init
[...]

It is advised to use e.g. Quilt which retains descriptions on refresh. `quilt ref --sort --diffstat -p1` creates/refreshes such patches, sorted, with a diffstat and in the wanted -p1 format.
Common fields encountered:

  • From: shall specify the e-mail address of the original author of the patch.
  • Date: when this patch was first created. Preferably an ISO-8601 timestamp with timezone. If a new patch was just created and has none, you can use `stat your.patch` to determine a timestamp.
  • References: links to mailing list posts, bugzillas, etc. No fixed format, though URLs are preferred for they are easy to copy&paste into the browser. See the below section “#Current set of abbreviations” for details.
  • Upstream: the disposition of the patch. No fixed format, though common options are “never”/“no” (openSUSE-specific), “to be done” (tbd), “sent”/“submitted” (sent to upstream developers; provide Reference if possible), “merged” (upstream has accepted it; provide Reference if possible) and “dead” (no activity in upstream project).
  • Subject: A short one-line summary of the patch.

Patches are to provide a description. The description shall describe why it is needed. Be as thorough as you like, because it will influence the decision what a different developer should do with the patch should it not apply anymore. The three questions “what command did you execute?”, “what did you observe?”, “what did you expect to see instead?” can give some guidance. If a related error message is available, e.g. when creating a patch to fix a syntactical error in a source file that causes the compilation to abort, it should be included, trimmed to the important parts. Furthermore, a summary on the how the solution is implemented can help readers grok larger patches.

Reading material (from the mailing lists) that shows the need for this kind of tagging: (1) (2) (3)

Patch naming

All new patches should end with the extension '.patch'.

Whether a patch's name should start with the name of the package it applies to is a matter of debate or style. When in doubt, follow the convention used in the package you are hacking on.

Do NOT use %{version} macro in Patch: line, specify the version by hand. Using the macro:

  • causes lots of renames on version update
  • makes it easy to overlook patches that are no longer needed
  • makes it hard to determine when the patch was touch for the last time
  • makes it easy to find out when the patch broke (package archaelogy)

An exception to this exists: patches that fix warnings that the compiler emits due to bogus code are frequently named abuild.patch.

The preferred patchlevel is -p1 as it makes importing using tools like quilt more straightforward.


Current set of abbreviations

To avoid confusion and double burden, referencing to other bugzillas is allowed. Here are some shortcuts for often used bugzillas, which should be added before the "#" of the bugzilla number. Note there is no whitespace between the shortcut and the bugzilla number.

Shortcut Bugzilla-URL Example
Boost https://svn.boost.org/trac/boost/report (boost#123456)
Ceph bug tracker http://tracker.ceph.com/ (ceph#123456)
Claws Mail http://www.thewildbeast.co.uk/claws-mail/bugzilla/ (claws#123456)
CVE entries (please add the number, even if there is an additional bugzilla for it) http://cve.mitre.org (CVE-2009-0067)
CPAN Public Bug Tracker http://rt.cpan.org/Public/ (RT#123456)
Debian http://bugs.debian.org/ (deb#123456)
Exim http://bugs.exim.org/ (beo#1234)
Fate (Feature tracking tool) https://features.opensuse.org/ (fate#123456)
freedesktop.org http://bugs.freedesktop.org/ (fdo#123456)
FSF http://bugs.gnu.org (gnu#123456)
GCC http://gcc.gnu.org/bugzilla/ (GCC#123456)
GH https://github.com/ (gh#yast/yast-core#42)
GNOME http://bugzilla.gnome.org/ (bgo#123456)
Graphviz http://graphviz.org/mantisbt/view_all_bug_page.php (gvz#123456)
ICCULUS http://bugzilla.icculus.org/ (bio#123456)
Jenkins CI https://issues.jenkins-ci.org (jenk#123456)
KDE http://bugs.kde.org/ (kde#123456)
Kernel or K http://bugzilla.kernel.org/ (bko#123456)
Launchpad (Ubuntu) https://bugs.launchpad.net/ (lp#123456)
Linux Foundation http://developerbugs.linux-foundation.org/ (lf#1234)
MeeGo http://bugs.meego.com (MeeGo#123456)
Mono http://bugzilla.ximian.com/ (Mono#123456)
Mozilla http://bugzilla.mozilla.org/ (bmo#123456)
Novell https://bugzilla.novell.com/ (bnc#123456)
OpenLDAP http://www.openldap.org/its/ (ITS#123456)
OpenOffice.org (Issuezilla) http://qa.openoffice.org/issues/ (i#123456)
OpenOffice.org Novell (obsolete) https://bugzilla.novell.com/ (n#123456)
openSUSE-Education http://devzilla.novell.com/education/ (os-edu#123456)
RedHat https://bugzilla.redhat.com/ (rh#123456)
Samba https://bugzilla.samba.org/ (bso#123456)
Sourceforge http://sf.net/support/tracker.php?aid=1234567 (sf#1234567); number is in the "aid=" part in an URL
SourceWare http://sourceware.org/bugzilla/ (swo#1234567)
Typo3 http://forge.typo3.org/ (t3#1234567)
WebKit https://bugs.webkit.org/ (webkit#123456)
Ximian http://bugzilla.ximian.com/ (Ximian#4321)
Xfce https://bugzilla.xfce.org/ (bxo#123456)
Xamarin http://bugzilla.xamarin.com/ (bxc#4321)

For other bugzilla numbers, please use the full URL to the coresponding bugzilla at the beginning of the patch file. For example:

Abbreviation bookmarklet

A bookmarklet for searching bugzilla.novell.com with bnc# prefixes can be found here