Personal tools
You are here: Home Articles Development How to create and apply patches
Document Actions

How to create and apply patches

by kaeru last modified 2007-08-15 14:59

Simple guide to creating, applying and submitting software patches

What is a patch

The word patch is heard often in open source. A patch basically is, the difference between the original file, and a modified file (also called a diff). It can also be a collection of differences for entire directories. It's in plain text format, and as such can be distributed in emails or as plain text files.

The benefit of a patch, is that it is easy to see what has been changed and also easily apply it to the original (usually the maintainer of a project). This makes it easy to review, and add changes from a lot of different people. Conversely it is also easy to distribute updates without having to download the entire source code base.

Example

This is the original code. We will call it db.py.

db.py

from pyPgSQL import PgSQL

## note this code is for demo only, don't follow it :)

def initialize():   
    try:
        db = PgSQL.connect (host='localhost',database='test',user='kaeru')
    except connectionFailed:
        print "This is a useless exception message and won't help you."
    return db

def getPlayers():
    db = initialize()
    cursor = db.cursor()
    cursor.execute('SELECT name FROM players')
    players = cursor.fetchall()
    db.close()
    return players

def printPlayers():
    players = getPlayers()
    print players

In the original file above, there is a problem with the exception handling. There is no such thing as connectionFailed handler, the error message is useless and it returns an empty db object regardless of what happens.

So we're going to create a copy of that file and fix these problems.

Here is our new modified file.

db-modified.py

from pyPgSQL import PgSQL

## note this code is for demo only, don't follow it :)

def initialize():   
    try:
        db = PgSQL.connect (host='localhost',database='test',user='kaeru')
        return db
    except StandardError, detail:
        print detail
        
def getPlayers():
    db = initialize()
    cursor = db.cursor()
    cursor.execute('SELECT name FROM players')
    players = cursor.fetchall()
    db.close()
    return players

def printPlayers():
    players = getPlayers()
    print players

How to create a patch

Creating a patch is simply done by using the command diff(1), which will output the differences between the two files to stdout (your screen). There are quite a few options, but generally the one you most likely need is -Nru.

  • -u will output it in the unified diff format. This output is easier to read compared to the default one.

  • -Nr are when you want to compare files in directories N is for new files which only exist in one directory, and r is to recurse into subdirectories.

    If you're only creating a patch for one file, you do not need N and r options.

The format when creating a simple patch is,

diff -u original_file modified_file > patch.diff

or for entire directories,

diff -Nru original_dir modified_dir > patch.diff

We will get our diff by running this command.

diff -u db.py db-modified.py

Here is how our diff looks like.

patch.diff

--- db.org      Sun May 16 22:33:11 2004
+++ db.py       Sun May 16 22:33:03 2004
@@ -5,10 +5,10 @@
 def initialize():
     try:
         db = PgSQL.connect (host='localhost',database='test',user='kaeru')
-    except connectionFailed:
-        print "This is a useless exception message and won't help you."
-    return db
-
+        return db
+    except StandardError, detail:
+        print detail
+
 def getPlayers():
     db = initialize()
     cursor = db.cursor()

As you can see the unified diff gives information about what has been removed (lines beginning with -) and what has been added (lines beginning with +). It also provides you information on where this change occurred by including relevant parts of the code that were not modified.

To save this output as a file, simply redirect stdout to a file.

diff -u db.py db-modified.py > patch.diff 

patch.diff which contains the diff output, is our patch.

How to apply patches

Applying patches is quite easy, you simply read the contents of your patch (the patch.diff file) into the patch(1) utility.

If the patch file is in the same directory.

patch -u < patchfile

If the patch file is in different directories, you should look into the -p and -d options in the man page.

For our examples, to apply the changes in our patch file, we would save the patch file in the same directory as the original db.py and then run the patch command.

patch -u < patch.diff

Further reading on creating patches

Good Patching Practice

From Eric Raymond's The Art of Unix Programming, provides good tips on how to get your patches accepted by open source developers.

LinkedIn Profie
View Khairil Yusof's profile on LinkedIn
Recently Listened
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: