Patches

There is no fixed rule for patch naming. The following are guidelines only.

Small patches (less than, say, a few KBytes) should be added to ${FILESDIR}. If you anticipate having several patches, it often helps to create version numbered subdirectories — ${FILESDIR}/${PV}/ is conventional. Patches are best named ${P}-what-it-does.patch (or .diff), where what-it-does is a two or three word description of what the patch is for. If the patch is to fix a specific bug, it is often useful to add in the bug number — for example, vim-7.0-cron-vars-79981.patch. If the patch is pulled from upstream's VCS repository, it can help to include the revision number in the patch name as a suffix to the version part — fluxbox-0.9.12-3860-menu-backups.patch.

Larger patches should be mirrored, preferably on the Gentoo Infrastructure. When mirroring patches, choosing a name that will not cause conflicts is important — the ${P} prefix is highly recommended here. Mirrored patches are often compressed with xz or bzip2. Remember to list these patches in SRC_URI. Please see The files Directory for more information.

If a package requires many patches, even if they are individually small, it is often best to create a patch tarball to avoid cluttering up the tree too much.

Patch Descriptions

It is possible to include a description with a patch. This is often helpful when others come to work with your packages, or, indeed when you come back to take a look at your own package a few months later. Good things to include in comments are:

  • What the patch actually does. Bug numbers are good here.
  • Where the patch came from. For example, is it from an upstream VCS, something from Bugzilla, or something you wrote?
  • Whether the patch has been sent upstream, if applicable.

To include the description, simply insert it at the top of the patch file. The patch tool will ignore leading text until it finds something that looks like it might be a 'start patching' instruction, so as long as each description line starts with letters (rather than numbers, symbols or whitespace) there shouldn't be a problem. Alternatively, prefix each description line with a hash (that's #, or 'pound' to the USians) sign. It's also best to leave a single blank line after the description and before the main patch.

Here's a simple example (023_all_vim-6.3-apache-83565.patch) from the vim patch tarball:

# Detect Gentoo apache files properly. Gentoo bug 83565.

--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -93,6 +93,9 @@
 " Gentoo apache config file locations (Gentoo bug #76713)
 au BufNewFile,BufRead /etc/apache2/conf/*/* setf apache

+" More Gentoo apache config file locations (Gentoo bug #83565)
+au BufNewFile,BufRead /etc/apache2/{modules,vhosts}.d/*.conf setf apache
+
 " XA65 MOS6510 cross assembler
 au BufNewFile,BufRead *.a65                    setf a65

Conditional patching

Patching is ideally only done to make the package in question build properly, and should not be done to modify the runtime behaviour of the package. This is what USE flags and features of the package are for. As such, it is preferable to apply patches unconditionally and avoid conditional patching.

There are a number of reasons to avoid conditional patching:

  • It may go unnoticed that a patch fails to apply, if a package is not being tested with a given flag
  • More variance is introduced and problems with a package can become much more difficult to debug
  • Patches should preferably be upstreamed, but conditional patches cannot

Consider the following example src_prepare() implementation:

src_prepare() {
	if use threads; then
		PATCHES+=( "${FILESDIR}"/${P}-mt.patch )
	fi
	default
}

As this patch is only applied when USE="threads" is set, any developer creating new versions of this package might not detect whether the patch applies successfully if they don't test with the same flag.

Although conditional patching is discouraged it can be unavoidable and as such, it is not considered a banned practice, but, to the extent possible, patches should be written such that they affect behaviour correctly based on e.g. build time definitions and configuration options rather than USE flags directly. This allows them to be applied unconditionally.

Clean Patch Howto

"Clean patch" does not refer to the patch itself (as in the changes it makes to the source code). It refers to all the metadata that exists in the patch to make it "maintainable".

Why

This may take more effort "up front", but the amount of effort that it saves for everyone else in the future more than makes up for it. This refers to other distributions or upstream maintainers who read the patch, or future Gentoo maintainers. By keeping all patches "clean", people can quickly and easily assess a patch without searching through many other files.

File Naming

Your patch name should be short and to the point. When doing a file listing (e.g., ls files/), it's a lot easier to be able to scan for relevant patches when they have good keywords in their file names.

It should also include the package name and the version it was written against. This way, people searching for patches or who happen to just stumble across the file itself have a clue as to what it's for. Stripping out the ${PN} (and to a lesser extent, the ${PV}) makes the filename significantly less useful. The fact the files are typically stored in ${CATEGORY}/${PN}/files/ is irrelevant, because the patch may be used outside Gentoo.

How

Here's a check list of things to keep in the patch header:

  • External references
    • Upstream mailing archives
    • Upstream bug reports
    • Upstream commit links
    • Upstream ChangeLog entries
    • Gentoo bug reports
  • Short/medium explanation
    • Why is the patch needed?
    • What is it fixing?
    • Why is it fixing it the way it is?
    • Proposal for better fixes in the future?
    • Is it a stop gap measure (workaround)?
    • How was it regression tested?
    • Examples of before/after behaviour
      • How to reproduce bug without patch
      • How to show bug is fixed after patch
      • Maybe upstream fixed it in a different way, so this test can be used to show that the patch is no longer needed with newer versions
  • Status
    • Was it merged/rejected/postponed/etc. upstream?
    • Is it distribution-specific?
  • Attribution
    • Who found the bug?
    • Who fixed the bug?
    • Who wrote the patch?
    • Who tested the patch?
    • Who gave advice on the patch?

All this information should be in the patch itself. It should never be found in something like the ebuild. If you really want to put a comment next to a patch in an ebuild, then this is about the only thing that is OK (where 93671 is the Gentoo bug number):

PATCHES=(
	"${FILESDIR}"/${P}-dont-umask.patch #93671
)

When documenting these things, it might be useful to use RFC822/Git-style tags to format the metadata. So when documenting the author, use:

From: Nice Person <foo@cow.example.com>

Or when documenting relevant URLs, use something like:

Bug: https://upstream.example.com/12345
Bug: https://bugs.gentoo.org/9889

And if you want to note your copyright signoff, slap on a Signed-off-by tag:

Signed-off-by: Diligent Developer <larry@gentoo.org>

Finally, your patch should be clear of useless cruft. If it was not taken straight from an upstream SCM (git format-patch or svn diff -r # or cvs diff -r 1.123 -r 1.124), then the metadata is useless. So delete it. This refers to things like the diff command used to produce the patch, or the timestamps on the files, local revision info, or other similar spam. Note that the context info (the stuff that comes after the @@) should be left, as that can be invaluable when applying patches to later versions. For example:

@@ -80,6 +82,7 @@ case $sys in
                  ^^^^^^^^^^^^ keep this part

Extra points if you make the filename in the ---/+++ section consistent and sane. That is, remove different leading backup/paths/ and .orig/.new suffixes. Your patch should be in the -p1 format because this tends to be much more standard than any other -p#. It is also what eapply understands by default. A good suggestion is to use either a/ and b/ (as in git format-patch) or the package name/version as the leading portion that gets stripped.

Also note that patch uses the timestamp info in order to remove empty files automatically. Alternatively, you can specify the -E option with eapply if you want to remove an empty file.

Removed lines should not appear in the patch because they are commented — just remove them entirely. Patches show removed lines by prefixing them with a -, so no information is lost by simply deleting lines rather than commenting them out (which adds noise). This makes the patch shorter and more readable.

The following function (for your interactive shell, not for the ebuild) will help deleting these things:

scrub_patch() {
	sed -i \
		-e '/^index /d' \
		-e '/^new file mode /d' \
		-e '/^Index:/d' \
		-e '/^=========/d' \
		-e '/^RCS file:/d' \
		-e '/^retrieving/d' \
		-e '/^diff/d' \
		-e '/^Files .* differ$/d' \
		-e '/^Only in /d' \
		-e '/^Common subdirectories/d' \
		-e '/^deleted file mode [0-9]*$/d' \
		-e '/^+++/s:\t.*::' \
		-e '/^---/s:\t.*::' \
		"$@"
}

scrub_patch some-patch-you-found.patch

Examples

This shows a simple explanation and a URL for more info (this patch could do with some attribution however). No metadata exists from running the diff command (timestamps, etc.).

Fixes compilation in FreeBSD.
https://bugs.gentoo.org/138123

--- man-1.6d/gencat/genlib.c
+++ man-1.6d/gencat/genlib.c
@@ -54,7 +54,7 @@
 #include <unistd.h>
 #endif

-#ifndef __linux__
+#if !defined(__linux__) && !defined(__FreeBSD__)
 #include <memory.h>
 static int bcopy(src, dst, length)
 char *src, *dst;
Don't force umask to 022 or the -o umask option doesn't work.
Patch by Daniel Drake.
https://bugs.gentoo.org/93671

--- mount/mount.c
+++ mount/mount.c
@@ -1491,8 +1491,6 @@ main(int argc, char *argv[]) {
    if ((p = strrchr(progname, '/')) != NULL)
        progname = p+1;

-   umask(022);
-
    /* People report that a mount called from init without console
       writes error messages to /etc/mtab
       Let us try to avoid getting fd's 0,1,2 */
Don't let target flags bleed into build flags.
Fix by Bertrand Jacquin.
https://bugs.gentoo.org/226035

--- netem/Makefile
+++ netem/Makefile
@@ -2,6 +2,7 @@ DISTGEN = maketable normal pareto paretonormal
 DISTDATA = normal.dist pareto.dist paretonormal.dist experimental.dist

 HOSTCC ?= $(CC)
+CCOPTS  = $(CBUILD_CFLAGS)
 LDLIBS += -lm

 all: $(DISTGEN) $(DISTDATA)