Creating a patch

  • Revision slug: Creating_a_patch
  • Revision title: Creating a patch
  • Revision id: 37812
  • Created:
  • Creator: Nickolay
  • Is current revision? No
  • Comment updated the notice about CVS-ness of this page; 10 words added, 7 words removed

Revision Content

After you have obtained the source code, made changes to it, built and tested it (and included your tests in your patch, if possible), you'll want to get your changes reviewed and checked in. In order to do that, you need to create a file listing the changes you made, called a patch or a diff file. You can generate it using cvs diff or hg diff command.

This article was initially written about CVS; and after Mozilla 1.9 (which corresponds to Firefox 3), we switched to another source control system - Mercurial. While the ideas are the same, the specific commands and tips may not apply anymore. See Mercurial FAQ#How can I diff and patch files? for the complete list of hg commands and tips.

Note that if you want to contribute your change, you will be asked to generate the diff against the latest version of the code (CVS HEAD, also known as "trunk", or the tip of an active branch for some patches).

People who need to apply your patch will be grateful if you generate it by running cvs diff from the top-level mozilla/ directory. (In this case they can apply it by running patch -p0 < your_patch from the top-level directory without looking at the patch.)

Creating a diff of a single file

In order to create a diff of a single local file against the current file in the repository, use:

$ cvs diff -u8p FILENAME
$ hg diff -p -U 8 FILENAME

This creates a diff in the so called 'unified' format (-u), with 8 lines of context. The diff is printed to stdout by default. To redirect the output to a file, use something like:

$ cvs diff -u8p FILENAME > OUT_FILE
$ hg diff -p -U 8 FILENAME > OUT_FILE

Creating a diff for multiple files

If, instead of using a regular file for FILENAME, you provide a directory, then this directory as well as all subdirectories will be searched recursively. For example

$ cvs diff -u8p mozilla/<restOfPath>/ > OUT_FILE
$ hg diff -p -U 8 mozilla/<restOfPath>/ > OUT_FILE

will compare all files in the current directory and all its subdirectories against the versions in the repository, and write the combined unified diffs to a file named OUT_FILE, using 8 lines of context.

There should be enough context in the patch for it to be understood without opening the source file. The default guideline is to use 8 lines of context; if more context is required to make the patch understandable, replace 8 with a higher number. Also note that the more context you include, the greater the chance to be able to also apply the patch to a file which differs heavily from the original source against which the diff was prepared.

Including new files in a patch

To include a new file in your patch, use the -N option:

$ cvs diff -u8pN mozilla/<restOfPath>/ > OUT_FILE

A common problem here is that cvs diff will not include the new files that were not cvs added, and cvs add requires write access to repository.

The solution is to use the cvsdo utility, which edits CVS/Entries to make cvs think the file is added to repository:

$ cvsdo add NEWFILE
$ cvs diff -u8pN NEWFILE > OUT_FILE

Creating a patch that contains files in new directories is a bit trickier. First, create a diff of everything NOT in a new directory:

$ cvsdo add newfiles
$ cvs diff -u8pN NEWFILES > OUT_FILE

Now, you will have to cvsdo add, each new directory, and then the files in that directory.

$ cvsdo add mozilla/<restOfPath>/newdir/
$ cvsdo add mozilla/<restOfPath>/newdir/newfile

Then you can cvsdo diff on each new directory, appending the changes to your diff.

$ cvsdo diff mozilla/<restOfPath>/newdir/ >> OUT_FILE

Patches with lots of whitespace changes

When generating a patch you can ask diff to ignore whitespace changes. This is especially useful if you are doing a lot of indentation changes, such as when wrapping or unwrapping parts of the code inside if statements. To create a patch without whitespace changes use the -w flag. So if you use:

$ cvs diff -u8pN mozilla/<restOfPath>/ > OUTFILE

for your original patch, then do another patch with

$ cvs diff -u8pNw mozilla/<restOfPath>/ > OUTFILE-w

When doing so, please make sure that both patches are attached to the bug (the patch without -w is needed for the reviewer to check that whitespace changes are done correctly and for the person doing the check-in for you to apply your changes).

Automated review tools

There are some tools available that may help to catch some errors within your patch thus making your and your reviewer's job a little easier, here are some that may be useful: JST Review Simulacrum.

The next step

Getting your patch in the tree

{{ languages( { "fr": "fr/Cr\u00e9ation_d\'un_patch", "it": "it/Creare_patch", "ja": "ja/Creating_a_patch" } ) }}

Revision Source

<p>After you have <a class="external" href="/En/Developer_Guide/Source_Code/Mercurial" title="https://developer.mozilla.org/editor/fckeditor/core/editor/en/Mozilla_Source_Code_(Mercurial)">obtained the source code</a>, made changes to it, <a href="/en/Build_and_Install" title="en/Build_and_Install">built</a> and <a href="/en/Mozilla_automated_testing" title="en/Mozilla_automated_testing">tested</a> it (and included your tests in your patch, if possible), you'll want to get your changes <a href="/En/Developer_Guide/How_to_Submit_a_Patch" title="en/Getting_your_patch_in_the_tree">reviewed and checked in</a>. In order to do that, you need to create a file listing the changes you made, called a <em>patch</em> or a <em>diff file</em>. You can generate it using <strong>cvs diff</strong> or <strong>hg diff</strong> command.</p>
<div class="note">
<p>This article was initially written about CVS; and after Mozilla 1.9 (which corresponds to Firefox 3), we switched to another source control system - <a href="/en/Mercurial" title="en/Mercurial">Mercurial</a>. While the ideas are the same, the specific commands and tips may not apply anymore. See <a href="/en/Mercurial_FAQ#How_can_I_diff_and_patch_files.3F" title="en/Mercurial_FAQ#How_can_I_diff_and_patch_files.3F">Mercurial FAQ#How can I diff and patch files?</a> for the complete list of hg commands and tips.</p>
</div>
<p>Note that if you want to contribute your change, you will be asked to generate the diff against the latest version of the code (CVS HEAD, also known as "trunk", or the tip of an active branch for some patches).</p>
<p>People who need to apply your patch will be grateful if you generate it by running <code>cvs diff</code> from the top-level <code>mozilla/</code> directory. (In this case they can apply it by running <code>patch -p0 &lt; <em>your_patch</em></code> from the top-level directory without looking at the patch.)</p>
<h3 name="Creating_a_diff_of_a_single_file">Creating a diff of a single file</h3>
<p>In order to create a diff of a single local file against the current file in the repository, use:</p>
<pre class="eval">$ cvs diff -u8p FILENAME
</pre>
<pre class="eval">$ hg diff -p -U 8 FILENAME
</pre>
<p>This creates a diff in the so called 'unified' format (<code>-u</code>), with 8 lines of context. The diff is printed to stdout by default. To redirect the output to a file, use something like:</p>
<pre class="eval">$ cvs diff -u8p FILENAME &gt; OUT_FILE
</pre>
<pre class="eval">$ hg diff -p -U 8 FILENAME &gt; OUT_FILE
</pre>
<h3 name="Creating_a_diff_for_multiple_files">Creating a diff for multiple files</h3>
<p>If, instead of using a regular file for FILENAME, you provide a directory, then this directory as well as all subdirectories will be searched recursively. For example</p>
<pre class="eval">$ cvs diff -u8p mozilla/&lt;restOfPath&gt;/ &gt; OUT_FILE
</pre>
<pre class="eval">$ hg diff -p -U 8 mozilla/&lt;restOfPath&gt;/ &gt; OUT_FILE
</pre>
<p>will compare all files in the current directory and all its subdirectories against the versions in the repository, and write the combined unified diffs to a file named OUT_FILE, using 8 lines of context.</p>
<p>There should be enough context in the patch for it to be understood without opening the source file. The default guideline is to use 8 lines of context; if more context is required to make the patch understandable, replace 8 with a higher number. Also note that the more context you include, the greater the chance to be able to also apply the patch to a file which differs heavily from the original source against which the diff was prepared.</p>
<h3 name="Including_new_files_in_a_patch">Including new files in a patch</h3>
<p>To include a new file in your patch, use the <code>-N</code> option:</p>
<pre class="eval">$ cvs diff -u8pN mozilla/&lt;restOfPath&gt;/ &gt; OUT_FILE
</pre>
<p>A common problem here is that <strong>cvs diff</strong> will not include the new files that were not <strong>cvs add</strong>ed, and cvs add requires write access to repository.</p>
<p>The solution is to use the <a class="external" href="http://viper.haque.net/~timeless/redbean/"><strong>cvsdo</strong> utility</a>, which edits <code>CVS/Entries</code> to make cvs think the file is added to repository:</p>
<pre class="eval">$ cvsdo add NEWFILE
$ cvs diff -u8pN NEWFILE &gt; OUT_FILE
</pre>
<p>Creating a patch that contains files in new directories is a bit trickier. First, create a diff of everything NOT in a new directory:</p>
<pre class="eval">$ cvsdo add newfiles
$ cvs diff -u8pN NEWFILES &gt; OUT_FILE
</pre>
<p>Now, you will have to <code>cvsdo add,</code> each new directory, and then the files in that directory.</p>
<pre class="eval">$ cvsdo add mozilla/&lt;restOfPath&gt;/newdir/
$ cvsdo add mozilla/&lt;restOfPath&gt;/newdir/newfile
</pre>
<p>Then you can <code>cvsdo diff</code> on each new directory, appending the changes to your diff.</p>
<pre class="eval">$ cvsdo diff mozilla/&lt;restOfPath&gt;/newdir/ &gt;&gt; OUT_FILE
</pre>
<h3 name="Patches_with_lots_of_whitespace_changes">Patches with lots of whitespace changes</h3>
<p>When generating a patch you can ask <code>diff</code> to ignore whitespace changes. This is especially useful if you are doing a lot of indentation changes, such as when wrapping or unwrapping parts of the code inside <code>if</code> statements. To create a patch without whitespace changes use the <code>-w</code> flag. So if you use:</p>
<pre class="eval">$ cvs diff -u8pN mozilla/&lt;restOfPath&gt;/ &gt; OUTFILE
</pre>
<p>for your original patch, then do another patch with</p>
<pre class="eval">$ cvs diff -u8pNw mozilla/&lt;restOfPath&gt;/ &gt; OUTFILE-w
</pre>
<p>When doing so, please make sure that <strong>both</strong> patches are attached to the bug (the patch without <code>-w</code> is needed for the reviewer to check that whitespace changes are done correctly and for the person doing the check-in for you to apply your changes).</p>
<h3 name="Automated_review_tools">Automated review tools</h3>
<p>There are some tools available that may help to catch some errors within your patch thus making your and your reviewer's job a little easier, here are some that may be useful: <a class="external" href="http://beaufour.dk/jst-review/" title="http://beaufour.dk/jst-review/">JST Review Simulacrum</a>.</p>
<h3 name="The_next_step">The next step</h3>
<p><a href="/En/Developer_Guide/How_to_Submit_a_Patch" title="en/Getting_your_patch_in_the_tree">Getting your patch in the tree</a></p>
<p>{{ languages( { "fr": "fr/Cr\u00e9ation_d\'un_patch", "it": "it/Creare_patch", "ja": "ja/Creating_a_patch" } ) }}</p>
Revert to this revision