Personal tools
You are here: Home Members kaeru's Home FOSS articles Software Development Create and Apply Patches
Document Actions

How to Create and Apply Patches

by Khairil Yusof last modified 2005-01-05 02:11 PM

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.

Blog feeds

  • Blog RSS Button
  • Blog RDF Button

Other sites

  • Free and Open Source Software Foundation Malaysia Web Button

My Profile

  • View Khairil Yusof's profile on LinkedIn

No to OOXML

 

Powered by Plone Section 508 WCAG Valid CSS Usable in any browser IOSN

Copyright respective authors. Unless otherwise specified, content licensed under Creative Commons Attribution License.

Legal Disclaimer