A guide for infrequent contributors to Racket
Do the following apply to you?
-
Maybe you want to contribute something to Racket: You’d like to improve the documentation, or you’d like to add a small feature.
-
Maybe you’re comfortable with Git, but haven’t made a pull request before.
-
Maybe you’ve made a one-off pull request, but haven’t tried to contribute to the same project over time and stay in sync with the upstream project.
If so, you may find my guide helpful. I was hopelessly confused about how to handle the branches and merging. After I figured it out, I wrote this down in a Gist as a note to my future self. Today I figured I’d dust it off and make it into a blog post.
One-time fork and setup
Fork plt/racket and git clone
your fork to your computer.
For more help on this, as well as building Racket locally, see Joe Gibbs Politz’s excellent blog post. Go read it now. I’ll wait.
Getting updates over time
If you haven’t already, define a remote for plt/racket:
1 |
git remote add upstream git://github.com/plt/racket.git |
Because nobody likes a dirty fork, get updates only using this command:
1 |
git pull --ff-only upstream master |
If you only update this way, it will ensure that your master
branch is a simple, exact mirror of the plt/racket master
branch.
Your master
won’t become cluttered with extraneous merge commits (like “Merge branch ‘master’ of github.com:plt/racket”).
This makes it easy to create pull requests containing only the commit that you intend.
Important: The
--ff-only
flag is the key to this. Don’t usegit pull
without this flag.
Note:
git pull --ff-only upstream master
is a shortcut for two steps,git fetch upstream
andgit merge --ff-only upstream/master
.
After doing:
1 |
git pull --ff-only upstream master |
You can push this back your forked repo on GitHub:
1 |
git push origin master |
Rebuild all after Racket version change
Eventually the Racket version number will increase and you may end up with stale compiled/
subdirectories:
1 2 3 |
compiled/reader_rkt.zo::0: read (compiled): wrong version for compiled code compiled version: 5.3.1.9 expected version: 5.3.2.1 |
The usual incantation may be sufficient:
1 |
make && make install
|
To force a rebuild of all collections, also do:
1 |
raco setup -c && raco setup
|
Contributing something
Create a topic branch
Never make changes on your master
branch. Instead, create a so-called “topic branch”, named after your feature:
1 |
git checkout -b my-feature-branch |
Hack, hack, hack
Make your changes and commit.
Don’t forget tests and documentation.
Prepare your topic branch for the pull request
-
Maybe you like to commit often as you work on a feature. I do. It’s a form of backup and a paper trail. That’s great, but preferably your pull request should be just one commit. Easier on the maintainer. Plus the upstream project doesn’t need 20 commits in its history for your 1 feature.
-
You should rebase your topic branch on the upstream master, to catch any changes or conflicts.
You can do both with git rebase
.
1 2 3 4 5 6 7 8 9 10 |
# First, get the latest upstream master git checkout master git pull --ff-only upstream master # Rebase our topic branch on that git checkout my-feature-branch git rebase -i master # 1. In the editor, change 'pick' to 'squash' to combine # multiple commits into one. # 2. If any conflicts from upstream, resolve them. |
See squashing commits with rebase.
Push your topic branch to GitHub
To push your topic branch to GitHub:
1 |
git push -f origin my-feature-branch |
The point of the -f
(force flag) is in case you had already pushed this topic branch. After you use rebase
(above), you’ll probably need to force the push.
Note: Using
push -f
is usually bad. Here it’s OK because we’repush -f
-ing to a topic branch in our forked repo that no one has pulled from yet.
Make your pull request on GitHub
Visit your forked repo’s page on GitHub.
If you recently pushed your topic branch, you’ll see a handy button to make a pull request for the branch:
You can also use the main Pull Request button.
Either way, you get the Pull Request page:
The pull request page has three “tabs”:
-
New Pull Request. This is a title and description. The title defaults to your commit message’s first line. The description defaults to the rest of your commit message. (If you have more than commit, you won’t have these defaults. But as described above, you really shouldn’t include more than one commit in your pull request.)
-
Commits. Preferably this should have the number 1 next to it — just one commit in your pull request. You should click the tab and double-check that the commit is what you expect.
-
Files Changed. Again, double-check to make sure it looks correct.
When all looks good, click Send Pull Request.
Waiting is the hardest part
What next? You wait for your pull request to be accepted and merged. Then it will flow back to you when you do git pull --ff-only
upstream master
, because your commit is now part of the official plt/racket repo.
But it might take awhile for the pull request to be accepted. It might never be accepted.
In the meantime, you might be tempted to merge your topic branch into your own master
. Don’t!
If you were to do that, your master
would cease being a nice clean mirror of the upstream master. Remember how no one likes a dirty fork, so we’re diligently using git pull --ff-only upstream master
?
So the simplest thing to do is just wait.
But if you really want to use your feature, in your own custom build, I suggest making some other branch (e.g. custom-build
). Feel free to merge from your topic branches (and from upstream master) into that branch, from which you can build your custom variation of Racket.
Just remember that topic branches for pull requests should still always be based off your master
, which should be a fast-forward mirror of upstream.