Image of a GitHub repository

How To Manage Your Drupal Patches with 'Drush Patch File'

It's only a matter of time. You encounter a bug in Drupal core or a contributed module, search the web for the issue you are encountering and more often then not, you are not the first person that has encountered the issue. You find an issue on Drupal.org and if you are really lucky, there is a viable patch associated with it. Hopefully this patch will one day make it into a release, but this won't slow you down. You apply the patch, it fixes the bug and all is well with the world. That is until it comes time to update this contrib module. Maybe a different developer is performing the update, or maybe it is just you months (years?) later. You don't necessarily remember that you previously patched this specific module and when you update it, you unintentionally overwrite the patched fix, reintroducing the bug.

To lessen the chances of this occurring, we want to be able to track all of the patches that have been applied, and ensure that they are re-applied every time the underlying code has been updated.

The Old Way

Legacy patches folder

In the past, we manually tracked patches in a directory at the top level of our git repository. Within this 'patches' directory, we have a folder for Drupal (core) patches and a folder for each contrib module that has had a patch applied. When a module is updated, it is up to the developer to consult this directory structure and identify any patches that may need to be reapplied. While this is technically a viable system, it is easy to see that there is at least one major flaw. It is not uncommon for a developer to simply forget to check the patches directory.

Drush Patch File

Recently, we have begun to utilize Drush Patch File to improve this workflow. Drush Patch File endeavors to simply document and track what patches have been applied, and automatically reapply patches when a module has been updated.

With Drush Patch File, our legacy 'patches' folder still exists, but we replace its contents with a patches.make file similar to the one below:

; Required attributes
api = 2
core = 7.x

; Core patches.

; D7 Backport: theme_table() should take an optional footer variable and produce <tfoot>
; @see https://www.drupal.org/node/1892654#comment-6956588
projects[drupal][patch][] = "https://www.drupal.org/files/Add_tfoot_support_to_theme_table-1892654-1.patch"

; Remove Html::resetSeenIds() call during form processing
; @see https://www.drupal.org/node/1831560#comment-7629461
projects[drupal][patch][] = "https://www.drupal.org/files/d7_form_html_id_1.patch"

; Contrib patches.

; devel

; Prefix tables in dpq() output
; @see https://www.drupal.org/node/2330035#comment-9105857
projects[devel][patch][] = "https://www.drupal.org/files/issues/2330035.1-dpq-prefix-tables.patch"

; Fix incrementing invalid property in _hive()
; @see https://www.drupal.org/node/2332361#comment-9118425
projects[devel][patch][] = "https://www.drupal.org/files/issues/2332361.1-hive-object-corruption.patch"

; entity

; entity_property_default_render_value_by_type() throws warnings on list properties
; @see https://www.drupal.org/node/2237141#comment-8669433
projects[entity][patch][] = "https://www.drupal.org/files/issues/2237141.1-list-warning.patch"

Getting Started

  1. Clone the Drush Patch File repo into your project at sites/all/drush.
  2. Create a patches.make file as detailed above, preferably outside of your docroot in a patches folder.
  3. Point drush to your patches.make file by adding the following line in /sites/all/drush/drushrc.php:

    $options['patch-file'] = '../patches/patches.make';

Drush Patch File's README provides detailed instructions on how to add new patches, check patch status, and apply all specified patches.

The Best Part

The best part of Drush Patch File, besides managing the tracking of all of your patches, is that it will reapply your patches automatically when you update a module!

drush up devel

> The following indicates that the patches were successfully re-applied.
Install location sites/all/modules/contrib/devel already exists. Do you want to overwrite it? (y/n): y
Project devel (7.x-1.5) downloaded to sites/all/modules/contrib/devel. [success]
devel patched with 2330035-1.patch. [ok]

Related Articles