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

For the purpose of defining the upstream policy, we can divide patches into two categories:

  • upstream - upstream probably will be interested in it
  • openSUSE/SLE specific - upstream won't be interested in it

Policy for upstream patches

If you want to add a patch that can be interesting for upstream, please note that this patch must always be sent upstream. This is the only way to ensure that our fixes will be integrated upstream and we can get rid of these patches within the next upstream release. A significant advantage is also that upstream can provide you with sanity checking and a valuable feedback regarding your patch.

When to send the patch to upstream

Usually, it's useful to contact upstream before you submit the patch to OBS. You save yourself from resubmitting the patch if upstream finds an error in it. Also, some of the package maintainers may request this "upstream first" policy before such patch is to be considered for inclusion in the OBS package. Usually, there should be a mention about "upstream first" policy in the specfile of those packages (e. g. SuSEfirewall). However, sometimes upstream is not active enough and sending them the patch after you submit it to OBS is the only reasonable way.

How to find upstream

You have to dig. A good start is to check 'Url' or 'Source' tags in the specfile and visit the upstream website. Then you have to find a way upstream prefers for sending patches. It could be e. g. mail, mailing list, Bugzilla, git, ...

Policy for openSUSE/SLE specific patches

Usually, we try to add patches that can be merged upstream. However, it can happen that our package is different from the upstream and a specific patch is the only solution. Then please note that every openSUSE/SLE specific patch should be documented properly with a justification why this specific fix is needed.

Patch markup (also called "Tagging patches")

To facilitate the use of automatic tools (some day), and to help inform future packagers about the patch nature, the following categories for our patches exist:

  • 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 (switching the displaymanager via /etc/sysconfig, 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.

There are two competing standards for this.

Type 1: minimal single-line comment in spec file

The old format consists of a comment line above a Patch: line, containing the patch category (see above), a (redundant) copy of the filename, and the rest of the line is a free-format string. Since a single line does not leave much room for words or other metadata, check out Type 2 below.

Type 1 format example:

# 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 Type 1 standard lacks the most important part of a patch: a useful description why it is needed or desired in the first place, its single line format is seldomly enough to convey all the desirable information, and the state of the patch (upstream or opensuse-specific, fix or feature, etc.) is cut off 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@example.org>
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.

NOTE: this list is not authoritative, please check with the Open Build Service how they are defined there (osc api /issue_trackers). You can also request new trackers via the OBS github project.

Shortcut Bugzilla-URL Example
openSUSE Bug tracker http://bugzilla.opensuse.org/show_bug.cgi?id=123456 (boo#123456)
Apache Software Foundation https://issues.apache.org/bugzilla/ (pr#37770)
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)
Enlightenment https://phab.enlightenment.org (e#1234)
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)
Mozilla http://bugzilla.mozilla.org/ (bmo#123456)
Novell https://bugzilla.novell.com/ (bnc#123456)
SUSE https://bugzilla.suse.com/ (bsc#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)
Pidgin https://developer.pidgin.im/ticket/12345 (pidgin.im#12345)
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)
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: