I usually work closely with the PR author, giving them multiple rounds of suggestions until it's up to our project's coding standards. Sometimes the PR author "drops out" of the process in frustration, as they were just trying to give us a quick fix, and didn't necessarily want to do a lot of work. In those cases, I usually thank them, and rewrite the PR (or heavily modify it). But I'm hesitant to do this in all cases, because often the PR author is excited to see their name as part of the contributors list, and/or to see their own code used in the project.
How so you deal with this kind of thing?
It's up to the PR's author to decide if they care enough to do better next time. By accepting their work and landing the change you've demonstrated an appreciation for their effort with open arms, and I feel this makes it more likely they will contribute in the future and care about doing better.
Maybe make a comment to that effect before merging as-is, creating the opportunity to clean it up themselves first.
If it's coming from a regular contributor I'm far less charitable, this approach I mostly reserve for first-time/infrequent contributors.
But it would be nice if there's a way to say "look, it is what it is, and while I'm willing to make an effort, I'm not living and breathing this codebase, and I'm not planning to become a major contributor going forward, much as I like the project. Playing 20 questions is exhausting on both ends and if you'd rather just take it and completely recast it how you want, I honestly don't mind and won't take offense" without sounding like "here's some random code, IDK if it works really, good luck, lol".
I don't even care about the authorship, I'd rather have the fix than get credit for a moribund PR. Half the time I contribute pseudonymously anyway.
1. I've been on the other side of spending time trying to figure out the arcane organizational details, existing utils functions, etc only to have there be things I missed. This is deeply frustrating.
2. I'm deeply appreciative that somebody took the effort to do something on project of mine! I recognize they did that for free out of good will and don't want to make it harder for them.
3. I know the codebase much better. I can fix up/trim/format/etc properly 10x faster than the contributor can. I'd rather spend 15 mins of my own time than try to suck away an hour or two of their time. I value my time very highly but I also try to be generous and loving, and that requires some giving of my most valuable asset: my time.
Super low effort/spammy PRs do not count. I don't merge those because I don't want to incentivize more of them.
1. Fork the PR branch. 2. Make the changes I want to see upstream. 3. Create a PR into the author's branch. 4. Ask the author to review my changes. 5. When my PR is complete, finally review and merge The original PR.
This gives me the opportunity to explain my changes in commit messages, and gives the author an opportunity to push back or argue actual functionality changes I made if it's not all coding style. Now the author has license in accepting my changes. It avoids the cumbersome comment/resolve feedback loop, shows the author that their contribution is important and I'm willing to put time into making it right, and ultimately gives them credit when their PR is merged.
As mentioned by sph: some projects have maintainers that have much stricter standards for outside contributors that for themselves. Speaking as a maintainer of a project that accepts contributions through PR requests, I am afraid I do indeed have such a double standard, although I try to avoid it as much as possible. I had to set some rules for myself:
- Contributors must fix outright bugs in their commits.
- Style issues are avoided by having a coding style enforced by a code formatting tool. This saves everyones time.
- If the commit is bug free (passes test suite and code review) and is a net improvement, accept it, regardless of my own plans for the project.
- If there is more that can be done to make it ideal, this can be done in a future pull request, or perhaps I will add those changes later myself.
I also try to hold myself to the same standards as I hold contributors to, and now often create a development branch myself for features so they get the same CI testing as pull requests, although I still sometimes bypass this for quick fixes.
>When code reviews are slow, several things happen: ...
>Developers start to protest the code review process. If a reviewer only responds every few days, but requests major changes to the CL each time, that can be frustrating and difficult for developers. Often, this is expressed as complaints about how “strict” the reviewer is being. If the reviewer requests the same substantial changes (changes which really do improve code health), but responds quickly every time the developer makes an update, the complaints tend to disappear. Most complaints about the code review process are actually resolved by making the process faster.
I generally err on the side of retaining the authorship when I do this kind of thing (our project follows the kernel's de-facto standard of retaining the original git author but adding a note of extra changes made in square brackets after the author's signed-off-by and before mine as the committer, which is how we record who's responsible for what parts of a change like this). If you've literally completely written a fresh change to solve the same problem a different way then that should be your authorship with some kind of reported-by or other acknowledgement to the PR author, though.
The other thing I try to make sure to do is thank each contributor explicitly in the release notes when their commits get merged. A simple "Special thanks to @foo for the fix for bug X, @bar for the implementation of feature Y, and @baz for improving the documentation of Z!" is a small amount of effort that I think can go a long way in making contributors feel welcome and appreciated.
After hearing this, I believe that a PR should be changed dozens of times even if it is a one line change of code. PRs can reflect a million changing things, and I often update a PR months after the code is done because new information has come in that makes the code change need more context.
More stories like this could help your cause, no?
If I expect or hope the contributor to become a long-term collaborator, I will submit the comments and wait for them to fix it. I'd rather they learn
If I don't expect them to stay around, I'll make the changes, force-push to their branch keeping their authorship, submit the comments, and let them know what I did and link to the diff caused by just the force push. I'll then ask them if it's OK and let the PR sit for a few days or until they respond, then I'll merge it.
---
The more of your expectations you can automate or at least document (e.g. in CONTRIBUTING.md) the easier it is.
If the changes are so major that the code cannot reasonably be considered theirs any more, then it would be dishonest to merge it under their name, and would not be doing them or anyone else a favor. In that case, commit and merge under your own name, but include a note in the commit message thanking them for their contribution.
It doesn’t make sense to ask contributors (especially new ones) to spend time going back and forth on such small changes. It’s better use of both our times if I take a few minutes to make the small changes and merge in.
For more complex PRs, my guiding principle is:
- Make those changes that might require a lot of back and forth and harder to explain or might be subjective.
- Request changes that are objective.
If I know they won't be frustrated by a review process, I work with them to improve it. When we get to a point where I think they'll be frustrated if we continue (or if it's just actually good now), and also the code is working, I merge it. I then will not touch it for at least a week or two. At that point, the code is fair game for me to refactor.
(edit - I think it's pretty important that the original merge is only their code, so that they have a sense of ownership & accomplishment, especially when they're college students.)
Assuming I have a good relationship with the author, if I do significant refactors to their code, I'll send them the commit in which I did so and explain to them why I did what they did so they can learn for next time.
This approach has never really backfired on me, except that maybe sometimes I forget/become apathetic about doing the second part, so I have some not-so-great code in part 2. But, it's never (to me) been worth the frustration of a volunteer contributor; people contributing to the project is more important than anything else, because otherwise the project dies. One of my projects does have one mostly-abandoned large component that no one wants to touch because someone came in, wrote a ton of mediocre code, we didn't really want to do a huge code review, and then that person left anyway because they got busy irl and/or thought "good enough" and/or got frustrated with what little code review we did do, but we openly say "this is not actively supported use it at your own risk" and people seem happy enough about the situation. Hopefully someday someone takes it over again.
I have to say, after I pointed out this was my first non-trivial contribution to the project, the developer in question backpedalled a bit and "on-boarded" me very politely and gave me lots of feedback and nice tips. But I think another way it could have gone was with me saying nothing and just quietly abandoning the PR.
I think saying something like the following can go a long way: "Thank you for your contribution and goodwill towards the project! Please understand that we cannot generally merge code that does not comply with our style standards. In your particular case, this means one of the regular developers may have to make the following changes (a,b,c) based on your suggestions, and commit on your behalf. If you'd prefer to do this yourself to carry the process to completion, and learn about our project's style and conventions a bit more in the process, you're more than welcome to do so; I'd be happy to guide the process or help out with any questions you have along the way."
This would prepare the committer that this dance is about to take place (and why!), so that they expect it, and decide whether they want to commit to it up front, rather than realise they're dancing halfway through and decide whether they want to continue or not.
Also, I would like to clarify the word 'badly-written' a bit. I would argue that occasionally, 'not up to the project's coding standards' and 'badly written' are not necessary synonyms. Some projects in particular have really awkward / prehistoric coding standards, and non-complying but well thought out commits are written with the best intentions. If there isn't a good explanation of why you're now trying to undo all those good intentions to introduce arbitrary spacings that hurt legibility, it probably won't go down so well with your committer.
If I subject others to my standards, it's annoying for them.
If I hold my nose and merge it anyway, I feel the pressure to clean it up before the release. Which burns me out, so I avoid doing this.
The thing that is hard for people to get is that time costs a ton of money. If you use software without contributing back at all, you’re getting a lot for free but at least you’re not actively costing the project. If however you “contribute” in a lazy way, it starts to actively cost the maintainers to deal with this. So: feel free to contribute but read up on what a project wants and try to show that you’re at least meeting their effort halfway in terms of sufficient detail, following coding styles and request templates, etc.
https://docs.github.com/en/communities/using-templates-to-en...
It's frustrating being on the other end of this (PR submitter), since for the repos I've contributed to, the maintainers usually want you to fix it until it's exactly how they like. Then I end up giving up and using a custom fork, or integrating their code into my program directly.
That way their commit is in the git history, you aren't "robbing" them from showing up in the contributors list.
The thing is that most of these PRs are small and very localized. The potential to do damage is very low. I'd rather have some new feature implemented with some not-so-stellar code that's hidden behind an interface then doing it myself.
I think there is a goldilocks zone between perfection (and being a control freak) and a steaming pile of crap where the stuff you're working on has a clean architecture and it is acceptable to have a few poorly written modules. I usually end up rewriting them anyway when I have time and they perform poorly. By that time the contributor is usually either long gone or already improved their skills so they don't mind me tampering with the code.
TL;DR: after it passes the tests / quality checker I just merge them and fix them later if they are too crappy. All in all the project benefits more from this compared to too strict coding standars.