Merge Pull Request Considered Harmful
blog.spreedly.com
blog.spreedly.com
However being able to edit pull request before merging was a good thing to learn. However I think in the long run I would want to learn it with plain old git rather than tack on another tool to my workflow.
And I hear your RE adding another tool, as I'm very cautious about that myself. That said, `git am` is "git cannon", and all hub is really adding is the ability for it to slurp Github urls as well as Maildirs.
Neat, related trick: add ".patch" to the end of any PR url on Github and you'll see a formatted patch for the PR. All hub is really doing is slurping that and passing it to git as though it came from a mailing list.
It is in reality. Try to git bisect a bug. (Yes, I read the part about the bisect in the post. But thanks, I'd rather search the bug in several 10-line patches than in one 1000+).
If someone contributes a true 1000+ line contribution that I'm even willing to take (yikes!) then you better believe I want that in multiple, logical commits, and it may even be me that ends up doing the splitting.
I'm sure a lot of it just has to do with what types of contributions a given OSS project receives, so YMMV.
Return a 125 from your script if the tests fail.
Well, if you're going to be bisecting a lot or compilation takes a while, it saves you time to do the squash now (when you know which commits are supposed to compile and which aren't) rather than when you come back to it.
> The commit you end up with or N prior commits which don't build (and which is incidentally usually full of "noise").
The alternative, where things are squashed together, would leave you with just one commit but it'd be those N combined together (at least, it could well be more).
You could also have a little script that does something like:
# Usage gbisect_prs bad good
git bisect start
for commit in "git log --since good --until bad"
if not commit.message.startswith("Merge pull request #"):
git bisect skip commit.hash
Turned into real code, obviously, but it'd tell git to ignore any commit that's not a PR merge.You could also just include this into your bisect script if you're not doing it by hand, return 125 if it's not a commit you want to test.
In a sense I work this way, without the squashing. When I write a test, the build fails and nothing has been done on the application codebase so I don't commit. When I fix the build by writing new code, I commit.
Maybe I should be doing small intermediate commits and squashing the commits into one commit.
I would recommend trying that, or at least something similar: Try committing regularly (this is useful if you ever want to go back to a prior state while working or e.g. pick up where you left off on a different machine, etc), but reorganizing and cleaning up your topic branch (via rebase -i, etc.) into a few commits before merging (fast forward). What is "a few commits"? Well, it's a bit of a judgement call, but I just group stuff into logicially coherent units which make sense as single units of functionality. Of course you must make sure each individual commit at least builds sensibly and preferably that all tests run too.
it helps prevent a SVN/CVS-style workflow, which will negate many of the other benefits of Git IMHO.
> you can create a script that tests for the thing you are looking for.
Yes, which you can tell to skip anything that doesn't compile/pass tests. Return 125 from your script and it'll be skipped.
> Non-building commit = more manual bughunting.
But you can just do a loop of "make || git skip" and skip everything that doesn't commit, surely. Or if you're using a script, just return 125 for things you want to skip.
For "conceptual chunks", I use branches or tags, and don't worry about the individual commits very much.
What stops you from doing automated git bisects when some commits shouldn't be tested? Returning a 125 from your script if it doesn't compile will skip that commit. When it comes to GH you can skip any commit where the message doesn't start with "Merge pull request #" for example.
Can you come up with an concrete example of where this would be a problem? I might be missing something but I can't picture a case where there'd be an issue.
http://www.mail-archive.com/dri-devel@lists.sourceforge.net/...
Turns out Linus also agrees with drunken_thor, that merge messages are useful. Suppose that's why Linus added merges in the first place. ;)
Most open source maintainers are not in that position.
So basically:
git fetch origin pull/ID/head:BRANCHNAME
git checkout BRANCHNAME
And now you can edit that pull request and/or make new pull request based on the previous one. Or just simply merge in master.I don't know about you guys, but I have not found them useful? Do you use the merge commits for anything?
You can also see the set of changes in a topic merge easily with "git log ${merge}^2..${merge}^1" whereas if you use a fast-forward merge it's not at all obvious which sets of commits are related.
https://gist.github.com/piscisaureus/3342247
and then you'll have each PR available under sth like
git checkout pr/123Note though that doing a fetch will take some time the first time after you set up this - it will fetch all the historical PRs.
The result is the same, but I've found the `git am` workflow to be much smoother vs. mucking around with remotes. Some of that could be due to the nature of the OSS project I work on - ActiveMerchant - since just in the last month we've had 30+ unique contributors, and most of them have contributed a single change.
My general recommendation is to make sure you try out the `git am` flow for a bit, but then just do what works best for you.
This makes life harder for the submitter, because they cannot ask a simple question: were my commits merged into the upstream repository? Because no, they weren't; but commits that are the moral equivalent were. Usually `git log --cherry-pick` can correlate the two, but not always.
We do use `git am` upstream when working on git itself, for the reasons you indicate in the article (plus we like mailing-list based review). But it does come at a cost in managing the various versions of patches.
And when I accept a patch, even if I've had to edit the commit summary so it is parsable english (not all of my contributors speak english as a first language), I send a reply via e-mail saying "Thanks, applied".
While I've often wished that Github had a proper mailing list per repository that could be used to discuss changes, I have to say that one awesome thing about PR's is how nice they make reviewing a patch. The diff view is just awesome, so now that I have a `git am` style flow with them it would be hard for me to switch to just passing patches around on a mailing list. That said, a mailing list would still be a welcome adjunct to the PR flow if done right.
git fetch origin pull/ID/head:BRANCHNAME
git checkout BRANCHNAME
// make changes
git push origin pull/ID/head...but it doesn't so you have to:
- checkout a local copy
- add a remote to the PR
- checkout a new branch
- merge the PR into your local branch
- fix code, merge to master
Which is entirely true; it is annoying.The simple solution, though, is to require pull requests to come in a feature branch, and flat out reject any that target master. /shrug
It's just: git fetch origin pull/ID/head:BRANCHNAME git checkout BRANCHNAME
Edit: I see that MaikuMori[2] posted the same information just before me; ah well.
[1]: https://help.github.com/articles/checking-out-pull-requests-...
Agreed, and in my experience, every major open source project I'm familiar with requires pull requests to feature branches. In fact, most small projects use the same workflow.
Is this not the case with most open source projects?
There are a lot of small, one-off, often very useful utilities that people are now sharing with each other via Github (I'm guilty/a participant in this phenomenon), and many noble users of these utilities want to help, contribute, and send PRs... a non-negligible number of them new to Git.
So, is it more of a PITA to set up a feature branch for a single python script and instruct users in your CONTRIBUTING file to 'make sure they submit PRs to branch XYZ!' or just deal with the odd occasional PR to master? Folks new to Git will probably just send a PR to master anyway (I believe OP addresses the 'new user' issue as well, having to explain Git commands to users in comments on a PR)
That all being said, I still typically follow the workflow shadowmint outlines above.
In general I'd just encourage maintainers to try the `git am` flow, especially on small to medium complexity contributions where it looks mostly ready to go and you don't want to do another week of ping-pong with the contributor just to get a variable renamed or some whitespace fixed.
As I tell my kids, "Just try one bite of <food I find delicious>. If you don't like it, that's cool, then it's more for me!" :-)
I haven't learned git yet so maybe my assumption that the original PR is on a branch/repo clone to which you can submit a PR is incorrect?
Bob requests that Alice merge bob/bob-feature into alice/master.
Alice requests that Bob merge alice/fix-bob-to-conform-to-pep8 into bob/bob-feature.
Bob merges that into bob/bob-feature, and Bob's PR into Alice's repo is now auto-updated to reflect the changes that he merged into his branch.
Alice is now satisfied, and merges bob/bob-feature with alice/master.
The issue described by the author is definitely more of a workflow problem than a technology or service problem.
[1]: https://github.com/torvalds/linux/pull/17#issuecomment-56546...
Another very common one isn't about bureaucracy, but making the commit messages readable --- including the stack trace of the faliure you are fixable (which again is important for non-toy projects that are being distributed in other products, and where people may cherry-pick fixes into a stable branch used for release purposes). Or if you have contributors from around the world whose native language is not English, and you want to make it easier for other people to understand what the heck is going on without having to read the contents of each and every diff.
This is fundamental to project health, which means that a proper workflow is fundamental to project health. Given that the vast majority of github repos are toy-sized, or end up being abandoned, maybe that's fine for github. But for any project where I have hopes that it will turn into something real (and if I don't have that hope, why would I waste time on it?), I'm not going to accept pull requests from git hub.
It is not just going to happen.
Here's another example: I recently made a PR to a project to fix a broken URL. I changed a wrong file and forgot about the PR. The maintainer had to close the PR, make the change himself, and explain why/what he did. This whole process would've been a lot simpler if Github allowed people to merge to another branch.
Is this a problem that comes from forking? I raise PRs on my projects onto various different branches all the time. Or maybe I've misunderstood the issue.
The first hit on Google and Bing for "git committer vs author" brings up this SO entry:
http://stackoverflow.com/questions/18750808/difference-betwe...
So, I don't think I'm taking some fringe view here. For my part, I don't think I want someone else writing code and putting my name on it.
I used to strictly stay away from the Pull Request button, because it made my history "messy". Now I care less about that and more about the convenience (when it's appropriate).
That's a very strange way to end an article. Could have just stopped before adding that last line.
that is right, editing history is the way to go, or is it? :)
http://meyerweb.com/eric/comment/chech.html
Which essay I already knew about and chose to willfully ignore when I titled the OP. We could chat over beers sometime as to whether I'm a bad person for doing so :-)
Every PR that adds a feature adds future support and maintenance effort. If you and your buddy are unwilling to spend the time to get it right, why are you expecting the maintainer to spend the time to support it?
The maintainer shortly thereafter attempted to do it himself his way, ended up with a bug-ridden and memory-leaking implementation that barely worked, and sits languishing in a lonely branch.
Don't make assumptions about the code you didn't see and the attitudes involved coders might have. We would have been (and still would be) more than happy to help maintain it had the bot turned out useful for us, but because it was a new project and the structure was changing constantly, attempting to fork and integrate upstream changes would have been a nightmare, so we decided to go a different direction.
This happens all the time, and is the nature of open source. No project is obligated to take your contribution, and that happens for a myriad of reasons that you are not obligated to understand.
It's fundamentally a human problem, not a software one. There's nothing wrong with the software here—it does everything required and more to be able to manage the codebase.
Take your fork, explain the situation in the README and let it be. It'll be in the fork graph and the list on Github. People can find it. If they like your feature, maybe they'll use yours instead. If enough people get behind it and ask for it, or say "hey this was in a PR, why wasn't it merged?", the pressure could be enough for the original author to just accept the PR.
In any case, this is not a problem with the pull request feature. It's a simple collaboration problem, and a PR is only one method of communication you can use to solve it. If you give up after throwing a PR into the void (not that I'm saying you did), you shouldn't expect instant success.
Some projects, you'll want to do a weekend of really rough work, contact the maintainer, get their thoughts. Others, you'll want to do 8 days work, get it far enough along to show, get their thoughts.
Often though, before you write a line of code, talk to them.
But I had to say no because it didn't fit well within the overall project, and didn't really add any value but a lot of complexity. I felt very bad to turn him down but otherwise I'd be now responsible for code I have no interest in and code I don't feel helps users.
The right way is to talk to the maintainer and agree on what to do first. Or be prepared to run a fork.