This past month at 窪蹋勛圖厙, we went through the process of updating all of our environments from PHP 5.6 to PHP 7.1. This process was not an easy one and took some careful testing, inspection, and review to make sure that we didn't miss any code changes between the versions.
Along the way, we encountered an issue with the module, where the summary was not displaying after a successful upload. This issue was actually logged by another user back in September 2016 with the title . The reporter graciously provided a solution (array syntax change) to create a patch, but, in the process, instead of creating an actual patch
file, the reporter uploaded the diff
instead.
As the newest member of the team, I had actually never created or applied patches to any Drupal project, so the process became a learning experience for me and one that I wanted to share with you.
What Is a Patch?
A patch is a specific file that outlines all the changes made between two sets of files. For example, if I have file and I make some changes to it, I would create a patch file that showcases the differences that I have implemented, and then I would submit it so other developers can review and/or implement it. This way, when developers are contributing to Drupal core or contributed modules, they can easily submit patches for any fixes without sending over a completely new file.
What Do Patches Look Like?
A patch file looks very similar to when you run git diff
on a file. It outlines all the added lines (+
) and all the lines removed (-
) in that specific file. Patches usually start out as diff
files and then move to a patch
file. Below is the output of a git diff for a file and we can see the added lines (+
) and removed (-
).
diff --git a/test_module.module b/test_module.module
index 17b9c77..9dc0261 100644
--- a/test_module.module
+++ b/test_module.module
@@ -13,7 +13,8 @@ function test_module_menu() {
// Admin configuration group.
$items['admin/config/services/test_module'] = array(
- 'title' => 'Test Module Settings',
+ 'title' => 'Test Module Admin Settings',
+ 'description' => 'Configure the test module',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_module_admin_settings_form'),
'access arguments' => array('administer site configuration'),
Creating a Patch File
When creating a patch file, there are two things to note before submitting it:
-
Make sure you are in the
git
repository for that one module. If you are creating a patch for a contrib module, download that contrib module from and apply it there, not your project specific repository. -
The
diff
file is not what you upload to ; make sure you have a.patch
file.
Let's get started! If you would like to follow along with a code sample, .
-
Inside of our
test_module
, we are going to create a simple patch to change the title of menu item and add a description. Go ahead and open uptest_module.module
in your favorite text editor. -
Inside of
test_module_menu()
update the'title'
to be"Test Module Admin Settings"
-
Next update, add a
'description'
to the menu item with the text'Configure the test module'
-
After following those steps, the
test_module_menu()
function should look like this:
/**
* Implements hook_menu().
*/
function test_module_menu() {
$items = array();
// Admin configuration group.
$items['admin/config/services/test_module'] = array(
'title' => 'Test Module Admin Settings',
'description' => 'Configure the test module',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_module_admin_settings_form'),
'access arguments' => array('administer site configuration'),
);
return $items;
}
-
Now that we have successfully updated our module, it is time to create the patch!
-
Open up the terminal and move into the module folder.
-
Inside the module folder in your terminal, go ahead and run
git diff
. You should see something very similar to this:
diff --git a/test_module.module b/test_module.module
index 17b9c77..9dc0261 100644
--- a/test_module.module
+++ b/test_module.module
@@ -13,7 +13,8 @@ function test_module_menu() {
// Admin configuration group.
$items['admin/config/services/test_module'] = array(
- 'title' => 'Test Module Settings',
+ 'title' => 'Test Module Admin Settings',
+ 'description' => 'Configure the test module',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_module_admin_settings_form'),
'access arguments' => array('administer site configuration'),
-
With the above output, we can now create a patch by running
git diff > test_module_patch.patch
-
This will create a file,
test_module_patch.patch
that has all of the outputs of thegit diff
command in it, but as a patch file! -
Success! You've officially created your first patch.
-
Now we want to test to make sure our patch works correctly. If you run
git status
from the command line, you should see something similar to this:
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: test_module.module
Untracked files:
(use "git add ..." to include in what will be committed)
test_module_patch.patch
no changes added to commit (use "git add" and/or "git commit -a")
-
To test, we will undo the changes we made to
test_module.module
, apple the patch, and make sure the patch changes are applied totest_module.module
. Rungit checkout -- test_module.module
. The module file will now be back to the original state before we made the changes. If we view the filetest_module.module
, you will see the thattest_module_menu()
function looks like it did originally:
// Admin configuration group.
$items['admin/config/services/test_module'] = array(
'title' => 'Test Module Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_module_admin_settings_form'),
'access arguments' => array('administer site configuration'),
);
-
Next up, we can run git apply
test_module_patch.patch
. This will apply the patch to the files specified in the patch. So for us, it will apply the changes we made totest_module.module
-
If we open
test_module.module again
, we can see the patch applied!
// Admin configuration group.
$items['admin/config/services/test_module'] = array(
'title' => 'Test Module Admin Settings',
'description' => 'Configure the test module',
'page callback' => 'drupal_get_form',
'page arguments' => array('test_module_admin_settings_form'),
'access arguments' => array('administer site configuration'),
);
That is all there is to it! Remember to make sure that you are creating a patch in the module specific git
directory. You do not want any path specific files showing up in the patch
file.
What's Next?
If you were contributing to a module on , there are a few other rules:
-
Make sure theres an issue related to the patch you are creating.
-
Name your patch file appropriately –
test_module_path
is a bad name for contributed modules. The best way to do it is with the Issue Number and then a descriptive title. For example:bulk-media-upload-previous-upload-summary-php-7-2800897-12.patch
. Look to follow the of [project_name]-[short-description]-[issue-number]-[comment-number].patch -
Make sure your patch follows all Drupal Coding Standards.
-
Make sure you follow all rules outlined by the module's coding standards.
Congratulations on making a patch! Now you can contribute back to Drupal and all of the contributed modules.