Now that dww has reorg'd the Patches part of the handbook (yay!) there is a bit of rewriting that needs to happen. I'm starting with the Create Patches page. I'm looking for feedback on this first draft. I am trying to get all the creating stuff on this page so that Submitting is about, well, submitting and not creating. The result that I have so far seems maybe a bit dense. I want to be thorough but not incomprehensible, so massaging of this or suggestions for breaking things out is appreciated. Once the create patches is done, the duplicate info on the submitting page will be removed. Feedback from people not familiar with patching is encouraged, since you are mostly the target audience. :)
Note, that this is written with HTML to be copied into a handbook page, so the text display in email will look a little crufty. Best viewed on d.o in the issue queue.
****************************************
Generating patches, files containing the difference between files, is the domain of diff programs. There are many programs with this functionality; some stand-alone (diff), some integrated in IDE's (Eclipse, Xcode) or version control systems (CVS). Diff can be found on most *nix systems, it's available in the free XCode Developers Tools on Mac and is included in the packages UnxUtils and Cygwin for use on Windows.
This page only deals with some basic principles using the command line utility diff (and the related cvs diff command). There is also a video available, Rolling Patches in Drupal. Guidelines for patch submission to the issue tracker can be found in the Submitting Patches section.
Diff compares two files. The regular diff command will compare two local files (the original and and the edited version) to create a patch. The cvs diff command will compare your local edited file to the CVS repository version if you have a CVS checkout of the file being patched and an internet connection. Both commands are used the same way and with the same options.
The most important thing to ensure that a patch is usable is that you need to run the diff command from within the Drupal directory structure where you are patching. Ideally you should run diff from the Drupal root directory (the one that contains index.php, cron.php, etc). For example, if I have a copy of Drupal installed on my localhost in a folder called drupaltest (e.g. /Users/username/Sites/drupaltest) then I need to change into the drupaltest directory before I run the diff command. You can successfully run a diff from outside of the Drupal directory structure and create a patch file but the patch will fail to apply properly for other people since they won't have the same system directory structure that you do. One thing to keep in mind with patching contributed modules/themes vs. core patches is that not everyone puts contribs in the same location so you may want to do the patch command from within the module's/theme's directory rather than Drupal root. Core patches should always be made from Drupal root.
Although diff can output in diverse formats, the easiest to read is the unified format. Use the -u option for unified format. Because patch readability is important for the review process it's best to add another option: -p. This option shows the function closest to the difference in the code, making it easy to see what function changed (alternately you can use the flag -F^function or in abbreviated form -F^f).
So the preferred diff command for patching in Drupal is:
diff -up old.php new.php > filename.patch
or
cvs diff -up old.php new.php > filename.patch
Note that the symbol > will redirect the output to the file filename.patch. Give it a name that helps identify what the patch is for, e.g. modulename_code_cleanup.patch. If you do not include the > filename.patch part of the command the diff will go to the standard output for your system, which in most instances will be your monitor. This way you can see what the patch will look like before actually creating a file for it. Note that you can output the patch file to another place like your desktop or a folder you have created just for patches if you want by simply typing the path name in front of the patch name, e.g. path/to/desktop/modulename_code_cleanup.patch.
When you've modified multiple files in the source tree, use diff's ability to compare directories. Add the -r switch to instruct diff to recurse (sub)directories and add the -N switch to account for new or deleted files:
diff -urNp old_directory new_directory > filename.patch
or
cvs diff -urNp old_directory new_directory > filename.patch
If you are using -N to account for a new file, you will also need to edit the CVS/Entries file for that directory and manually add a line for the new file. For example, if you have created a new file called newfile.inc in the modules/system directory, you will need to add a line at the end of the modules/system/CVS/Entries file like this:
Editing modules/system/CVS/Entries:
/admin.css/1.12/Tue Jan 16 23:15:28 2007//
/defaults.css/1.2/Fri Aug 25 09:01:12 2006//
/system.css/1.22/Wed Feb 7 03:46:21 2007//
/system.info/1.3/Tue Nov 21 20:55:35 2006//
/system.install/1.79/Fri Feb 16 16:39:46 2007//
/system.js/1.1/Thu Feb 22 16:33:29 2007//
/system.module/1.451/Thu Feb 22 16:33:29 2007//
/newfile.inc/0/New file//
D
In this example, the "New file" string is arbitrary, but the 0 must be specified as the file's revision to show that it is new. Once this new line has been added cvs diff -Nup will properly include the new file in the diff.
An example using diff
- Create a working copy of the file you are editing in the same directory as the original (e.g. example.module copied to exampleNew.module).
- Do your edits to the working (new) copy.
- When you are ready to roll your patch, go to the command line and change (
cd) to the Drupal root directory. - Do a
diff -up path/to/file/example.module path/to/file/exampleNew.module > mypatchname.patch. This creates a new patch file in the Drupal root that you can now upload to an issue.
An example using cvs diff
- Make sure you have the latest CVS version of the file(s) you are working on: change (
cd) to the Drupal root directory and run the update command:cvs update -dP. - Edit the file you are making changes to.
- When you are ready to roll your patch, change back to the Drupal root directory.
- Do a
cvs diff -up path/to/file/example.module path/to/file/exampleNew.module > mypatchname.patch. This creates a new patch file in the Drupal root that you can now upload to an issue.
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | creating_patches_rewrite_0.txt | 7.08 KB | add1sun |
| #4 | creating_patches_rewrite.txt | 7.44 KB | add1sun |
Comments
Comment #1
senpai commentedwatching.
Comment #2
boris mann commentedAll of the current writing focuses on "diff" (not yours here, but previously in handbook). Speaking with some core devs recently, they looked at me like I had a second head when I said I used diff (following handbook pages, naturally).
So, I would write about using cvs-diff by default (because it compares directly to latest code on the server, in case someone else has changed it in the meantime).
And only use diff if you are "offline", and ALSO that you need to have a "clean" version of Drupal to diff against (whereas with cvs-diff, you are comparing against the file in the sky).
Comment #3
dwwthe draft above is a good start. however:
Comment #4
add1sun commentedOK, I've added a bunch of stuff, done some more editing pursuant to feedback and also started a draft for Submitting Patches (see that issue here: http://drupal.org/node/133559). I don't want this queue to end up being log chunks of text so I am attaching the drafts as patches here on out. Not as easy to read with the HTML cruft but easier on the queue and email spam ;-).
Comment #5
add1sun commentedaha! No one noticed that both cvs diff and diff commands are the same. Doh! Fixed that and did some more cleanup.
Comment #6
add1sun commentedThis is done.
Comment #7
(not verified) commented