Making a patch
Short URL to this page: drupal.org/patch/create
Video
There is a short video on Applying and Creating Patches with Git that covers much of the material on this page.
Introduction
Previously, the main way to contribute source code changes to a Drupal project repository was via patch files, as described on this and other pages in this section. As of November 2020, we have a different workflow available, similar to what open-source contributors commonly use on sites like GitHub, using issue forks and merge requests. You can still use the patch workflow described here, but for larger changes, or issues where many people are collaborating on the changes, it is preferred to use the fork/merge workflow instead.
For smaller changes, this page outlines a workflow for making a patch in a local workspace, based on local "feature branches". This page assumes you have already set up Git. Note that you can also use the drupalorg-cli tool to create an issue branch.
Prepare the local repository
- Follow the steps on Cloning a Drupal git repository to make a local copy of the repository or update your existing local copy to the latest version.
- Create a local "feature branch" for the issue you're working on.
git checkout -b [issue-number]-[short-description] # e.g. 123456-some-bug
-
If there was a previous patch that you are using as a starting point, follow the steps in Applying a patch to apply the previous patch.
Make the patch
- Make the changes you want to the repository you are working on.
- When you're ready to make a patch, open a terminal window and change to the repository directory.
- If you have added any new files, be sure to add these before committing:
git add new.filename
. Then commit any changes you've made to your local feature branch:git commit -m "my new feature"
- If there is a long lag between when you most recently cloned or updated the repository, and when you are finished making your changes, you will want to rebase your patch so that it will apply to the most recent updates to the repository. To do this, run these commands:
git fetch origin
git rebase origin/BASE_VERSION
where BASE_VERSION is the branch you started from, such as 8.9.x or 7.x-2.x. - Use the
git diff origin/BASE_VERSION
command to review the changes that will go into the patch, where BASE_VERSION is the branch you started from, such as 8.9.x or 7.x-2.x. Also reviewgit status
to make sure that all the changes you made are committed. - Check locally that the changes pass the pre-commit checks, following the steps in running core development checks.
- When you're ready, create the patch with this command:
git diff origin/BASE_VERSION > PATCH_FILE_NAME.patch
If your patch removes a binary file, you'll need to add--binary
in the command:
git diff --binary BASE_VERSION > PATCH_FILE_NAME.patch
ThePATCH_FILE_NAME
should be formatted like:[module-name]-[short-description]-[issue-number]-[comment-number].patch # e.g. some_module-some-bug-123456-3.patch
- Upload the patch to the issue, along with an interdiff file (if there was a previous patch) and a comment explaining your changes. Set the issue status to Needs review. The automated tests will run, if the project maintainer has set up automated testing for patches on this branch of the project.
When you're done: Code cleanup
After you have finished testing the patch, you'll want to get your repository back to a "clean" state:
- Use this command to revert one file that has not been committed:
git checkout filename.file
- Use this command to revert all files that have not been committed:
git reset --hard
- Use this command to delete the feature branch you created:
git branch -D [branch-name]
Making Updates To Composer-based Core Dependencies
Some core contributions will modify the Composer-based dependencies. This can lead to some confusion as to how to generate the proper composer.lock file. Here’s what you need to know for making changes to Drupal core 8.8 and later:
Composer allows you to pretend you’re on a core branch, despite being on a feature branch. An example might be that you’re contributing to Drupal 9.0.x, but you have checked out a feature branch such as 3091418-update-things
. This feature branch might change the root composer.json, and it might change core/composer.json.
You might be tempted to just type composer update
and be done. However, Composer will complain that it can’t find a version of drupal/core for 3091418-update-things-dev. That is as it should be, because there is no such version of Drupal core, and your patch wouldn’t work in DrupalCI anyway.
What you should do instead is a command like this:
COMPOSER_ROOT_VERSION=9.0.x-dev composer update [list of packages you updated]
If your changes include modifying core/composer.json, you should add drupal/core to the list, like this:
COMPOSER_ROOT_VERSION=9.0.x-dev composer update drupal/core [list of other packages you updated]
Here’s how that’s constructed:
COMPOSER_ROOT_VERSION
tells Composer what version to try to resolve for all the updates you specify.9.0.x-dev
is a concatenation of the version branch of core we’re working on (9.0.x) and-dev
. So if your issue is targeted to 8.9.x, the value would be8.9.x-dev
, and so forth.composer update
tells composer to update stuff.- *Only update the dependencies you changed. If you made changes to drupal/core, you should include that package in the list. Generally, we want to minimize changes to the composer.lock file, so only update the dependencies you changed.
This will make Composer update the dependencies themselves, and also the composer.lock file to include all the things you changed.
Additional notes
When you run composer update
on drupal/drupal, there’s an event script which will look at the composer.lock file and generate some metapackages.
These metapackages are located at composer/Metapackage/. They will eventually become Composer packages, and will be available to everyone as drupal/core-recommended, drupal/core-dev, and drupal/core-dev-pinned.
This means that if your change to any Composer dependencies modifies anything in the composer/Metapackage/ directory, then you should include that in your patch.
Here is a sample workflow for this sort of Composer update:
# Start clean.
git checkout 9.0.x
git pull origin 9.0.x
rm -rf vendor/
composer install
# Start working on our feature branch.
git checkout -b feature-branch
# Manually edit core/composer.json and save the file.
# We updated psr/log from ^1.0 to ^1.1.
COMPOSER_ROOT_VERSION=9.0.x-dev composer update drupal/core psr/log
# Composer tells us that we updated psr/log from 1.1.0 to 1.1.2.
git diff —name-only
# Show us this:
# composer.lock
# composer/Metapackage/CoreRecommended/composer.json
# core/composer.json
# We must add all those files to our changes, even if we didn't
# directly touch the metapackages.
git add composer.lock core/composer.json composer/Metapackage/
git commit -m 'Updated psr/log'
git diff HEAD~ > my.patch
Patches to info.yml files
If you are trying to patch a file that's modified by the Drupal.org packaging script (such as mymodule.info.yml
), you may run into an issue with the patch working fine on code direct from the repo, but failing "in real life" on module code on an actual site. This can happen if there are contextual discrepancies due to the Drupal.org packaging script. If you find yourself in this situation, you can:
- Create the patch with fewer lines of context than the default 3 lines of context:
git diff -U1 origin/8.x-1.x > mypatchfile.patch
- Create two patches -- one for folks to test "in the wild" / "in real life", one to actually apply to the module.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion