Ask HN: Do you rewrite pull requests?
Just wondering how other open-source developers deal with valid by badly-written pull requests.
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?
77 comments
[ 3.6 ms ] story [ 150 ms ] threadIf 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.
https://docs.github.com/en/pull-requests/committing-changes-...
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?
Doesn't a PR need a commit to be able to create it?
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.
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.
That preserves the original author credit (and any GPG signatures), but moves things along. If that's not enabled, making a new PR based on the same commits works too.
Sometimes that just really isn't feasible or efficient. Happens often enough I glance over a PR to see it has code style issues or obvious mistakes in the code or architectural problems. Especially in those last cases, when the implementation still needs to change, I'll just point that out, then later on revisit and do a more thorough review. Because it makes no sense reviewing things which might not even end up in the final PR.
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.
It's not that I will refuse to make changes, I will, within reason, it's that I'm also fine with the maintainer just taking over at any point and finishing it however they want, without any further back-and-forth. And I don't even care whose name is on it.
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.
Sometimes I will actually create the fixup commits and push them separately to communicate with the submitter, but then squash them into the appropriate places in history before merging.
The only technical issue is when someone has signed their commits, as I obviously cannot re-sign them :-). In that case, I call it out to them and let them re-sign if they want before I merge.
If I find an issue in your code and I submit a pull request or (more likely) file a detailed issue with associated patch, and I watch you try to block back onto me to edit it to your liking when I know it would take you less effort to just do that final work yourself, you are less likely to get me to care in the future to do the work to isolate an issue and potentially even likely to lose me as a downstream user of your code.
I also definitely wouldn't want you force pushing a change with my name on it: if you are editing my code it isn't my code anymore... just commit the code as you. I am not playing some weird game where "credit" on a commit matters: I'm trying to get work done (as I'd hope we all are), and feel a need to be helpful to others instead of selfishly hoarding patches for myself. And if someone is playing such a game, it is probably better to discourage them of it rather than putting up with it.
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.
I've seen projects (on GitHub, won't call them out) get bad reputation when the maintainer implements code previously submitted as a PR.
I will. vim/vim has been doing this for years, with Bram basically ignoring the whole point of GitHub, and putting his name on every commit. I love Vim, but that's not acceptable.
I don't understand how this is the whole point of GitHub. I feel like GitHub has exacerbated misguided expectations that every contribution is worthy and that being rejected should feel bad.
Simplify maintenance and encourage contributions
One project has 700+ contributors, the other is less than 120. So no, it's not looking "fine" from a user perspective.
Not aware there would be a standardized header for that, but you can always invent your own ones.
[1] https://github.blog/2018-01-29-commit-together-with-co-autho...
Edit: * that almost never happens, it appears that github now supports changing the base of a PR
> merge pull requests liberally and get new contributors’ “vision of progress on record” so that they immediately become members of the community. Worry about fixing the progress later.
See also https://jeremyfelt.com/2016/03/12/pieter-hintjens-building-o...
>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.
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.
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.
I guess that's messy if it's linked to issues and the connotation of "declined PR" isn't as nice.
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.
https://docs.github.com/en/communities/using-templates-to-en...
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.
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.
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.
Do you have any particular rules about performance? I worry that accepting net improvements on functionality alone could result in “death-by-a-thousand-cuts” performance issues down the line (assume it’s a project where performance is one of the deliverables).
Would you ask a contributor to perform benchmarks or some other performance validation, for example?
What you do with the performance results really depends on the kind of patch they want to commit. Is it an important bug fix? Then I would get that merged first and worry about fixing performance afterwards. And then you have those patches that improve performance in one area at the cost of decreasing it in another. In that case you might have to use your experience in what is more important to decide whether to accept or reject it.