It’s not always obvious what really helps when it comes to getting your code upstream (i.e. accepted by core project maintainers). So, here’s a short primer based on my long experience as a Linux kernel developer and maintainer.
First, why would you want to get your code upstream?
For one thing, it reduces technical debt. Some people think maintaining code out-of-tree is the easier path. But actually, it’s burdensome. If you tweak a project for yourself and don’t send it upstream, the project can change without you and render your own changes irrelevant to the larger effort. And when you try to respond to a bug in your code, you can’t rely on upstream fixes because you’ve deviated from them. You first have to learn what’s changed and why, which is a ton of work. The longer you avoid going upstream, the worse this gets.
Additionally, by upstreaming your code, you benefit from other people reviewing it and giving you feedback. That means your code will be maintained at a higher standard than you would likely be able to achieve alone. It’s hard to think of a circumstance in which code can’t benefit from external review.
Finally, contributing upstream is how you make an impact in open source. It builds your reputation and influence within the community that you’ve joined – and if you’re depending on any particular open source project, it will give you some influence on how it develops.
Hopefully, now you are convinced that upstreaming is good. The next question is: How do you do it? There’s really just one thing you need to remember: code is not pushed upstream, it’s pulled.
A few things follow from this:
You can think you’ve built the greatest thing in the world and want to push it upstream. But what’s good for you might not be good for others. They might not see why it matters. Maybe you rely on tools that they don’t and so they’ve never had the issues you have. But for whatever reason, it’s on you to persuade the maintainers that your change will be valuable to more people than you – in other words, why they should pull it upstream.
Linus Torvalds famously noted that everyone thinks theirs is the most important code in the world, and of course it feels that way to us. But recognize that the same goes for the people whose code you are looking to change. That has consequences – you are more likely to be successful, for example, if you frame your contributions as collaborations that build on good earlier work rather than urgent replacements for badly written mistakes.
You also need to remember that you are asking others to maintain your code. If they accept your additions, they take on responsibility for it, too, and put their reputation behind it. So, understand the very legitimate reasons they can have for being cautious about accepting your changes.
Lastly, when you go to a new project, people likely won’t know how good of a programmer you really are. You can’t expect your reputation to precede you. Instead, you have to earn your place – it won’t take long, but you can’t just breeze into a project and expect everyone to be impressed that you’ve arrived (unless your name is Linus Torvalds).
If that’s the context, what about practicalities? Here’s what you should do first. Take the time to:
- Do your homework – read the fine manual
- Learn about the project and its community. For example:
- Find out who the maintainers are (i.e. who you need to convince?)
- Read the mailing list / IRC / Slack channels
- Read the issues on GitLab / GitHub and Bugzilla
- Look at previous code that got rejected so you can avoid it happening to you
- Learn from other peoples’ comments
- Get a feel for the culture of the community
- Learn the project’s procedures for submitting patches / changes
- Follow its coding style, even if you hate it!
Next, start with simple changes. One-off bug fixes and documentation updates are easy to do and usually welcomed. But do whatever small things people find helpful. That will begin to build your relationships within the community – and it’s how most maintainers started out, too. Of course, be sure to follow their guidelines and coding style as much as possible.
Then, introduce yourself. Without showing off or appearing like a know-it-all (which will guarantee that you’ll be ignored), tell people where you are coming from and what you are hoping to achieve on the project. If you are there to help solve a problem, set it out clearly and explain why you want the changes you are hoping to make. Always have a problem to solve.
Don’t forget to be humble. Listen to feedback. Remember that there’s more than one way to accomplish something and that the maintainers are usually the experts of their project. Be open to the likelihood that you’re not getting your way because they have a better understanding of the issues than you do, rather than because everyone else is an idiot. Be open to other, perfectly good solutions to your problem that help solve other issues that you aren’t aware of. Rather than getting annoyed when people write code that solves your issue, thank them for doing your work for you – and then become a reviewer to make sure that your problem is still being solved.
It’s also essential to back up your claims. Maintainers don’t accept changes simply because they work. If you say that your solution fixes a problem, explain how it does so and how it leaves everyone better off. Offer examples of how your new features can be used. Share numbers when you can, using common benchmarking tools so that others can replicate your results.
All of these points underscore that one central truth about open source upstreaming: open source code is pulled, never pushed. To contribute code in open source is to work within a context of radical egalitarianism: the community gets to decide the value of your contributions. The communities that build the best projects are welcoming, fair and eminently persuadable – but they will pull in your code on their terms, not yours.