Bitbucket's fork feature makes the process of contributing to an open source project easy. Chad Perrin explains how to take advantage of the opportunity.
The Bitbucket code hosting site is a great resource for people starting open source projects and for people who want to contribute to open source projects hosted there. If you are running one of these projects, the most obvious way to solicit code contributions from people is to give them commit access to your repository. It is often the case that you do not want to give everybody with an idea the ability to commit code to the repository, though.
There are a number of ways to solicit contributions that do not require handing out copies of the keys to the kingdom. One example is the Patchbomb extension for Mercurial. From the Patchbomb extension page: "This extension adds a new email command to send a collection of Mercurial changesets as a series of patch emails." Another is submission of patches as attachments on emails sent to a project mailing list. Patches can be stored on Web servers for download as well. Numerous other kludges and work-arounds can be invented as needed.
None of these are really necessary for a Bitbucket hosted project, however — and they all require use of tools and contributor commitments outside of Bitbucket itself. Bitbucket provides all the tools you need to make it trivially easy to access, vet, and ultimately merge contributions with the main development codebase, assuming the contributor has a Bitbucket account. Central to the toolset Bitbucket provides for this is the humble fork.
The contributor's side
Every Bitbucket project has a
fork link near the top of the page. By clicking this link, you can create a separate Bitbucket project repository that is an exact copy of the repository you wish to clone. As a contributor, you can then clone your Bitbucket repository locally, make changes, commit them locally, and push them to your Bitbucket project just as if you were a lone developer hacking on the sources of the original project. Of course, in that case you are not actually a lone developer hacking on the sources of the original project.
The next step is to pull from the original project and, if there are any changes that were made there since you created your clone, merge them with your local repository. The process is simple.
- Open the original project's page in your browser (e.g., the droll project), and copy the URI for cloning the repository (e.g.,
- Issue a pull command, explicitly using that URI (e.g.,
hg pull ssh://email@example.com/apotheon/droll).
- Merge any changes (i.e.,
- Commit your changes (i.e.,
- Push the merged codebase to your fork on Bitbucket.
Giving the maintainers of the original project the chance to examine and possibly adopt your changes is simple at that point. Open the original project's page again, and click the
pull request link in the same row of links as the
fork link. You will have the opportunity to specify your fork of the project as the source of the pull request. This causes a message to be sent to the project maintainer telling him or her that there is a code contribution available for inclusion in the original project.
The project maintainer's side
When you receive a pull request, you can get the source from the Bitbucket fork the same as you would for any other Bitbucket project you wish to clone locally. It might be easiest to create a clone of the Bitbucket fork separately from the local clone of the original project, so you can examine the code and determine whether it is something you want to merge with your code.
Once you vet the code and find it to your liking, you can delete the fork's clone and issue a pull command within your local copy of your project, much as the contributor did to ensure his or her copy was up to date. Just get the clone URI for the fork from the fork's Bitbucket page, and explicitly identify that URI when issuing the pull command. Once the contribution has been pulled, you can merge and commit, then push the commits to your Bitbucket project. Almost magically, the contributor's identity is then included in the revision history of the project.
A special use case
I have issued a couple of pull requests to other people's projects on Bitbucket in the past. More recently, however, I have had to do some work on one of my projects from an untrusted environment. Just as you should take steps to protect yourself from closed source SSH, I have taken steps to protect my primary Bitbucket account from the potential for an untrusted environment to be leveraged to gain access to my development projects on Bitbucket.
I created a separate Bitbucket account whose sole purpose is to let me safely work on my projects from an untrusted working environment. I used this account to fork my project, then worked with the fork to make improvements when I had to work within the untrusted environment. When my work there was finished, I later pulled the changes from the fork into the local clone within my trusted environment and merged them. At that point, I was able to push the changes to the main project on Bitbucket under my primary account, avoiding the need to use my login credentials for my primary Bitbucket account within an untrusted computing environment.
Document the process
Simple documentation of the process involved in contributing to a Bitbucket project via pull request should probably be included with the project itself, so contributors have a simple, straightforward path to offering contributions. Alternatively, you could link to this article in a prominent place in your project's README file. One of the most common errors in open source project management is discouraging contributions by failing to give would-be contributors a simple, easy path to submitting contributions. When Bitbucket makes such a process so easy, there are not many reasons to fail to support it to the best of your ability.
Even for closed source projects, a similar process can be employed where several unprivileged contributors are involved, though the cases where closed source contributors whose code should be directly incorporated into the project will not have commit access are likely to be few and far between.