问题
I'm aware of How can I check out a GitHub pull request?
While adding fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
to .git/config
does allow fetch and checkout, pull actions fail:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
Fetch and checkout work fine:
$ git fetch origin
... all good
$ git checkout -b "pr-123" origin/pr/123
Branch pr-123 set up to track remote branch pr/123 from origin.
Switched to a new branch 'pr-123'
... success, got the code!
But pull fails:
$ git pull
Your configuration specifies to merge with the ref 'refs/heads/pr/123'
from the remote, but no such ref was fetched.
... failed.
I can specify the ref manually:
$ git pull origin refs/pull/123/head
and this works. But how can I configure the config file so that:
- fetch & checkout still work, and
- subsequent pull actions work without manually specifying the remote ref?
I have found that if I edit the config file and change:
[branch "pr-123"]
remote = origin
merge = refs/heads/pr/123
to:
[branch "pr-123"]
remote = origin
merge = refs/pull/123/head # <-- here is the change
... then git pull
works fine. How can this be achieved without manually editing the config file for every pull request?
回答1:
You've only fetched branches, not pull requests. Add this to your config:
fetch = +refs/pull/*/head:refs/pulls/origin/pr/*
After that you can checkout a branch that points to a PR remote ref:
git checkout -b "pr-123" pulls/origin/pr/123
Generally, you can check out a ref if you've fetched it from the remote, so look through the git fetch
command output and find the PR's ref name. That's what you should put in the checkout
command. You should see something like:
[new ref] refs/pull/123/head -> refs/pulls/origin/pr/123
Note that you can substitute the pulls
part for any custom prefix. You can now create a branch and point it to pulls/origin/pr/123
, which is equivalent to refs/pulls/origin/pr/123
(see git refspec doc).
回答2:
From the fetch specs is not possible to find unambiguously find that remote reference refs/remotes/origin/pr/123
tracks origin:refs/pull/123/head
because origin:refs/heads/pr/123
is also possible. To help it, you could use different remote name for example:
[remote "origin-pr"]
url = <same as for origin>
fetch = +refs/pull/*/head:refs/remotes/origin-pr/pr/*
Then git checkout with explicit branch name (which should be available in GUIs) would be able to create correct tracking reference:
$ git checkout -b pr/123 origin-pr/pr/123
[branch "pr/123"]
remote = origin-pr
merge = refs/pull/123/head
Though, looks like it is not possible to make simple git checkout br/123
work:
$ git checkout pr/123
error: pathspec 'pr/123' did not match any file(s) known to git.
回答3:
One correct way is with hub! :)
$ brew install hub
$ hub checkout https://github.com/github/hub/pull/123
...
$ hub pull
Already up-to-date.
It has extra utilities for working with Github pull requests, such as
hub pull-request
回答4:
I think I found a solution, and it's unbelievably simple: Order of the lines with fetch = +refs...
matters!
I changed:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
to:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
fetch = +refs/heads/*:refs/remotes/origin/*
(last two lines swapped)
Now everything works (fetch
, checkout
, pull
).
I'm still waiting to see some (un)expected problems with this configuration, but so far so good...
来源:https://stackoverflow.com/questions/40662771/what-is-the-correct-git-config-for-working-with-github-pull-requests