Last updated May 24, 2013.

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 [branchname] 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 [branchname]
    git pull

[branchname] might be 7.x-2.x for example. See footnotes below for complete indications about git branch names. In general, do not attempt to contribute patches against git tags.

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 them:
    <your_editor_here> [other-filename]
    # Confirm changes again:
    git status
  3. When you are satisfied, make one single commit with all your changes. If you are not adding new files, you can do this using the -a option. If you are adding new files, you'll need to git add the new files before making your commit.

    For complete information about adding files, see https://www.kernel.org/pub/software/scm/git/docs/git-add.html. The following command, using -a, will add only updated files (preventing things like accidentally committing the .patch file.)

    # Commit changed files to your topic branch
    git commit -a -m "Issue #123456 by username: Fixed all instances of foo bug."

    See the Drupal.org documentation on commit messages for more details on commit message standards, including how to express proper patch attribution.
  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/[branchname] #e.g. [branchname] 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/[branchname] > [project_name]-[short-description]-[issue-number]-[comment-number].patch
    2. For contrib projects (core does not use attribution) - 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/[branchname] --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.

Note: If your patch is a modification of an existing patch, please provide an interdiff.

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 advice is to redact your comment offline, and refresh the page just before you paste in your comment text and attach the patch.
do-not-test
can also be added before the .patch when the patch you are uploading will not work with the current version of Drupal. For example, you are fixing a bug in Drupal 8, so the issue is tagged with version "8.x" but you want to upload a patch for Drupal 7 too, so that when the D8 version gets committed the Drupal 7 version will be all ready to go.

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

  • See Configuring git for tips on your configuration, including how to make git ignore certain filenames and how to move or rename files cleanly.
  • git branch names

    The [branchname] specifically refers to an existing development branch of the given project which follow the format "drupalversion.x-projectversion.x". So, for example, the branch name of version 3 of the Views module for Drupal 7 would be 7.x-3.x. Note that this differs from the development releases notation listed on project pages and elsewhere which adds "-dev" to the end of the version, e.g. 7.x-3.x-dev. In the context of git, "-dev" is extraneous information.

    If you're unsure which branch you need, or if the [branchname] you thought existed does not, you can first clone the project, without the branch information from the first step above, using git clone http://git.drupal.org/project/[project_name].git . Then explore all the branches using git branch -a to list them and git checkout [branchname] to switch to the one you need. You may also obtain an official git branch name from the "Version control" tab (example) of any project.

  • Do not attempt to create or apply patches to git tags. This causes trouble for not only you, but everyone else trying to use your patch. Except in very specific an unusual cases, patch development should generally be done on branches.
  • 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 -do-not-test at the end of the patch name will cause the testbot to skip testing of the patch. For example, my_module-spelling-9876543-13-do-not-test.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.
  • 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 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.

Comments

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
*.rej
*.patch
*.diff
LICENSE.txt
.directory

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

thanks for the tip

thanks, very helpful.was exactly looking for git ignore way.

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 comment, and then pretending to forget the patch and posting it with the original comment number in the new comment...

Paul K Egell-Johnsen

The comment-number is the comment number that your comment (with the patch attached) will end up being. Say there is 3 comments all ready and you are going to post a patch, your comment would be '4'. It is the semantic comment number not the one in the URL.

-----------------------------------------------
The Future is Open!

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.

The comment-number is the comment number that your comment (with the patch attached) will end up being. Say there is 3 comments all ready and you are going to post a patch, your comment would be '4'.

-----------------------------------------------
The Future is Open!

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 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.

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.

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

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 )

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....

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 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

How about making 2 copies in subdirectories a/ and b/ where a is the original and b is modified, and run diff from that top level? (I haven't tried this, but sounds like it should work)

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

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

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

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

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.

--
Damien McKenna | Mediacurrent

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.

see http://drupal.org/patch/submit#patch_naming and this page at http://drupal.org/node/1054616#naming-conventions

This page makes the most sense to me, since a guess as to which number the comment will be might be wrong.

What is [version] and where do you find this [version] info?

git clone --branch [version] http://git.drupal.org/project/[project_name].git

@earwax, you can get the version number by going to a project page, then clicking on the "repository viewer" link under the Development section. Form there, the version numbers are listed under the Tags section.

Yeah, same question. I'm trying to clone megamenu version 6.x-2.0-beta2, but it's not a branch, it's a tag according to http://drupalcode.org/project/megamenu.git

But I couldn't find how to clone from a tag, i.e. there's no --tag option. When I try to use the tag as --branch, I get

>git clone --branch 6.x-2.x-dev http://git.drupal.org/project/megamenu.git
Cloning into megamenu...
remote: Counting objects: 192, done.
remote: Compressing objects: 100% (96/96), done.
Receiving objects:  76% (146/192), 28.00 KiB | 37 KiB/s
Receiving objects: 100% (192/192), 54.98 KiB | 37 KiB/s, done.
Resolving deltas: 100% (125/125), done.
warning: Remote branch 6.x-2.0-beta2 not found in upstream origin, using HEAD instead

By the way, I'm using tortoisegit (http://code.google.com/p/tortoisegit/), much easier to use than command line, highly recommend.

[EDIT]
Unfortunately tortoisegit didn't help with the tag either

[Another EDIT]
In tortoisegit I couldn't find how to clone from a tag, but after cloning from HEAD, selected Switch from the menu, then there's the list of all branches, tags, etc.

I've updated the instructions above to explain that a [version] refers to a development branch, and that official release versions (ie tags in git) should generally not be used when following this patch contribution guide with git, if at all possible.

Yeah, I noticed the update, thank you.

I started my changes from the specific version I installed, so I have to create path against this tag.

Probably another option is to merge from the head to my version and then create the patch?

> Probably another option is to merge from the head to my version and then create the patch?

Yes this should work. Git clone the module, switch to whatever version of the code you started from (eg, at a specific tag), create a topic branch, apply your code over-top, and confirm that *only* your changes are present. Then merge from head (or the most logical place, such as the branch to which the tag pertains).

There should be more information on this page regarding using drush dl to checkout projects from git.drupal.org.

To get started, take a look at the documentation for drush command pm-download:

  • drush pm-download
    • --package-handler=git_drupalorg
      • --gitusername
    • --dev

--
Madness takes its toll.
Please have exact change.

Hi all,

Can commits into core be authored by the user how actually submitted a patch? In the article it is said:

For contrib projects (core does not use attribution) - 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.

Does it mean that commit to core never can be authored by the patch creator or it can be done explicitly by someone who actual commits code using this attribute --author="authorname "?
I want to encourage my team to spend more time contributing into D8 and it would definitely add enthusiasm if they could see commits on their profile.

Dmitry

I would like the "(core does not use attribution)" sentence clarified too. I hope it only means no automatic attribution works on core but that the person that commits the patch gives manual attribution to the person that contributed the code. I want to believe it doesn't mean that the core commiters are getting attribution for other people coding. So could someone clarify please? Thanks.

A nice simple way to create a patch that includes a new file, then reset back to a clean state before the addition.

git add -N transliteration.api.php
git diff > ../patches/transliteration-1919874-5-alter-hook.patch
git reset --hard

This basically flags the file as "intent-to-add" to the git index, so the default git diff output will include the file, and then you can easily reset the branch back pre-add.

[edit]
Note that this is not recommended by the doco above? I guess that this is purely for semantics, as it appears to be fully functional excluding new file notice within the patch.


Alan Davison
Back roads somewhere in South America