Home Overview Workflow Git GitHub Cautions Clone Maintain Patch


Getting Started with Patches and Pull Requests

Introduction

If you would like to see some change in a Boost library, one approach is to submit a patch. There are two ways to accomplish that - submitting a traditional patch file, or submitting a pull request.

Traditional Patches

Traditional patches are submitted in the usual ways:

  • Attach a diff to Boost developers list message explaining the patch. Easy to do, but least effective.
  • Attach a diff to a patch ticket. Less likely to get lost in the shuffle than a mailing list attachment, but many developers prefer to get pull requests (see below).

Pull Requests

The preferred GitHub patch approach for open source projects is to fork the library involved, develop your patch, and then submit a pull request to the library maintainer. Here is what GitHub says about what they call the "Fork and Pull" approach:

The Fork & Pull Model lets anyone fork an existing repository and push changes to their personal fork without requiring access be granted to the source repository. The changes must then be pulled into the source repository by the project maintainer. This model reduces the amount of friction for new contributors and is popular with open source projects because it allows people to work independently without upfront coordination.

Read the entire !GitHub article for more information on pull requests. Having a !GitHub account is a prerequisite, so open an account if you don't already have one.

Forking a Single Repo

The simplest way to create a pull request is to fork a single library's repo. You'll have to manually check out your fork every time you update or clone the super project, but this is generally less work than forking the super project yourself. Here's how to do that:

  1. If you haven't already done so, create a local clone of the boost tree: git clone --recursive git@github.com:boostorg/boost.git boost
  2. Go to the GitHub page for the library's repo, and fork it.
  3. Copy the ssh url for the forked library from the right hand side of the web page.
  4. Add it as a remote to your local repo: git remote add myremote ''ssh_url''
  5. Now you have two remotes: origin for the repo in the boostorg organisation, myremote for your clone.
  6. Create a branch for your changes: git checkout origin/develop -b changes.
  7. Push to your fork: git push --set-upstream myremote changes.

Now you can create pull requests from the github page for your fork. Be careful to create it for the correct branches.

When you update the super project it will switch you back to the branch from boostorg. It's generally easiest to just checkout your branch when you need it, but if you want to have it always checked out, you can create a local branch of the super project:

  1. Go to the root of the super project.
  2. Create a branch: git checkout origin/master -b updated.
  3. Edit .gitmodules and change the relative url for your module to your fork's ssh url.
  4. Commit your changes to .gitmodules: git add .gitmodules && git commit.
  5. When you update the module, commit those changes to the super project as well. For example, for Boost.Utility: git add libs/utility && git commit.
  6. You can merge updates from the boost repo using git pull - there might be conflicts if the module has been updated on boostorg.

Unfortunately, if you fork the super project on GitHub, the other modules won't work, as they're still using relative urls. To avoid this you can edit the .gitmodules to use absolute urls - see below for details. Alternatively, a user can clone the super project from boostorg/boost, and then add your fork as a remote and pull from that, so that the origin remains the boostorg repo.

Forking the super project

First, using a web browser and your GitHub account, fork the Boost super-project and the Boost library you want to patch. The GitHub Bootcamp Fork a Repo instructions give all the details, but basically you just go to the boostorg repo and click the "Fork" button on the upper-right side of the super-project or library's repo page.

Then do the following from the command line:

1. Fork boostorg/boost
2. Clone *just* boostorg/boost, not all the sub-projects (as this will fail):
 - `git clone git@github.com:ncrookston/boost.git modular-boost`
2.5 (Optional) Create a branch (I called mine 'updated')
3. Edit .gitmodules and change all the relative URLs to absolute, SSH
or HTTPS (whichever kind you or your company firewall likes).
 - I ran `:%s/\.\./https:\/\/github.com\/boostorg/g` in
vim to use https.
4. Fork the particular repos you want to apply patches to:
 - For this example, I forked 'range'.
5. Edit the 'range' url line in boost/.gitmodules to point to your fork:
 - I changed the https://github.com/boostorg/range.git to
git@github.com:ncrookston/range.git.
6. Commit your gitmodules change, push it to your fork:
 - `git commit -a -m "create local boostorg"; git push origin updated`
7. Now get all the submodules:
 - `git submodule update --init`.

You should see it fetch most libraries from boostorg, but those you've edited will be registered with the URL you gave in step 4.

If you need to make a fresh clone it's straightforward:
If you created a new branch:
 - `git clone -b updated --recursive
git@github.com:ncrookston/boost.git modular_boost`
If you did not:
 - `git clone --recursive git@github.com:ncrookston/boost.git modular_boost`

Avoid "Drive-by Fixes"

A drive-by fix occurs when a patch fixing for the original problem also contains a fix for an unrelated problem. Drive-by fixes should be avoided because they entangle unrelated fixes in the same patch or pull request.

  • The entire patch may be rejected or delayed because of a problem with one of the fixes.
  • If the patch is committed as submitted, the commit history may be muddied. This is made worse if the commit messages never mention the drive-by fix.

Instead, please submit separate patches or pull requests for each problem. That allows a library maintainer to apply non-controversial patches right away while trying to resolve issues with patches that turn out to be controversial or are outright rejected.

Acknowledgements

Sohail Somani suggested the topic, Nathan Crookston worked out the steps given in the example. Bjorn Reese suggested some corrections. Beman Dawes wrote the section on Drive-by fixes.

Last modified 3 years ago Last modified on Nov 7, 2015, 2:07:50 PM