使用 GitHub 拉取请求的正确 git 配置是什么?
What is the correct git config for working with GitHub pull requests?
我知道 How can I check out a GitHub pull request?
虽然将 fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
添加到 .git/config
确实允许提取和检出,但拉取操作失败:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
抓取和签出工作正常:
$ git fetch origin
...都很好
$ 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'
...成功,获取代码!
但是拉取失败:
$ git pull
Your configuration specifies to merge with the ref 'refs/heads/pr/123'
from the remote, but no such ref was fetched.
...失败。
我可以手动指定 ref:
$ git pull origin refs/pull/123/head
这行得通。但是我如何配置配置文件以便:
- 获取和结帐仍然有效,并且
- 后续拉取操作无需手动指定远程引用即可工作?
我发现如果我编辑配置文件并更改:
[branch "pr-123"]
remote = origin
merge = refs/heads/pr/123
至:
[branch "pr-123"]
remote = origin
merge = refs/pull/123/head # <-- here is the change
... 然后 git pull
工作正常。如果不为每个拉取请求手动编辑配置文件,如何实现这一目标?
一个正确的方法是 hub! :)
$ brew install hub
$ hub checkout https://github.com/github/hub/pull/123
...
$ hub pull
Already up-to-date.
它有额外的实用程序来处理 Github 拉取请求,例如
hub pull-request
您只获取了分支,而不是拉取请求。将此添加到您的配置中:
fetch = +refs/pull/*/head:refs/pulls/origin/pr/*
之后您可以检出指向 PR 远程引用的分支:
git checkout -b "pr-123" pulls/origin/pr/123
通常,如果您从远程获取了引用,则可以检出它,因此查看 git fetch
命令输出并找到 PR 的引用名称。这就是您应该在 checkout
命令中输入的内容。您应该会看到类似以下内容:
[new ref] refs/pull/123/head -> refs/pulls/origin/pr/123
请注意,您可以用 pulls
部分替换任何自定义前缀。您现在可以创建一个分支并将其指向 pulls/origin/pr/123
,这相当于 refs/pulls/origin/pr/123
(请参阅 git refspec doc)。
从获取规范中无法明确地找到远程引用 refs/remotes/origin/pr/123
跟踪 origin:refs/pull/123/head
因为 origin:refs/heads/pr/123
也是可能的。为了帮助它,您可以使用不同的远程名称,例如:
[remote "origin-pr"]
url = <same as for origin>
fetch = +refs/pull/*/head:refs/remotes/origin-pr/pr/*
然后 git 使用明确的分支名称(应该在 GUI 中可用)结帐将能够创建正确的跟踪参考:
$ git checkout -b pr/123 origin-pr/pr/123
[branch "pr/123"]
remote = origin-pr
merge = refs/pull/123/head
不过,看起来不可能使简单的 git checkout br/123
工作:
$ git checkout pr/123
error: pathspec 'pr/123' did not match any file(s) known to git.
我想我找到了一个解决方案,而且非常简单:fetch = +refs...
的行顺序很重要!
我改了:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
至:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
fetch = +refs/heads/*:refs/remotes/origin/*
(最后两行交换)
现在一切正常(fetch
、checkout
、pull
)。
我仍在等待看到此配置的一些(意想不到的)问题,但到目前为止一切顺利...
我知道 How can I check out a GitHub pull request?
虽然将 fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
添加到 .git/config
确实允许提取和检出,但拉取操作失败:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
抓取和签出工作正常:
$ git fetch origin
...都很好
$ 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'
...成功,获取代码!
但是拉取失败:
$ git pull
Your configuration specifies to merge with the ref 'refs/heads/pr/123'
from the remote, but no such ref was fetched.
...失败。
我可以手动指定 ref:
$ git pull origin refs/pull/123/head
这行得通。但是我如何配置配置文件以便:
- 获取和结帐仍然有效,并且
- 后续拉取操作无需手动指定远程引用即可工作?
我发现如果我编辑配置文件并更改:
[branch "pr-123"]
remote = origin
merge = refs/heads/pr/123
至:
[branch "pr-123"]
remote = origin
merge = refs/pull/123/head # <-- here is the change
... 然后 git pull
工作正常。如果不为每个拉取请求手动编辑配置文件,如何实现这一目标?
一个正确的方法是 hub! :)
$ brew install hub
$ hub checkout https://github.com/github/hub/pull/123
...
$ hub pull
Already up-to-date.
它有额外的实用程序来处理 Github 拉取请求,例如
hub pull-request
您只获取了分支,而不是拉取请求。将此添加到您的配置中:
fetch = +refs/pull/*/head:refs/pulls/origin/pr/*
之后您可以检出指向 PR 远程引用的分支:
git checkout -b "pr-123" pulls/origin/pr/123
通常,如果您从远程获取了引用,则可以检出它,因此查看 git fetch
命令输出并找到 PR 的引用名称。这就是您应该在 checkout
命令中输入的内容。您应该会看到类似以下内容:
[new ref] refs/pull/123/head -> refs/pulls/origin/pr/123
请注意,您可以用 pulls
部分替换任何自定义前缀。您现在可以创建一个分支并将其指向 pulls/origin/pr/123
,这相当于 refs/pulls/origin/pr/123
(请参阅 git refspec doc)。
从获取规范中无法明确地找到远程引用 refs/remotes/origin/pr/123
跟踪 origin:refs/pull/123/head
因为 origin:refs/heads/pr/123
也是可能的。为了帮助它,您可以使用不同的远程名称,例如:
[remote "origin-pr"]
url = <same as for origin>
fetch = +refs/pull/*/head:refs/remotes/origin-pr/pr/*
然后 git 使用明确的分支名称(应该在 GUI 中可用)结帐将能够创建正确的跟踪参考:
$ git checkout -b pr/123 origin-pr/pr/123
[branch "pr/123"]
remote = origin-pr
merge = refs/pull/123/head
不过,看起来不可能使简单的 git checkout br/123
工作:
$ git checkout pr/123
error: pathspec 'pr/123' did not match any file(s) known to git.
我想我找到了一个解决方案,而且非常简单:fetch = +refs...
的行顺序很重要!
我改了:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
至:
[remote "origin"]
url = https://github.com/the/repo.git
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
fetch = +refs/heads/*:refs/remotes/origin/*
(最后两行交换)
现在一切正常(fetch
、checkout
、pull
)。
我仍在等待看到此配置的一些(意想不到的)问题,但到目前为止一切顺利...