Creating a patch
This page amends the Devmanual's patches article and describes how to create a patch for source code.
Creating a patch
Using diff
Unpack the package to a directory name "a".
root #tar -x -v -f /var/cache/distfiles/package.tar.xzroot #mv package aCopy to a directory named "b".
root #cp -r a bMake your changes to b.
root #emacs b/file.cRun diff.
root #diff -ur a b > /etc/portage/patches/example-category/example-packagename/my-patch.patchUsing git
A source code patch for an existing package can easily be created using git diff.
Unpack the package to be patched using the ebuild command:
user $ebuild $(portageq get_repo_path / gentoo)/sys-fs/lvm2/lvm2-2.02.145-r2.ebuild clean unpack... >>> Unpacking source... >>> Unpacking LVM2.2.02.145.tgz to /var/tmp/portage/sys-fs/lvm2-2.02.145-r2/work >>> Source unpacked in /var/tmp/portage/sys-fs/lvm2-2.02.145-r2/work
Step into the ${S} directory as defined in the ebuild:
user $cd /var/tmp/portage/sys-fs/lvm2-2.02.145-r2/work/LVM2.2.02.145/Initialize a git repository
If the unpacked directory is a git repository, skip the following initialization of the git repository.
Initialize the unpacked package sources as a git repository:
user $git initInitialized empty Git repository in /var/tmp/portage/sys-fs/lvm2-2.02.145-r2/work/LVM2.2.02.145/.git/
Add all the existing files to git and do a commit. Remember to write a commit message!
user $git add .user $git commit -m "Initial commit"Make changes
Now make the necessary changes to the unpacked source code, one or more files may be changed. Of course, the required changes should probably be known in advance.
Here is an example of a command making changes to the source code:
user $sed -e 's/MAKEDEV:-"debian"/MAKEDEV:-"gentoo"/' -i scripts/lvm2create_initrd/lvm2create_initrdCreate diff using git
When changes are done, have git output the diff, and tee it into the patch file:
user $git diff | tee /tmp/foobar.patchdiff --git a/scripts/lvm2create_initrd/lvm2create_initrd b/scripts/lvm2create_initrd/lvm2create_initrd
index 6e70c55..1e46b5e 100644
--- a/scripts/lvm2create_initrd/lvm2create_initrd
+++ b/scripts/lvm2create_initrd/lvm2create_initrd
@@ -57,7 +57,7 @@ DEVRAM=/tmp/initrd.$$
BINFILES=${BINFILES:-"`which lvm` `which bash` `which busybox` `which pivot_root`"}
BASICDEVICES=${BASICDEVICES:-"std consoleonly fd"}
BLOCKDEVICES=${BLOCKDEVICES:-"md hda hdb hdc hdd sda sdb sdc sdd"}
-MAKEDEV=${MAKEDEV:-"debian"}
+MAKEDEV=${MAKEDEV:-"gentoo"}
# Uncomment this if you want to disable automatic size detection
#INITRDSIZE=4096
Using quilt
dev-util/quilt is a patch manager used extensively by the Debian project, that can be used to create and maintain simple patchsets. It fills a niche where the diff method is too inconvenient for multiple patches, and git is too involved. The workflow is similar to both:
Unpack the package and enter the directory:
root #tar -x -v -f /var/cache/distfiles/package.tar.xzroot #cd packageCreate a new patch:
root #quilt new package-fix.patchAdd a file to the patch and make your changes:
root #quilt add file.croot #vi file.cOr as a shortcut (change the $EDITOR variable for your prefered editor):
root #quilt edit file.cRefresh the patch. This generates the actual patch file:
root #quilt refresh -p abOther useful commands include:
- quilt series: Show patch stack
- quilt pop -a: Unapply all patches
- quilt push -a: Apply all patches
- quilt header -e: Modify the patch's header (Using $EDITOR)
- quilt diff: Show changes of current patch in the stack, without refreshing the file
- quilt rename package-fix-more.patch: Rename the current patch in the stack
- quilt fork package-v2-fix.patch: Copy and rename the current patch in the stack
- quilt delete: Delete the current patch in the stack
- quilt remove: Remove file from current patch
Cleanup
If the patch isn't in a standard format already (like git format-patch), it's a good idea to clean it up a bit before using it in an ebuild. The devmanual has a guide, and the scrub-patch command from app-portage/iwdevtools may used to automate some changes.
Adjusting a malformed patch from TortoiseGit or Git for Windows
Patches generated by Tortoise Git and Git for Windows are padded with additional information that patch does not understand.
PATCH.patchTypical Tortoise Git/Git for Windows PatchFrom HASH Day Mon DD hh:mm:ss YYYY
From: AUTHOR <[email protected]>
Date: Day, DD MMM YYYY hh:mm:ss +hhmm
Subject: [PATCH] COMMIT MESSAGE
---
PATH/TO/FILE.EXT 1 +
1 file changed, 1 insertion(+)
diff --git a/PATH/TO/FILE.EXT b/PATH/TO/FILE.EXT
index HA..SH CODE
--- a/PATH/TO/FILE.EXT
+++ b/PATH/TO/FILE.EXT
@@ -56,6 +56,7 @@
+ some new code
- some old code
--
VERSION.windows.REVISION
The individual generating the patch has to strip these additional lines to make a viable patch file.
PATCH.patchAcceptable Tortoise Git/Git for Windows Patch--- a/PATH/TO/FILE.EXT
+++ b/PATH/TO/FILE.EXT
@@ -56,6 +56,7 @@
+ some new code
- some old code
See also
- /etc/portage/patches — provide a way to apply patches to package source code when sources are extracted before installation
- User:Veremit/Patch_format
- GLEP 25 - Technical information about the formal inclusion and usage of patches within portage.
External resources
- How to write clean patches when not using git-format-patch.
- Patching with eapply - Describes how ebuilds should use PATCHES=( "${FILESDIR}/mypatch.patch" "${FILESDIR}/patches_folder/" )