I don't find Github pull requests an easy way to submit patches

May 28, 2015

(This is a grumble. You've been warned.)

A lot of open source projects are hosted on Github these days and many of them prefer to get patch submissions in the form of Github pull requests. On the one hand I admire Github for making the process of pull requests relatively painless for the maintainer(s) in my brief experience. On the other hand, I don't find pull requests to be very attractive from the other side, as a (potential) submitter of changes, and I suspect that a lot of other potential change submitters are going to feel the same way.

In the moderately old days, submitting changes was really easy. You started with a current, checked out copy of the project's source repo and you carried your relevant changes on top of it as uncommitted changes (in a CVS or SVN based project you didn't have any choice about that and in general it was usually the easiest approach). When you wanted to submit your change, you ran '<whatever> diff' to get a unified diff relative to the latest master, dumped the output in a file, and emailed the result off to the project with an explanatory note. If you were running your modifications yourself, you could do this from your live working repo.

Creating a Github pull request is not so simple in practice. As far as I can tell, the workflow I'd want to use is something like the following:

  • fork a copy of the project into my own Github account.
  • 'git clone' that copy to a scratch repo locally. Create a new branch in the repo and switch to it.
  • 'git diff' my working repo with the uncommitted change then use patch to apply the diff to the scratch repo.
  • 'git commit' my change in the scratch repo (on my branch) and push it to my Github fork.
  • go to Github and submit a pull request from my Github fork to the master.
  • after the pull request is merged, delete my Github fork and my local scratch repo.

If I was being thorough, I should actually build the project out of this scratch repo and maybe do a test install (even though I've already built and installed from my working repo).

I have no idea what I'd do to keep clean commits if the master repo moves forward between my pull submission and when it gets merged. Maybe Github manages this transparently; maybe I need to update my scratch repo, 'git rebase' to get a new clean commit (maybe on a new branch), and push it back to Github to make a new pull request. It's a fun new frontier of extra work.

(None of this is difficult with the 'email a patch' approach. You 'git pull' to update your working repo, maybe fiddle with your change, then send another email with a newly generated 'git diff' if you think you need to or get asked for it.)

Note that there are some simplifications to this that could be done if I contributed a lot to specific projects, which is what I suspect Github pull requests are good for. But I rather feel that they're not so good for essentially one-off contributions from people, which is the category I'm most likely to fall into. So I'd sure like it if Github based projects still made it easy to send them patches by email (and mentioned this in any 'how to contribute' documentation they have). Unfortunately patches by email don't integrate very well with Github issues (of course), while Github pull requests work great there. I'm sure that this is a not insignificant factor pushing projects towards pull requests.


Comments on this page:

By steve at sk2 dot org at 2015-05-28 03:35:49:

You can make things a little easier on Github by using multiple remotes: keep your work repo, clone the upstream project on Github and add your new scratch repo as a new remote on your work repo. That way you can just push to the new remote instead of manually applying patches.

By Dominic at 2015-05-28 03:36:21:

If your "working repo" is a clone of the upstream project, then you'd just add your fork as a new remote in the git checkout instead of creating a new one and having the question of whether to rebuild it. For example: `git remote add github https://github.com/youruser/reponame.git` and `git push github yourbranch`.

Also, `git format-patch` is preferred for patches by e-mail, especially for generating patch series. The latter generates files by commits, so you would need to commit things, but commit messages can then be added and proper attribution given. If the project does use GitHub issues, you could use "Closes #123" in the commit message so when it is committed, it'll be closed.

GitHub don't help at all with keeping your fork up to date, but it generally doesn't matter when working with two remotes (one for upstream, one for your fork). You'd "git pull upstream master" to update your local repo's master branch from upstream, base your branch on that and push it to your fork. (It doesn't matter that "master" on your fork is outdated.)

If you're submitting a pull request based on an old branch, it doesn't matter if it's mergeable. If git can merge it, it will work. If not, then you'd be asked to git pull, git rebase master, git push -f github (updating the existing branch and PR).

Most of this general git workflow. GitHub itself has focused on adding in-browser file editing functionality for quick patches, so when you press "Edit" on a file it automatically forks and sets up pull requests etc.

Yup, just adding another remote is the standard way to do this.

And if you don’t have push access to your current origin, there is an even more convenient way: set your GitHub fork as the push URL for your existing origin remote.

git remote origin set-url --push git@github.com:siebenmann/whatever.git

Now suddenly you can git push to origin because pushes will go to your forked GitHub repo instead of whichever repo you originally cloned, even though fetches from origin continue to come from the upstream repo.

This can be a little confusing in that some origin remote branches will now refer to stuff in the original origin (e.g. origin/master probably) and some to stuff in your own GitHub fork (origin/mytopic). The simple way to keep them straight is just make sure to pick a unique topic branch name, maybe by prefixing your branches à la cks/mytopic to cordon them off a little.

Whether you want to do this will depend on how comfortable you are with the concepts of remotes and remote branches. If you don’t have any trouble keeping the constellation straight in your head, it can be less overhead to set things up this way, particularly if you plan to send multiple pull requests: as far as futzing around in the local repo is concerned, you can pretend that your fork on GitHub doesn’t even exist. It only ever matters when you’re preparing a PR for submission.

There's also a 'hub' tool that you can use to more easily manage forks & pull requests from the command line. As suggested, I've aliased 'git' to 'hub' in my environment; hub adds more stuff to the git command and passes anything it doesn't specifically know how to do back to git itself.

I think the PR flow is a big nuisance for occasional contributors, especially having to fork on the GitHub site first (and you can only have one fork, so if you already forked the project for an entirely different purpose, you must clutter the repository with some off-topic branch...).

By Pete at 2015-05-28 19:30:15:

All of it is just as bad as everyone else is describing. Strangely, the way I abhor branches comes handy here for once. I just clone the real upstream and my fork and then add a couple of remotes (pointing to local dirs) here and there, then do "git fetch" "git cherry-pick".

Making every contributor to open a Github account is still bs, regardless.

By cks at 2015-05-28 20:42:30:

I wasn't clear enough about this in my entry: I can't directly use my normal working repo for this because I maintain all of my changes there in uncommitted form (because this is far easier in practice). Github pull requests can only be made from committed changes, so I need a separate repo where I will commit the changes and then deal with the headaches that ensue from having committed differences from upstream.

Written on 28 May 2015.
« The impact on you of making 'bad' bug reports
I don't commit changes in my working repos »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu May 28 01:51:49 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.