Don't "Push" Your Pull Requests
You've run into a problem, or you have an itch to scratch, so you fire up the editor and dive right in. On a good occasion the patch is simple, so you pat yourself on the back, fire off a pull request and sit back and watch - even though it is a simple patch, past experience shows that often you will have to incorporate some feedback before it will be merged upstream.
Then, every once in a while, you stumble on that gnarly problem - the one that looked simple on the surface - and you spend the better part of your day on it, or more, and the further you get in, the more committed you become to see it through. Finally, you emerge victorious with a 300+ line patch, a dozen modified files, and a feeling that you have just done the world a favor - time to fire off the pull request!
This is where it all breaks down. You expect gratitude for all the time, work, and effort you've put in, but the maintainer looks in horror at the patch as he tries to enumerate all the reasons why he can't accept it. Half the time, he doesn't even know where to start, so he picks a nitpick and digs in - your contribution is going nowhere fast and neither side is to blame.
Don't "push" the pull request
Contributions are always welcome, but surprise patches are mostly just a burden. Yes, you are offering your help, but someone else will have to maintain your code over the long term - get their buy-in first, avoid surprises. Even worse, a localized change to address a specific problem will often miss the full implications to the project: other existing use cases, future roadmap plans, or overall architectural decisions. A good idea can be implemented inappropriately for the specific project; it can be invalidated by another effort that you may not even be aware of; the timing may be wrong, and a dozen other reasons can conspire against you.
Those responsible for maintaining the code have the best perspective, so engage them early. That is not to say they are always right, and you may have to make your case regardless, but this is a discussion better had before you write the code, not after. This is one of the most frustrating paradoxes in open-source: all too often it is your most engaged fans that fall into this trap, spending their nights and weekends working on a massive contribution, only to be disappointed when the maintainer flat out rejects their work.
Code reviews are hard: start early
Next time, before you dive into the editor, open a discussion, outline your problem and solution and offer to do the work. It shouldn't take more than a paragraph to explain the goal - if you need an essay, that's a sign already that you need to break it up, or the problem is not yet well defined. If the project or the change is large, pick a specific reviewer and go over the design. Ask for help and input early, and magically, you will find your code getting "pulled" (merged) on schedule.
Code reviews are hard. In fact, as it turns out, the effectiveness of a code-review drops dramatically after 200-400 lines of code, and the suggested inspection rate is at most 300-500 lines an hour. Keep this in mind, break down large commits into small, manageable chunks. As a rule of thumb, shoot for half an hour of review, or less than 200 lines with good and clear (not clever) code. If there are multiple commits, then provide a roadmap, and get feedback on each piece as it comes together.
Good work gets "pulled" not "pushed"
There is nothing more frustrating than to read the threads, or even worse, be on the receiving end of this experience gone wrong. The contributor is wounded because they are not recognized, and the maintainer is caught in a dilemma: they want to build and foster their community, but they have to dig-in against their biggest fans. There is no winner here and neither side is to blame.
Next time, before you dive into the editor, open a discussion, outline your problem and solution, and offer to do the work - don't "push" the pull request, and don't work in the dark.