如何将来自其他分支的未合并上游拉取请求应用到我的分支中?
Posted
技术标签:
【中文标题】如何将来自其他分支的未合并上游拉取请求应用到我的分支中?【英文标题】:How to apply unmerged upstream pull requests from other forks into my fork? 【发布时间】:2011-08-26 17:02:28 【问题描述】:我有一个 fork 的 GitHub 上的项目有一个新的拉取请求,我想拉入我的 fork 中,但作者尚未拉入。
有没有一种简单的方法可以将来自其他分叉的拉取请求应用到我的分叉中?这里还有什么我想念的吗?
【问题讨论】:
有一条指令:gist.github.com/piscisaureus/3342247 如果你使用 git 命令来做,这是否反映在 GitHub 的网络图上? 找到所有分支也可能很有趣:***.com/q/47798937/10245 【参考方案1】:您可以很容易地手动完成:
将另一个 fork 添加为你的 repo 的远程:
git remote add otherfork git://github.com/request-author/project.git
获取他的 repo 的提交
git fetch otherfork
然后您有两个选项来应用拉取请求(如果您不想选择选择 1。)
如果您不关心应用在源和拉取请求之间添加的最终提交,您可以重新设置拉取请求所基于的分支
git rebase master otherfork/pullrequest-branch
如果您只想要拉取请求中的提交,请确定它们的 SHA1 并执行
git cherry-pick <first-SHA1> <second-SHA1> <etc.>
【讨论】:
实际上,您不应该使用cherry-pick,它会创建新的提交......如果您向上游发送拉取请求,这反过来会导致混乱。相反,您应该像拉取请求所要求的那样合并。您也不需要添加遥控器。git pull URL branchname
@Tekkub:同意,最好避免与新创建的提交混淆。在我看来,合并不太优雅,因为您可以从要合并的分支中带来其他更改
是的,但在这种情况下,他特别询问如何将拉取请求拉入他的分叉中。拉 == 合并。
@CharlesB,由于 GitHub 会自动将同一分支上的新提交添加到拉取请求中,因此不会很难获得任何“其他更改”(假设请求者遵循最佳实践并进行更改在与持续开发不同的分支上,以便所有提交都是相关的),除非你得到的是当你只想要一个拉取请求的 part 时?
对于那些与我有同样心理问题的人,“otherfork”不是引用原始存储库,而是引用从 发出对原始存储库的拉取请求的分支的提交。忽略原始 repo 并直接转到发出拉取请求的 fork。您想手动拉取拉取引用的提交并将其与您自己的合并。【参考方案2】:
我会做以下事情;
git checkout master
git remote add #NAME# #ADDRESS TO REPO#
git fetch #USERNAME#
git checkout -b test_fork
git rebase #NAME#/#BRANCH#
我现在已将更改合并到一个名为 test_fork
的测试分支中。这样任何更改都不会弄脏我的树。
如果更可取,您可以选择使用上述的 cherry-pick 来选择特定的提交。
旅途愉快:)
【讨论】:
【参考方案3】:就像 Tekkub 之前说的,你可以直接把分支拉进去。大多数情况下,在 GitHub 中,分支只是请求用户的项目分支上的“主”。
例如:git pull https://github.com/USER/PROJECT/ BRANCH
作为一个实际的例子:
假设您分叉了一个名为 safaribooks 的 github 项目,并且在原始项目中有以下拉取请求,您希望将其放入您的分叉中:
然后,在你 fork 的克隆项目文件夹中,运行:
git pull https://github.com/fermionic/safaribooks.git fix-str-decode
【讨论】:
这样的缺点是分支中除了拉取请求之外可能还有其他东西。此外,您必须查找拉取请求作者的分支的正确 URL。如果你想使用单行,最好改用git pull https://github.com/upstream/project refs/pull/id/head
。
@jbyler 如果分支中有其他内容,我很确定 GitHub 无论如何都会更新拉取请求。【参考方案4】:
一些更详细的信息对我有用。
我的 .git/config 文件用于分叉的 repo 如下所示:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
[remote "origin"]
url = git@github.com:litzinger/angular-carousel.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
rebase = true
[remote "source"]
url = git://github.com/revolunet/angular-carousel.git
fetch = +refs/heads/*:refs/remotes/source/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
然后运行“git fetch source”,然后列出来自分叉仓库的所有拉取请求。
* [new ref] refs/pull/54/head -> origin/pr/54
* [new ref] refs/pull/67/head -> origin/pr/67
* [new ref] refs/pull/69/head -> origin/pr/69
* [new ref] refs/pull/71/head -> origin/pr/71
然后在特定的拉取请求中合并运行“git merge master origin/pr/67”
【讨论】:
我编辑了我的 .git/config 并添加了 [remote "source"] 行,但对于我感兴趣的项目,说明工作完美无缺。我喜欢这个答案。 可以在news.ycombinator.com/item?id=9051220 和help.github.com/articles/checking-out-pull-requests-locally 中找到优秀的相关建议,提示这个(真棒)GitHub 特定的只读远程refs/pull/
命名空间。
如果您使用 Smartgit,如果您按照 syntevo.com/doc/display/SG/System+Properties 将 smartgit.branch.otherRefs=notes;pull
添加到 smartgit.properties,您可以在日志图中看到这些拉取请求(以及关闭的请求) - 您也可以将它们从在那里。
顺便说一句,您也可以在命令行上尝试使用 git fetch source +refs/heads/*:refs/remotes/upstream/* +refs/pull/*/head:refs/remotes/原产地/pr/*【参考方案5】:
项目的拉取请求可能来自许多不同的作者(分支),您可能不希望每个分支都有单独的遥控器。此外,您不想对作者在提交拉取请求时使用的分支或作者的主分支中可能存在的其他内容做出任何假设。因此,最好在上游存储库中引用拉取请求,而不是在其他分支中出现。
第 1 步:
git remote add upstream <url>
您可能已经完成了这一步,但如果没有,您需要为上游项目定义一个远程。该 URL 是您分叉的项目的克隆 URL。更多信息请访问 Configuring a remote for a fork 和 Syncing a fork。 upstream
是您为遥控器指定的名称,虽然它可以是任何名称,但 upstream
是常规名称。
第 2 步:
git pull upstream refs/pull/id/head
... 其中id
是拉取请求编号。 upstream
是要从中提取的遥控器的名称,即如果您完全按照步骤 1 操作,则只是“上游”。它也可以是 URL,在这种情况下您可以跳过第 1 步。
第 3 步:
输入合并提交的提交消息。您可以保留默认值,但我建议提供一个漂亮的单行摘要,其中包含拉取请求编号、它修复的问题和简短描述:
Merge PR#42, fixing VIM-652, support for mapping arbitrary IDEA actions
【讨论】:
另见related answer 的变体,它创建了一个包含拉取请求的本地分支。最后一个变体:您可以使用git pull upstream refs/pull/id/head
将提交提交到您的本地仓库中,然后将它们引用为FETCH_HEAD
(例如git log ..FETCH_HEAD
以查看其中的内容,然后git merge FETCH_HEAD
)
我将如何进行变基,所以拉取请求是最重要的,我可以避免合并气泡?
这是我需要的解决方案,因为拉取请求作者已经删除了他的 repo。
是的,这也适用于从不再公开的存储库中合并开放 PR。【参考方案6】:
更新:通过网页
您也可以通过 github 网页执行此操作。
我假设,您应该已经有一个公共 repo (BaseRepo
) 的 fork (MyFork
),其中包含来自您感兴趣的 fork (OtherFork
) 的待处理拉取请求。
-
导航到已发起拉取请求的分叉 (
OtherFork
),您希望将其放入分叉 (MyFork
)
转到OtherFork
的拉取请求页面
点击新的拉取请求
应提供待处理的拉取请求。记住也要选择正确的OtherFork
分支。在左侧选择您的叉子作为基础叉子 (MyFork
)(重要提示)。
现在View pull request
的选项应更改为Create pull request
。点击这里。
现在您的 fork (MyFork
) 中应该有一个待处理的拉取请求,您可以简单地接受它。
【讨论】:
效果很好。比 cmd 行简单得多,并且易于查看更改。谢谢。 我无法找到如何访问 UI 上的“OtherFork”。要轻松到达那里,只需使用 github 用户名修改 url。即github.com/userName/repoName 我看不到第 4 步中提到的待处理拉取请求。相反,我从右侧的“比较”下拉列表中选择了与OtherFork
提出的拉取请求对应的分支。然后,如上所述,我选择左侧作为基础分叉,以便能够创建拉取请求。
工作,除非没有分叉。例如:github.com/OculusVR/RakNet/pull/61/files
来自 githubs 网站的确切文字可能已经过时,但过程是正确的。超级简单 - 谢谢!【参考方案7】:
我为此使用了一个方便的花花公子脚本。我通过键入以下内容运行脚本:
git prfetch upstream
它会从上游分支获取所有拉取请求。
要创建脚本,请创建一个文件~/bin/git-prfetch
。
该文件应包含以下内容:
#!/bin/bash
if [ -z "$1" ]; then
echo "Please supply the name of a remote to get pull requests from."
exit 1
fi
git fetch $1 +refs/heads/\*:refs/remotes/$1/\* +refs/pull/\*/head:refs/remotes/$1/pr/\*
通过设置确保您的路径包含脚本:
export PATH="$HOME/bin:$PATH"
您可以将此文件添加到 ~/.bashrc
以使更改永久生效。
现在,请确保添加要从中获取拉取请求的分叉:
git remote add upstream https://github.com/user/repo.git
然后
git prfetch upstream
【讨论】:
以上是关于如何将来自其他分支的未合并上游拉取请求应用到我的分支中?的主要内容,如果未能解决你的问题,请参考以下文章
在发出拉取请求之前,是不是有任何理由将功能分支合并到分叉主控中?