== My workflow for testing Github pull requests Every so often a Github-based project I'm following has a pending pull request that might solve a bug or otherwise deal with something I care about, and it needs some testing by people like me. The simple case is when I am not carrying any local changes; it is adequately covered by part of Github's [[Checking out pull requests locally https://help.github.com/articles/checking-out-pull-requests-locally/]] (skip to the bit where they talk about '_git fetch_'). A more elaborate version is: .pn prewrap on > git fetch origin pull//head:origin/pr/ > git checkout pr/ That creates a proper remote branch and then a local branch that tracks it, so I can add any local changes to the PR that I turn out to need and then keep track of them relative to the upstream pull request. If the upstream PR is rebased, well, I assume I get to delete my remote and then re-fetch it and probably do other magic. I'll cross that bridge when I reach it. The not so simple case is when I am carrying local changes on top of the upstream master. In the fully elaborate case I actually have two repos, the first being a pure upstream tracker and the second being a 'build' repo that pulls from the first repo and carries my local changes. I need to apply some of my local changes on top of the pull request while skipping others (in this case, because some of them are workarounds for the problem the pull request is supposed to solve), and I want to do all of this work on a branch so that I can cleanly revert back to 'all of my changes on top of the real upstream master'. The workflow I've cobbled together for this is: * Add the Github master repo if I haven't already done so: ((git remote add github https://github.com/zfsonlinux/zfs.git)) * Edit _.git/config_ to add a new '_fetch =_' line so that we can also fetch pull requests from the _github_ remote, where they will get mapped to the remote branches _github/pr/NNN_. This will look like: (([remote "github"])) \\ {{C:nbsp}}{{C:nbsp}}{{C:nbsp}}((fetch = +refs/pull/*/head:refs/remotes/github/pr/*)) \\ {{C:nbsp}}{{C:nbsp}}{{C:nbsp}}(([...])) (This comes from [[here https://gist.github.com/piscisaureus/3342247]].) * Pull down all of the pull requests with '_git fetch github_'. I think an alternate to configuring and fetching all pull requests is the limited version I did in the simple case (changing _origin_ to _github_ in *both* occurrences), but I haven't tested this. At the point that I have to do this complicated dance I'm in a 'swatting things with a hammer' mode, so pulling down all PRs seems perfectly fine. I may regret this later. * Create a branch from _master_ that will be where I build and test the pull request (plus my local changes): ((git checkout -b pr-NNN)) It's vitally important that this branch start from _master_ and thus already contain my local changes. * Do an interactive rebase relative to the upstream pull request: ((git rebase -i github/pr/NNN)) This incorporates the pull request's changes 'below' my local changes to master, and with _-i_ I can drop conflicting or unneeded local changes. Effectively it is much like what happens when you do a regular '_git pull --rebase_' on _master_; the changes in _github/pr/NNN_ are being treated as upstream changes and we're rebasing my local changes on top of them. * Set the upstream of the pr-NNN branch to the actual Github pull request branch: ((git branch -u github/pr/NNN)) This makes '_git status_' report things like 'Your branch is ahead of ... by X commits', where X is the number of local commits I've added. If the pull request is refreshed, my current guess is that I will have to fully discard my local _pr-NNN_ branch and restart from fetching the new PR and branching off _master_. I'll undoubtedly find out at some point. Initially I thought I should be able to use a sufficiently clever invocation of '_git rebase_' to copy some of my local commits from _master_ on to a new branch that was based on the Github pull request. With work I could get the rebasing to work right; however, it always wound up with me on (and changing) the _master_ branch, which is not what I wanted. Based on [[this very helpful page on what '_git rebase_' is really doing https://matthew-brett.github.io/pydagogue/rebase_without_tears.html]], what I want is apparently impossible without explicitly making a new branch first (and that new branch must already include my local changes so they're what gets rebased, which is why we have to branch from _master_). This is probably not the optimal way to do this, but having hacked my way through [[today's git adventure game https://twitter.com/thatcks/status/626411869490835456]] I'm going to stop now. Feel free to tell me how to improve this in comments. (This is the kind of thing I write down partly to understand it and partly because I would hate to have to derive it again, and I'm sure I'll need it in the future.) === Sidebar: Why I use two repos in the elaborate case In the complex case I want to both monitor changes in the Github master repo and have strong control over what I incorporate into my builds. My approach is to routinely do '_git pull_' in the pure tracking repo and read '_git log_' for new changes. When it's time to actually build, I '_git pull_' ([[with rebasing GitCommitAndRebaseNotes]]) from the tracking repo into the build repo and then proceed. Since I'm pulling from the tracking repo, not the upstream, I know exactly what changes I'm going to get in my build repo and I'll never be surprised by a just-added upstream change. In theory I'm sure I could do this in a single repo with various tricks, but doing it in two repos is much easier for me to keep straight and reliable.