Over the past couple of years I have become more active in issues on drupal.org, in which time I have honed a selection of commands that I regularly use in the creation and application of patches. Here is a run-down of my most useful commands.
This examples in this article will focus on patches for Drupal core, but most of it (if not all) is equally relevant for contrib modules too.
I strongly recommend you read and understand the Git Instructions on drupal.org which covers many of the basics (e.g. how to set up the repo). This article with overlap on certain points, but will include a few alternatives too.
I am not claiming this is necessarily the best solution, rather the best I have come across so far - I am always learning.
Obtain latest code
If you are intending to create a patch for submission to drupal.org then you should make sure you have the latest version of code and are working on the correct branch:
git pull --rebase git checkout 8.3.x
Most of my current patches are for the
8.3.x branch, but replace this with the name of which ever branch you are working on.
Create a feature branch
I usually have multiple issues open at the same time ("Needs review", RTBC, etc.) and, because it is rare for me to fix an issue with a single commit, I create a feature branch for each issue:
git checkout -b feature/2669978-migrate_d7_menu_links
These feature branches will only ever be local so you can use any naming convention you like, but I prefer
Feature branches can also make it easier to create interdiffs (see below) so I normally make a commit to a feature branch for every patch I submit to drupal.org.
Apply existing patch
There are times when you may want to make changes/improvements to an existing patch, in which case you will need to apply that patch to your code base. Drupal.org recommends the use of
git apply -v migrate_d7_menu_links-2669978-43.patch
but that requires you to download the patch to your working directory (and remember to delete it later) so I prefer the following:
curl 'https://www.drupal.org/files/issues/migrate_d7_menu_links-2669978-43.patch' | git apply -v
which works in exactly the same manner, but uses the online version of the patch.
Patch failed to apply
git apply will not work, often when a re-roll is required. In this situation I use:
curl 'https://www.drupal.org/files/issues/migrate_d7_menu_links-2669978-43.patch' | patch -p1
which will apply as much of the patch as possible and create .rej files for those hunks that failed to apply making it easier to fix.
Create a patch
Once you have made the relevant code changes to fix your current issue (and fully tested it, of course!) it is time to create the patch. I usually use the simplest option, as recommended by drupal.org:
git diff > [description]-[issue_id]-[comment_number].patch
but here are a couple of alternatives worth remembering. If you do not want to include every change you have made to your codebase then just stage the changes you require and run:
git diff --cached > [description]-[issue_id]-[comment_number].patch
Or if this is not the first commit since branching from core (e.g. a subsequent patch), often on a feature branch, then use:
git diff [old_sha] [new_sha] > [description]-[issue_id]-[comment_number].patch
This command can also be used if you have already committed your changes.
Create an interdiff
To quote from drupal.org's Creating an interdiff:
An interdiff is a text file in patch format that describes the changes between two versions of a patch.
If you have changed an existing patch then it is recommended that you create an interdiff to make life easier for code reviewers.
Normally I use:
git diff [previous_patch_sha] > interdiff-[issue_id]-[old_comment_number]-[new_comment_number].txt
This explains why I prefer to make a commit to my feature branch for every patch (see above).
If this is the only change since the previous patch then you can instead use:
git diff > interdiff-[issue_id]-[old_comment_number]-[new_comment_number].txt
There are some cases, most notably when re-rolling a patch that has failed to apply, when the previous options are not possible. In this case I recommend using the interdiff command that is included with patchutils:
interdiff old.patch new.patch > interdiff-[issue_id]-[old_comment_number]-[new_comment_number].txt
If you have any better/alternative commands that you prefer to use then tell me about them in the comments below.