8 steps for fixing other people’s code
Before or after you’re sharing your own code as open-source, you might find yourself itching to fix someone else’s code.
Twelve months ago I made my first contribution to someone else’s project – I added some auto-generated tests to the AjaxScaffold project (now ActiveScaffold and no longer a rails generator). It was the first RubyGem I really investigated. It was the first Rails Generator I investigated. It was the first OSS project I think I’ve ever submitted a patch to. It took days.
Its always the same process
Yesterday I created a patch for Merb: an update to their README file so it converted to RDoc nicely. The whole patching process: spotting the ugly README, checking out merb trunk, changing its README, testing, creating a patch, and submitting it to Merb’s trac, took about 30 minutes whilst also doing other things.
The process was the same, I’m just better at it.
Step-by-step
So here’s how to fix other people’s code. It has Ruby-specific examples, but I’m sure the process is the same in all OSS communities. Its also worth checking out the slides from Josh Susser’s Railsconf talk on contributing to Rails Core.
1. Get annoyed by a defect or missing feature
Open source software isn’t written by an army of coders, with a back up army of testers, documenters, and “Dummies Guide” book authors. Rather, its code that fixed the author’s problem; and they were nice enough to flesh it out generically so you could use it. Or they were seeking fame and glory.
So you find problems. The project owner and all its users will be super grateful if you fix it for them.
2. Finding the source
The modern Ruby community uses subversion/svn for their source repositories. So now is your excuse to install it and start to learn how to use it.
The tricky part is “where is the repository?”
If the project has a RubyForge project go to (if its URL is http://XYZ.rubyforge.org, then its project page is http://rubyforge.org/projects/XYZ) then try the “SCM” tab on the project page. If the project isn’t hosting on RubyForge SVN, hopefully they have disabled this menu tab. If not, you’ll get version 0 when you do the checkout to tell you the project’s not hosted here.
Alternately, the project’s homepage/README file should tell you where the repository is.
Finally, email the project owner. And tell them to get their act together and publicise their SVN repos.
3. Checkout the source
Hopefully you’re told the complete URL to the trunk of the project. For anonymous access to the newgem RubyForge project the URL is svn://rubyforge.org/var/svn/newgem/trunk
A project SVN repository might contain multiple projects, and may or may not use the common trunk/branches/tags root folders. So you may need to navigate around the repository and til you find the trunk of the project’s code.
So for a generic RubyForge project, the root URL for anonymous access is svn://rubyforge.org/var/svn/XYZ.
$ svn list svn://rubyforge.org/var/svn/newgem branches/ tags/ trunk/ $ svn list svn://rubyforge.org/var/svn/newgem/trunk History.txt …
[Thx to Seth - originally I suggested doing a checkout; but list is cleaner.]
If there is a trunk root folder, then do the following:
rm -rf XYZ svn co svn://rubyforge.org/var/svn/XYZ/trunk XYZ cd XYZ
And now you’ve checked out the trunk or “edge” of the project. The latest and greatest.
4. Snoop around
Load up the project into your editor and poke around.
If it has test cases (!) try running them. You may need to create some databases and/or modify the Rakefile/connection details to work with your database. Hopefully the project comes with rake tasks to create/drop the databases. rake -T should find them.
If its a RubyGem, try installing the gem locally (on top of the existing defective gem that you’re about to fix). Again, run rake -T and hopefully there is a task install_gem or similar to build and install the gem from source. If not, send hate mail to the author. And then fix the Rakefile to use the Hoe gem. And then send a patch to the author with the fixed Rakefile.
rake install_gem
5. Make changes
Finally, you get to change their code.
If the project has a suite of test cases, please make an effort to add “failing test cases”. That is, add test cases that demonstrate the defect by failing (unless the project includes your fix).
Run the tests to ensure they are working.
6. Refresh the code from the repository (svn up)
The original repository may have changed since you did the checkout, so update your version.
svn up
If there are any conflicts, go fix them and delete any helper files created by SVN.
7. Create the patch
First, you need to tell subversion about any folders/files you’ve added (svn add) or deleted (svn remove).
Then, from the root folder of the trunk:
svn diff > i_fixed_a_bug.patch
Give the patch file a useful, readable name. Like readme_updated_for_rdoc_syntax.patch.
8a. Submit patch to trac
Each project may have a different preferred way to submit patches.
If the project uses trac then:
- Register an account (normally a link at the top right of the page) if available. Some trac installations require an account (e.g. Rails) and others allow anonymous tickets.
- Click “New Ticket”
- Fill in details (note, there is nowhere initially to add your patch). Prefix the subject with [PATCH]
- Save the ticket (check the box “Attach files”)
- Attach the patch file and save
8b. Submit patch to Google Groups
Projects hosted on rubyforge SVN cannot use trac. I personally use Google Groups for my projects – the project communities are all small enough such that its manageable.
- Join the Group (using Google Account)
- Add a picture to your Google Groups account; I cannot communicate how relatively unnecessary this step truly is
- Go to Files section (link on right hand side)
- Attach your patch file to the group
- Get the URL for the uploaded file
- Post a note/write an email to the group describing your patch, and include the URL for the patch file
8c. Submit patch to RubyForge Tracker
[link to 8c] [Thx Chris Martin]
RubyForge offers a bug/patch/feature request tracker for each Project. It is enabled by default for new projects:
- Login or Create new Rubyforge account
- Go to project page and click “Tracker“ from sub-menu
- Click “Submit New”
- Fill in details (each RubyForge Project can contain many sub-projects/gems - pick from Category drop-down)
- Check the box “Check to Upload & Attach File”
- Browse and select your patch file; put file name in File Description field as you’ve already made it human readable, because you’re a champion.
- Save the ticket
8d. Submit patch to LaunchPad Tracker
“I have to say I quite like Launchpad, now that I’ve got used to it. If you’re an Ubuntu guy like me then it is perfect.” - from Neil Wilson
- Login to/Register for your Launchpad account
- From The Launchpad bug tracker click the Report a bug button.
- Enter the name of the project, or select it from the list.
- The project in question will almost certainly provide its own bug reporting link that takes you directly to the Report a New bug page.
- Enter a one line summary and click Continue
- Fill in the comment box and click Submit Bug Report
- Then click the link “Add a comment/attachment”, and Browse for the patch file. Check “This attachment is a patch” and add a Description if required.
- Click Save Changes
8z. Email the project owner
See title: Email the project owner. Prefix the subject with [PATCH].
Why 8z? I figured readers might want to share other ways they coordinate within a project, like Google Code, etc. I haven’t used it. So, (c) - (y) are placeholders
Corollary: Tell users how to fix problems
If you administer some OSS projects, you are doing yourself a disservice not telling your users how to quickly, easily submit patches.
Either copy and paste the relevant sections above, and/or link them to this “8 steps” page.
Make it really clear on your project website that patches are welcome and will be rewarded with free t-shirts and other complimentary items of stationary, and watch those patches roll in.
For example, on the New Gem Generator site (and in all default project websites), there is a link to this page and a reference to section on Google Groups as the default.
How to submit patches
Read the 8 steps for fixing other people’s code and for section 8b, use the Google Group above..
The trunk repository is svn://rubyforge.org/var/svn/newgem/trunk for anonymous access.
Trackbacks
Use this link to trackback from your own site.

Great post. A large barrier to contributing to OSS is how to do it, and this is a great outline.
Thank you. While it is usually easy to figure out individual parts, it is much harder to connect all the dots. This post helps a great deal.
Great article as always, Dr. Nic!
One note I’d like to add is that some projects also have style guidlines (e.g., http://www.ruby-doc.org/documentation-guidelines.html).
A good step 4a might be to look for such things. Although usually only the larger projects have them.
@Mat - nice link. For me personally, I’m too eager for patches to reject them based on missing or poorly formatted docco
Ultimately, the project owner will probably clean up the patch before checking it in.
BTW - to apply a patch created with the process above use:
Then clean up any conflicts and fix up anything missing that the patcher forgot. Then update your History/Changelog file with [thx Bob the Patcher].
Thanks for yet another great post.
One thing though, a better thing to do than checking out the whole source tree to see if they have the trunk directory is to use the “svn list” (or the shortened “svn ls”) command:
svn list svn://rubyforge.org/var/svn/XYZThat’ll save you a whole lotta downloading and removing, especially on large projects with many tags.
Uh, not to be a total jacka** but the link to 8b doesn’t work in your example. There’s no #8b-fixing id on this page.
Don’t hate the messenger….
Thanks, Dr. Nic! An excellent intro for we patch-submitting virgins.
8c. Submit patch via Rubyforge (If it’s hosted there)
On the project page (http://rubyforge.org/projects/XYZ) under “Public Areas” there’s a link to Rubyforge’s built in patch tracking system.
This method usually automatically performs 8z. for you.
I’d typically email the project owner first to see how they prefer to receive patches.
@seth - ahh, legacy tags. Have added 8b-fixing as well so it works
[Read 'legacy' = 'I changed my mind']
@chris - thx - added 8c. With 8z - when you post your first patch via email, the project owner can sort you out then. Heck, they can’t be too rude about it - you’ve just given then a patch!
8 steps for fixing other people’s code…
Dr Nic Williams shares 8 simple steps he uses to submit patches to an open source project….
Excellent stuff, Dr. Nic. I think it’s hard for some of us to start contributing just because of the fear of the unknown, and this post helped me get a handle on things. Thanks.
[...] Interesting post about fixing code in other peoples open source projects. 8 steps for fixing other people’s code [...]
I’m forever honored to be associated with popping your OSS cherry
[...] Dr Nic » 8 steps for fixing other people’s code Fairly obvious to anyone who’s been using open source software for any length of time, but an excellent writeup. I feel like I should use the word codify here… (tags: programming) [...]
Added 8d for using LaunchPad Tracker, from Neil Wilson.
[...] Dr Nic » 8 steps for fixing other people’s code Before or after you’re sharing your own code as open-source, you might find yourself itching to fix someone else’s code. Here is how to do it. (tags: patch opensource programming reference rubyonrails ruby collaboration) [...]
[...] read more | digg story [...]
In step 6 you say:
If there are any conflicts, go fix them and delete any helper files created by SVN.
I assume you mean the files that Subversion creates to help you fix up the conflict. The way to clean up these files after resolving the conflict is to run:
$ svn resolved path/to/conflicted/file
Dr. Nic,
I believe modern Ruby community is using Git and Subversion and Git adoption is huge. Maybe update the post?
@Michael Klishin [via] - I agree. Amongst the various projects I manage/contribute to the processes for contribution seem to vary. With Subversion there’s really only one way to contribute but with git there various ways. Sometimes the projects will pull commits or whole branches, others will accept patches etc. I’m still not sure which method is best or what the pros/cons are for each option.
I guess the Using Git in Teams article was my initial attempt to throw around some ideas.
I also think there are cool tools coming out to make git easier to use etc. So perhaps those will drive a “best practise” for using git for contributions. Sites like github could also become the defacto standard for using git within a project. Interesting times