Community & Support

Advanced patch contributor guide

Last updated January 13, 2012.

Almost all improvements to other peoples' projects come in the form of a self-contained set of changes, e.g., a bug fix against a particular module or include file, improvements to existing code, and so on. The exact changes are captured in a patch file — a simple text format that shows lines added and removed.

This page describes an advanced workflow that can help maintainers give you credit in the repository log by creating and uploading a patch containing instructions for one single commit to a project hosted on Drupal.org. For the general high-level overview of patching with git, see Making a patch with Git.

Prerequisite: Every workflow requires the initial set up detailed in Using Git on Drupal.org.

Obtain or update a copy of the project

  1. Clone the project to obtain a copy of it that you can work with locally. You only need to do this once per project.

    git clone --branch [version] http://git.drupal.org/project/[project_name].git
  2. If you didn't just clone for the first time, pull the latest changes down to ensure you're working on the latest code.
    git checkout [version]
    git pull

Creating patches via topic branch

  1. Create and checkout a local "topic branch" for the issue you're working on. (If the issue appears at http://drupal.org/node/123456 then the issue number is 123456.)
    git branch [issue-number]-[short-description] # e.g. 123456-example-bug
    git checkout [issue-number]-[short-description]

    Or in a single line:
    git checkout -b [issue-number]-[short-description] # e.g. 123456-example-bug
  2. Make whatever changes are necessary to see your issue fixed.

    # Edit file in your favorite editor:
    <your_editor_here> [filename]

    # After making your edits and saving the file, confirm your changes are present:
    git status

    # Make more edits in other files and save theme:
    <your_editor_here> [other-filename]

    # Confirm changes again:
    git status
  3. When you are satisfied, make one single commit with all your changes using the -a option.
    # Commit the changes to your topic branch
    git commit -a -m "Issue #123456: Fixed all instances of foo bug."

    See the Drupal.org documentation on commit messages for more details on commit message standards.
  4. When your code is ready to show people, grab the latest code once more.
    git fetch origin
  5. Make your code apply to the latest version of the code
    git rebase origin/[version] #e.g. [version] could be 7.x-2.x
  6. Now, create your patch file. Two methods of creating patches are as follows:
    1. The most generic (and fool-proof) way is to create a diff relative to the branch you just used for the rebase:

      git diff origin/[version] > [project_name]-[short-description]-[issue-number]-[comment-number].patch
    2. In the case where you have followed the instructions above and have just one SINGLE commit on your local topic branch you can use the git format-patch command to make a patch that will include your author information.
      git format-patch origin/[version] --stdout >  [project_name]-[short-description]-[issue-number]-[comment-number].patch
  7. Upload your patch to the Drupal.org issue attached to a new comment; remember to change the issue status to "needs review", to flag the issue for reviewers.

Patch naming conventions explained

The (unofficial) patch naming convention that has emerged from the community is:

[project_name]-[short-description]-[issue-number]-[comment-number].patch
[project_name]
refer's to the project's name as it appears in the URL of the project page on Drupal.org, i.e. http://drupal.org/project/[project_name], or from the git remote repository location, i.e. http://git.drupal.org/project/[project_name].git
[short-description]
is an 1-2 word summary about what the patch does with dashes between the words.
[issue-number]
appears in the URL of the issue on Drupal.org; For example, if the issue you're working on is at http://drupal.org/node/9876543, the issue number is 9876543.
[comment-number]
is the comment on the aforementioned issue that caused another patch file to be needed or the one that inspired the patch. If there is no comment causing the patch to be submitted then none is required for the filename or you can use a comment-number of 0 (zero) to indicate the original issue. If you're fixing, changing or improving upon a previously provided patch in a way that has not yet been documented in a previous comment, you may wish to guess at the comment number you're about to post by adding 1 to the last comment number on the issue; please note that this last option is an imperfect method that may not work as intended on active issues with many people commenting. In this case, the best advise is to redact your comment offline, and refresh the page just before you paste in your comment text and attach the patch.

Hypothetical example

A patch for a spelling error on the contributed module "my_module" and a suggested fix in comment #12 of issue #9876543 might look like: my_module-spelling-9876543-12.patch.

Footnotes

  • Do not use a hash sign (a.k.a. pound sign) "#" in your patch file's name as it does not work.
  • In general, automated testing of your patches on Drupal.org by the friendly testbot is a Good Thing. However, adding -DX at the end of the patch name will cause the testbot to skip testing of the patch. For example, my_module-spelling-9876543-13-D7.patch will be ignored.
  • The best practice recommendation is to use Git, however patches may be created with many tools. The minimum requirement for uploading patches to Drupal.org is that you must be able to apply the patch with patch -p1 or git apply.
  • Before creating a patch that spans many commits, users should use git rebase -i to squash their several commits into one if it's only one logical commit.
  • Following the nomenclature documented here, a Drupal core patch might look like: drupal-proper-title-987654321-23.patch. Please note that while some people opt to leave off the [project_name] from core patches, adding "drupal-" to the front helps distinguish core patches from others, and is therefore still recommended for consistency, clarity, and simplifying the instructions.
  • When you remove or move files in the repo using git rm or git mv, git diff creates a verbose output. Use git's format-patch command with the -C and -M options will move the file, instead of removing and adding the lines. The patch size becomes much smaller as a result of this.

    git format-patch -C -M [version] --stdout > [patch-name].patch

  • If you use git format-patch to create patches and you post them to Drupal.org, then the email and name you have configured in user.email and user.name will be widely indexed on the Internet, as Google picks up all our patches. If you don't want this, you may want to consider using the alternate git diff <main_branch> >/tmp/my_module.my_issue.patch method for creating patches.
  • When you add new files to the repository with git add, avoid use of the -N option, which causes any resulting patches to try to apply against a non-existent file.
  • Since patch files themselves should never be added to a project, you may wish to tell Git to ignore them globally by adding the line *.patch to a ~/.gitignore file, followed by the command: git config --global core.excludesfile ~/.gitignore. You can also use this for other types of files that Git should always ignored, like text editor backup files. For more information, see: gitignore Manual Page.

Comments

git ignore

Example for doing this globally. I want to ignore all *~ files; as these are created by my text editor on file save.

Place the following in ~/.gitignore:

*~
*.orig
*.patch
*.diff
LICENSE.txt
.directory

Then run this:
git config --global core.excludesfile ~/.gitignore

The topic "Creating patches"

The topic "Creating patches" includes the following section:

Now, create your patch file.

git format-patch origin/[version] --stdout > [description]-[issue-number]-[comment-number].patch

It's not clear to me what the comment-number should be. Is it the comment number that will (supposedly) be generated when you (will) upload your patch? This seems rather fuzzy, because you can't really be sure about that.

Ditto. I ended up posting one

Ditto. I ended up posting one comment, and then pretending to forget the patch and posting it with the original comment number in the new comment...

Paul K Egell-Johnsen

Re: The topic "Creating patches"

The comment-number mentioned here is the one that caused another patch file to be needed or the one that inspired the patch. If there is no comment causing the patch to be submitted then none is required for the filename or you can use a comment-number of 0 (zero) to indicate the original issue.

conflict with drush_make defaults?

Heads up. It seems drush_make and the expected git format might conflict...

http://drupal.org/node/745224#comment-4118226

I believe drush_make expects patches to be rolled (by default) with

git diff --no-prefix --relative

while automatic patch testing, as indicated above, expects them to be rolled with

git format-patch

So to clarify, it states above that expected patches must be able to be applied with patch -p1, but drush_make (as mentioned in the link), has a default strip of -p0.

Awesome work though guys! Pumped for git :)

Not sure about others, but when I'm working on fixing a bug in a module used a site that's built with install profiles, I post a patch to the issue queue in question (or start on if needed), and then I fix things and submit a patch. Then in the drush_make file, I reference the release and apply the patch from the queue.

Note that the automated

Note that the automated testbot accepts patches with and without prefix created with git diff or git format-patch.

Drush Make obviously implements what was the default with CVS, the default suggestions has been adjusted with the change to Git, so drush make will have to be updated to incorporate this. If possible just like the testbot is doing it, by trying -p1 first and if that doesn't apply, he retries with -p0.

Attaching single aggregate patch vs. separate patches

Hi,

I was wondering if attaching separate patches (one patch per commit) looks acceptable to you; I think this could ease code review, imagine a reviewer telling the submitter: “patch 01 is OK” or “In patch 03 you need to change this and that”, or even “patch 04 will never be merged”.
With a single aggregate patch this is a bit harder.

Also I think we should encourage the use of git am over git apply, as the authorship of commits will be preserved that way. A footnote could mention git apply -p0 stating to use it only for older patches. If you agree with this latter point I can update the Patch contributor guide.

using rebase yields a single aggregate patch = good

As someone coming up the learning curve with git and trying to figure out a good workflow, a key point for me was learning why to use git rebase to create a patch. The explanation in the ProGit book was the one that really clarified it for me.
Here are two really important rebase benefits from the ProGit book:

  • [T]he maintainer doesn’t have to do any integration work — just a fast-forward or a clean apply. It's a simple process for the reviewer. The reviewer can use git am --signoff just once (after reviewing and approving the code of course).
  • [R]ebasing makes for a cleaner history. The history is cleaner because it looks like things were applied linearly, making things much easier to figure out. Since anyone working with the code in the future depends on this history being usable, this is really important.

Re: code review, I think that it's highly situational. Some patches are really tiny (a line or two of file changes), some are complex and large. But reviewers have other powerful and well known tools for dealing with this (grep and related tools, git diff, git apply --check and the like). Ways for making code reviews easier and more effective are a separate topic. I wouldn't want to see the d.o repos be less effective because of code reviews.

I'd like to see this guide note the reason why rebase is used. The reasons why certain commands are used are important to anyone coming up a learning curve. Even if it's decided that rebase isn't the way to go, including the reason why is still important. Yes, it's a balance; we don't want to explain how to use git, but we do need to point out important choices that will keep drupal.org working well.

I can't comment on using git am vs. git apply since I'm not that far along my learning curve... yet. :-) @ao2: Just having it mentioned in your comment drives me to go learn more about them. Thanks for bringing them up!

Cheers,
- aenw

For older versions of git, see http://drupal.org/node/1065850

What is [version]?

Thanks for the manual, but I'm stuck on the first checkout.
I want to get SPECIFIC version of the module, the released version like `7.x-2.0-beta3`.
Then I want to make my changes.
Then I want to create patch.

What version are you talking about? How would I know what 'versions' are available?

And, to say truth, even knowing Git is so sexy, the above instructions are really so monstrous in extreme that I think about shooting myself. Sorry )

git branch -a

I think the branch command will give you a list of available versions. At least that was my read on it. The annoying thing about this process is that it would take about 4 clicks in my IDE under SVN or CVS, but now we have this guessing game.

Still, I get why we need to use git, so lets git git....

Agree, I try to contribute

Agree, I try to contribute and read and think and read... is it possible that git don't want to be used or is the documentation only for some?

Hey guys make it easier for people who just want to contribute. This is really useless because I still don't know how I can made a patch.

Please dont post links again I bet i clicked and read them all. It would be better to make a step by step example (maybe for idiots) so that everyone can follow and just learn the flow.

So how can I made patch and why if I use this git diff > [description]-[issue-number]-[comment-number].patch command are there newly created files are missing?

How do I create a p1 patch using diff?

No matter what parameters I try (including -p1), when I try to apply the patch it won't work with -p1. I get:

missing header for unified diff at line 3 of patch
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?

Then if I switch to -p0, it works. What do I do?

The reason I want to use diff instead of git is that git won't let me download the current release, only the development release.

I have this problem also. I

I have this problem also. I don't mind retrieving the contrib module with git (it would usually be fetched with Drush Make in my case), but I often want to provide patches against current stable version, which is impossible with the way d.o. is currently set up. What to do?

Cheers,
Achton (aka Geddeth)
http://achton.net

Direct application with wget

You can also do direct application with wget using the following:

wget -q -O - http://drupal.org/files/issues/[patchname].patch | git apply -

binary files?

What's the best way to generate and/or apply a patch that includes (new or changed) binary files?

--full-index --binary

Using git diff --full-index --binary to generate the patch seemed to do the trick.

module name in patch filename

There are three pages that detail patch naming conventions:

The most logical format would be:

  • [module-name]-[issue#]-[comment#].patch

or

  • [module-name]-[issue#]-[comment#]-[description].patch

e.g.:

  • nodewords-n1200526-10.patch
  • twitter_block-n1264734-8.patch

And yes, IMHO even Drupal core patches should mention the [module-name], to help separate them from other ones.

Updated

I'm seeing a lot of people have different opinions and suggestions on the ideal way patches should be named, so, in lieu of an agreement and official format, let's just make the documentation *consistent*. That way, newcomers will not be confused by mixed signals, and can start off using a default that is useful, while advanced user can use the shorthand format of their liking ;)

I think everyone agrees that, at the very least, we need to see the module name and the node id of the related issue. Most suggestions are to put the module name at the left hand side of the patchfile name, while placement of the description and the node id, and even the separator character (dot or dash) are hotly debated.

So, instead of changing the order, I've simply added the [project_name]- prefix before the [description], which brings all the documentation (except one place, noted below) inline with the original suggested format on http://drupal.org/patch/submit. I've created a section on this page called "Patch naming conventions explained" to elaborate on what each placeholder means, using feedback from Damien's and others' comments.

Sadly, the one remaining place that still does not mention the need to have [project_name] at the beging is on the Version control tab of every project on Drupal.org. I believe this will require an issue to webmaster and probably a code patch against the drupalorg module.

- James

nobody click here