Open main menu

CDOT Wiki β

Changes

Working with Patches Lab

5,734 bytes added, 12:22, 22 September 2008
New page: == Overview == This lab is designed to give you first-hand experience creating and applying patches, and doing incremental builds of your source tree. The concepts introduced in this lab...
== Overview ==

This lab is designed to give you first-hand experience creating and applying patches, and doing incremental builds of your source tree. The concepts introduced in this lab will help you understand how to make small changes to your tree, share those with others, or use other people's changes.

== Instructions ==

Because open source trees are so large, developers use patches as the basic unit of work for passing code back and forth. A patch is a text file that contains information necessary to add or remove lines from a source tree. Patches are created using the '''cvs diff''' or '''hg diff''' commands.

'''NOTE: All instructions below assume the use of an objdir. Replace all uses of ''objdir'' with your object directory path.'''

=== Making a change and doing incremental builds ===

* Make a small change to a file in your tree, for example, a .cpp file in '''mozilla/netwerk/protocol/http/src'''. Here is a possible change:

#include <stdio.h>
...
...''put this code inside a function''...
/* DEBUG_<username> is defined at build time, and Faculty is the username in the lab */
#ifdef DEBUG_Faculty
printf("Hello World!\n");
#endif

* Make sure your change compiles. You need to rebuild your tree in order to test using one of the following methods:

$ make -f client.mk build

or, to make things go faster, move to the parallel location in your ''objdir'' and run make there

$ cd src/''objdir''/netwerk/protocol/http/src
$ make

''NOTE'': you can also do the above command in one step, by passing a directory to make like so:

$ make -C src/''objdir''/netwerk/protocol/http/src

=== Create a patch ===

* Now create a patch containing the changes you just made using the so called '''unified''' format (-u), with 8 lines of context. By default the diff is printed to stdout, so you should redirect it to a file. Typically patches are created from the top of your source directory (e.g., '''src/''') so that they can be easily applied later (i.e., people don't have to figure out where to apply the patch, and can just use their tree's root directory):

$ cd src
$ cvs diff -u8p . > patch.txt

If you are using hg instead of cvs, you do it this way:

$ cd src
$ hg diff -p -U 8 . > patch.txt

* Open patch.txt in a text editor and notice the changes you made are prefixed with + signs. Any code you deleted will be prefixed with a - sign.

=== Apply a patch ===

* Trade patches with someone else in the class (use http://pastebin.mozilla.org and IRC), and take turns trying to apply their patch to your tree:

If the patch was created using cvs, do this:

$ cd src
$ patch -p0 < patch.txt

If the patch was created using hg, do this:

$ cd src
$ patch -p1 < patch.txt

* Here '''-p0''' means strip 0 leading directories from each filename in the patch (hg has a quirk which requires -p1 even though you'd use -p0 in the cvs case). We do this because we are in the same location (i.e., ./) as the person who created the patch. If the directories were mis-aligned, we would have to strip leading directories using -p1, -p2, etc.

* You can use the '''--dry-run''' option to test and see what would happen if you did apply the patch. Some people like to call patch with the -s or --silent or --quiet option (all do the same thing). This will suppress all output except error messages, and can make it easier to see which parts don't work.

=== Backing-out a patch ===

* Now try backing-out this same patch. To do this you can call patch with the -R or --reverse option to tell it to swap the old and new files, basically reversing the patch.

For patches made with cvs:

$ cd src
$ patch -R -p0 < patch.txt

Or with an hg patch:

$ cd src
$ patch -R -p1 < patch.txt

* Check to make sure the changes in patch.txt are gone from the file.

=== Applying a real patch ===

When developers are working on fixing a bug or adding a feature, they write code locally, then make patches and attach these to bugs in [https://bugzilla.mozilla.org bugzilla]--the standard open source issue tracking system. This lets people try out a patch before it gets checked-in (i.e., 'landed') in the tree.

One example at the time of writing is the so-called [https://bugzilla.mozilla.org/show_bug.cgi?id=248970 Safe Browsing bug].

Download the [https://bugzilla.mozilla.org/attachment.cgi?id=339569 latest patch] for this bug. '''Save the file''' (do not copy-paste it) to your '''src/''' directory.

* Apply the patch, using what you learned above. Remember the '''--dry-run''' option and to examine the paths of files in the patch.

* Rebuild the necessary parts of your tree. You'll have to experiment a bit to figure out which parts need to be rebuilt based on the files you're changing with this patch.

* Run your new browser and prove that this new feature has actually been added.

* Blog about your experience.

=== Life-cycle of a patch in review ===

When someone submits a patch, it goes through extensive review. It is rare that a patch is accepted "as is." Usually it will go through many iterations, with comments being made at each step.

Read the comments in the following bug to see an example of this process, and watch the evolution of the patch in terms of stylistic changes to the code, fixes, optimizations, etc:

https://bugzilla.mozilla.org/show_bug.cgi?id=343416

== Resources ==
* [http://developer.mozilla.org/en/docs/Creating_a_patch Creating a patch for Mozilla]
* [http://developer.mozilla.org/devnews/index.php/2007/07/10/getting-a-patch-checked-in/ Instructions for getting a patch checked into the tree]
* There are many tutorials on using diff/patch, for example [http://tools.devchannel.org/devtoolschannel/04/06/02/1521207.shtml?tid=46 this one].