适用于与GitHub拉取请求合作的正确git配置是什么?

20

我知道如何检查 GitHub 上的 pull request,具体操作请参考此链接

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*添加到.git/config可以实现 fetch 和 checkout,但是 pull 操作会失败:

[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.

...失败了。

我可以手动指定参考文献:

$ git pull origin refs/pull/123/head

这个方法是有效的。但是我该如何配置配置文件,以便:
1. 仍然可以使用fetch和checkout命令 2. 后续的pull操作可以在不手动指定远程引用的情况下正常工作?
我发现如果我编辑配置文件并更改以下内容:

[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就可以正常工作。如何在不手动编辑每个拉取请求的配置文件的情况下实现这一点?


你是在询问如何一次性编辑git配置文件以便对所有拉取请求生效吗?你发布的链接已经给出了答案,这个方法对你不起作用吗? - yelsayed
@yBot 不行。也就是说,pull 没有起作用。我已经在问题中添加了配置文件的部分,也许那里有什么问题? - frnhr
我不确定你是如何检查 origin/pr/123 的,因为PR中不应该有这样的参考(也许你有一个名为这个的远程分支?)。请尝试使用 refs/remote/origin/pr/123。当你执行获取(fetch)操作时,你应该看到被获取的内容。 - yelsayed
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - frnhr
4个回答

9
你只拉取了分支,没有拉取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”,因为它是隐含的。请查看更新后的答案。 - yelsayed
尽管这个回答得到了很多赞,但它并没有解决我的问题。实际上,它根本不起作用。 - frnhr
我非常有兴趣知道为什么它对你不起作用。它在我这里运行良好。如果其他人可以确认,那就太好了。 - yelsayed

4

从提取规范中,无法明确找到远程引用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/*

然后,使用明确的分支名称(在GUI中应该可用)进行git checkout,将能够创建正确的跟踪引用:

$ 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.

这个答案是一个解决方案。我们可以配置两个远程仓库: origin 用于常规分支,origin-pr 用于PR。只要选择正确的远程仓库,它似乎工作得很好。 - frnhr

4

我认为我找到了一个解决方案,而且它非常简单:使用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/*

to:

[remote "origin"]
    url = https://github.com/the/repo.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
    fetch = +refs/heads/*:refs/remotes/origin/*

现在一切正常(fetchcheckoutpull)。

我仍在等待看到这个配置是否会出现一些(不)预期的问题,但目前为止还不错...

(最后两行交换了位置)


如果有人在使用这个解决方案时遇到问题,请留言评论。 - frnhr
1
我曾经遇到过同样的问题 - 即使在 Git 2.33.1 版本中,这个解决方案仍然有效。我很惊讶这个顺序很重要,但它确实很重要。如果没有这个,git checkout pr/1 会在配置文件中创建一个错误的合并条目:merge = refs/heads/pull/1。但是通过这个修复,不知何故相同的命令 git checkout pr/1 会创建 merge = refs/pull/1/head。有了正确的 branch.pr/1.merge 配置条目,一切都能正常工作。 - CrashNeb

1
一种正确的方式是使用hub:)
$ brew install hub
$ hub checkout https://github.com/github/hub/pull/123

...

$ hub pull
Already up-to-date.

它有额外的工具,用于处理Github的pull请求,例如:
hub pull-request

这对作者有什么帮助吗?问题是关于正确的git配置。 - yelsayed
2
无益,因为最终此 git config 是由 GUI(SourceTree)使用的。谢谢信息。 - frnhr
SourceTree中有自定义操作,可以运行任意命令。 - max630
4
对于所有的投票者:真的吗?是的,这并不是我直接想要的答案,但它确实与我的问题相关,不是吗?在稍微不同的情况下,它可能会很有用。而且对于未来的谷歌搜索者,它可能仍然很有用。 - frnhr
1
Andy Ray:这里有我的点赞!我认为这是一个有用的答案!虽然不完全符合OP的要求,但对其他人可能也有用。 - user5483398

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接