August 15, 2013
So one thing that inevitably happens when working on enterprise distros is the number of patches to a package builds up over time. It makes sense; part of what a customer pays for is backports and fixes. The other day someone sent me a mail asking how I deal with the patches in a package. I figured it would be useful to write it out here, too.
First, (much like in Fedora), RHEL packages are stored as git repositories. They’re stored as a .spec file, the patches, and a file with a checksum for the source tarball. The patches themselves may be done in many different styles (git-am formatted patches, patches generated with the gendiff command, or just manualy diff’s). Each patch file may have multiple patches in it together. For instance, in gnome-screensaver for RHEL6, there is a patch file called “fix-unlock-dialog-placement.patch” that has 2 patches in it, one that makes the unlock dialog always show on the primary monitor, and another that forces the mouse pointer to stay on the primary monitor. So in my workflow, it’s one file per fix or feature, but potentially more than one patch in a file.
As issues are corrected, older patches may need to be updated to fix bugs in them, and those changes may require rebasing subsequent patches from other files so they still apply on top.
The easiest way to work with the patches is to apply them to the upstream source in a git repository, so the standard git rebasing machanisms can be used.
That’s where this script i hacked together sometime ago comes in for me. The way it works is I clone the upstream git repostory, then run
git checkout -b rhel 2.28.3
(where 2.28.3 is the upstream tag that tarball is generated from)
git spec-apply ../path/to/spec/and/patches/dir/gnome-screensaver.spec
(where gnome-screensaver.spec is the name of the spec)
It then goes through and applies all the patches in the spec file one-by-one to the branch, and creates sub-branches for every patch file. If i’m going to work on one particular feature or fix, I jump to that branch to fix things up. When i’m finished I run git format-patch to regenerate the patch file. If necessary, I rebase the patches that apply on top as well and regenerate them too.
So that’s my workflow. I’m not really advocating the script for others to use. There’s a much more complete program that Federico wrote that works on SRPMS instead of expanded spec file + patches trees. I haven’t yet tried to fold it into my workflow, but want to eventually.