Creating Patches

---------------- NEEDS TO BE EXPANDED/REVIEWED ----------------------

Please see these links for more information until this is written up.
http://svnbook.red-bean.com/en/1.4/svn.tour.cycle.html#svn.tour.cycle.examine.diff
http://svnbook.red-bean.com/en/1.4/svn.branchmerge.copychanges.html#svn.branchmerge.copychanges.specific

http://www-128.ibm.com/developerworks/java/library/j-subversion/index.html#N1022B
http://dev2dev.bea.com/pub/a/2005/11/subclipse.html?page=last
http://ariejan.net/2007/07/03/how-to-create-and-apply-a-patch-with-subversion/
http://dslinux.org/cgi-bin/moin.cgi/CreatingPatches?action=show&redirect=Creating+Patches
http://www.posterita.org/mediawiki/index.php/Subversion

-----------------------Draft Content-------------------------------

Creating patches

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 (SVN). Diff can be found on most *nix systems. It is 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 svn diff command). Guidelines for patch submission to the issue tracker can be found in the Submitting Patches section.

SVN diff vs. diff

Diff compares two files. The svn diff command will compare your locally edited file to the SVN repository version if you have a SVN checkout of the file being patched. The regular diff command will compare two local files (the original and and the edited version) to create a patch. The regular command can be used if you do not have an internet connection or do not have SVN set up on your computer (for more information on SVN see the SVN section of the handbook). Both commands are used with the same options and will result in usable patches.

Check your directory

The most important thing to ensure that a patch is usable is that you need to run the diff command from within the ProjectPier directory structure where you are patching. Ideally you should run diff from the ProjectPier root directory (the one that contains index.php). For example, if I have a copy of ProjectPier installed on my localhost in a folder called projectpiertest (e.g. /www/htdocs/projectpiertest) then I need to change into the projectpiertest directory before I run the diff command. You can successfully run a diff from outside of the ProjectPier 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 translations/themes vs. core patches is that not everyone puts contribs in the same location so you may want to do the diff from within the translation's/theme's directory rather than ProjectPier root. Core patches should always be made from ProjectPier root.

Readability

Patch readability is very important for the review process and a patch not created with that in mind is likely to be rejected by reviewers. The two best options to accomplish this are the -u option for unified formatting and -p to show the function closest to the difference in the code, making it easy to see what function changed.

Separating your changes and whitespace

Separate each logical change into its own patch. For example, if your changes include both bug fixes and performance enhancements, separate those changes into two or more patches. Likewise all whitespace and code style cleanup should be in a separate patch and not mixed in with functional changes to the code. This just makes it harder for reviewers to see your substantive changes. Speaking of whitespace, keep in mind that if your text editor is set up to automatically remove whitespace, then you need to turn that setting off when editing code for a patch or you could create a messy patch without intending to.

Line endings and directory separators

Use Unix line endings (LF) and directory separators (/). Line endings can be converted manually with many text editors or by piping diff output through a dos2unix utility.

The command

So the basic command to use is:

svn diff -up original.php > filename.patch
or
diff -up original.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 (uppercase) switch to svn diff and the -r (lowercase) switch to plain diff to instruct the respective program to recurse (sub)directories.

svn diff -uRp directory > filename.patch
or
diff -urp original_directory new_directory > filename.patch

Adding/Deleting files

**this is for cvs, needs review**

You use the -N switch to account for new or deleted files.

Adding

If you are using -N to account for a new file, you will also need to edit the SVN/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/SVN/Entries file like this:

Editing modules/system/SVN/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//

If you are working from a tagged version the line will have the tag at the end. Use the other entries in the file to guide you:

/newfile.inc/0/New file//TPROJECTPIER-0.8

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 svn diff -Nup will properly include the new file in the diff.

Deleting files

If you are using -N to account for a deleted file, you will also need to edit the SVN/Entries file for that directory and manually change the line for the removed file file. For example, if you want to remove system.module in the modules/system directory, you will need to modify the corresponding of the modules/system/SVN/Entries file like this:

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

That's it! all you need to do is add a - to the version, so 1.451 becomes -1.451. This works for files only, not directories.

Here is the command:

svn diff -upN directory > filename.patch
or
diff -upN original_directory new_directory > filename.patch

An example using svn diff

  1. Make sure you have the latest SVN version of the file(s) before you begin making your changes: change (cd) to the ProjectPier root directory and run the update command: svn update -dP.
  2. Make your changes to the file(s).
  3. When you are ready to roll your patch, change back to the ProjectPier root directory.
  4. Do a svn diff -up path/to/file/example.module > mypatchname.patch. This creates a new patch file in the ProjectPier root that you can now upload to an issue.

An example using diff

  1. Make sure you have the latest, clean copy of the file(s), either by downloading the latest tarball or updating from SVN (if possible)
  2. 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).
  3. Do your edits to the working (new) copy.
  4. When you are ready to roll your patch, go to the command line and change (cd) to the ProjectPier root directory.
  5. Do a diff -up path/to/file/example.module path/to/file/exampleNew.module > mypatchname.patch. This creates a new patch file in the ProjectPier root that you can now upload to an issue.