Want to get Lullabot article, videocast, and podcast announcements delivered right to your in-box?
Let us know your email address (we won't share it) and we'll let you know when anything exciting happens.
Strategies for Patch Management
Introduction
Of course, we all know the golden rule about Drupal: "If you're hacking [modifying] the code, you're doing something wrong." And in general, this is a very good rule to adhere to. When you want to modify the behaviour of Drupal, you should in almost all cases be able to either write a custom module to do what you want, or handle the modification at the theme layer.
However, sometimes we need to modify the code. There might be a bug in a contributed module that the maintainer hasn't gotten around to fixing yet, or we might need to back-port a core patch for the next version of Drupal in order to gain a particular feature or performance benefit. We already know that forking code has a variety of severe disadvantages, so how can we best ensure that we don't get bitten in the future, while still meeting the needs of our project today?
Quick note to the uninitiated: A "patch" is a file containing a list of all of the modifications to a piece of code. For more information, see Drupal.org handbook page on patches.
Consequences of Making Sweeping Changes
At our last round of workshops, a student asked [paraphrasing], "I needed to get a site out the door quickly, so I made numerous modifications to a particular module. What is the strategy for giving those changes back to the community?" The answer, unfortunately, is that you probably can't. No module maintainer is going to take a huge patch that does 10 different things to the code: adding a new feature here, fixing a bug there, re-wording some text in places, fixing the coding style... And trying after the fact to remember what changes you made, why you made them, and trying to split them up in a distinct way so that they're independent of one another is a mammoth, time-consuming task, which takes time away from you doing your next project. So that honest intention of "giving back" never ends up materializing. And worse, when your changes are not applied "upstream" to the module, that means that you're now using a proprietary fork and that you are responsible for making sure those changes get re-applied on every update.
So, don't do that. ;)
Making Customizations Manageable
When I start a new project, I create a "patches" directory, to store patch files that contain the modifications I've made. The patch files in this directory all have the following naming convention:
UPDATE 2007-MAY-26: Because drupal.org interprets # in the filename as a link fragment, updated the naming convention to use - rather than # to indicate the issue reply number.
module_name-description_of_patch-Issue number-Issue reply number.patch
So for example:
googleanalytics-hook_requirements-137536-0.patch
nodecomment-disable-comments-121357-3.patchThis tells me:
- Which modules have I modified?
- What the heck was I modifying in each case?
- Where can I check up to see if anything was ever done with this patch by the module maintainer?
- Which specific patch in that issue was I using? (Other patches could be contributed later that improve the patch I initially used.)
So each time I go to update Drupal or one of the modules I'm using, I spend 5 minutes going through the issues referenced by the patches in that directory and see how many of them I still need. Often, it's not too many... if the patch is already in the next version of the module, I can simply delete the patch file. If not, I know I need to re-apply that patch to the updated version.
But There's No Issue ID!
What if I modified this module myself (rather than applying someone else's modifications) so there is no issue ID? Go and make one. And be disciplined about doing it right now and not putting it off until the end of your project, or even the end of your current coding stint... each distinct change you make needs to have an issue associated with it.
Doing this means there are more eyes on your code. Someone else might improve upon the patch you put out there, or the module maintainer might come along and say, "Did you know you don't actually have to do that, and you can do it this way instead?" The client benefits, because their site is infinitely more maintainable -- you don't have to skip module updates, which may contain critical security fixes, for fear of screwing up your customizations. Many of your improvements could make it to the "upstream" module, which means that there's now a community responsibility for maintaining those changes, rather than just your own. And you also essentially have built-in documentation for your project and how it differs from the norm.
So don't delay, maintain your patches the easy way, today. ;)







Comments
subversion
Do the lullabots use subversion or cvs to manage patches? Keeping the folder for patches is a good idea too.
Thanks!
Mark
Definitely...
Subversion is an absolutely critical tool to development. So the patches will be reflected in our changelogs as well. And I figure it's only a matter of time before someone comes across this article and screams, "VENDOR BRANCHES!" ;)
However, for modifications to third-party code, I prefer this method, because they are (or should be) out of the ordinary, and it's nice to keep those modifications all in one place, referencing the place to check their status. Personal preference, I guess. :)
Great advice
This is some great advice that comes non-to-late as I've just started really getting into writing patches to contrib modules that don't quite do what I want them to do. I like your idea about the naming convention, but does it make more sense to have the patch file right within the module folder itself? That is where I've been keeping them.
I also like the advice of disciplining yourself to create an issue right away. I find that if I don't, it never ends up getting done and gets lost in the fray, even though it is a bit time consuming.
I think either works...
I prefer a centralized place mostly because when it comes time to update from Drupal 4.7.6 to Drupal 5.1 (or whatever), I have one place to check for "how many ways did I fork my old install?)... also, some patches will span multiple modules; for example, core patches may touch node.module, taxonomy.module and menu.inc. OTOH, for upgrading individual modules, it can be nice to have that information right there.
And yeah, creating an issue with your patch might take a couple minutes (or longer, the way drupal.org has been lately ;) -- remember to donate!), but if your patch either gets incorporated into the module/core, and/or someone comes along and improves it, you'll benefit far more than that in terms of hours spent. Plus it increases your karma, and you can never have too much of this in an open source project. :)
module_name-description_of_patch-Issue number#Issue reply number
so far so good :)
but don't use this pattern on d.o yet, it uploads the file and then you won't be able to download it because what's after the # sign in the url is interpreted as a fragment
Right you are!
I'll update the text to change the naming convention to use another - rather than a # so it'll work on drupal.org as well. :)
A simple patches management tool
You may take a loot at http://pmsvcs.sourceforge.net/ that allows to switch between patches using many version control systems (CVS, SVN, GIT).
Post new comment