如何从他人的仓库中拉取远程分支

397

我有一个托管在GitHub上的项目,有人对它进行了fork。在他们的fork上,他们创建了一个名为“foo”的新分支并进行了更改。 我应该如何将他们的“foo”拉取到我的存储库中同样命名为“foo”的新分支中呢?

我知道他们可以向我提交pull request,但我想自己启动此过程。

假设以下情况:

  1. 因为他们fork了我的项目,我们两个repo共享相同的“历史记录”
  2. 尽管GitHub显示他们的项目是从我的项目fork来的,但我的本地存储库没有任何关于这个人的项目的引用。我需要将他们的项目添加为远程吗?
  3. 我还没有一个名为“foo”的分支 - 我不知道是否需要先手动创建这个分支。
  4. 我肯定希望将此拉入一个单独的分支而不是我的主分支。
7个回答

542
git remote add coworker git://path/to/coworkers/repo.git
git fetch coworker
git checkout --track coworker/foo

这将设置一个本地分支 foo,以跟踪远程分支 coworker/foo。因此当你的同事做出了一些更改时,你可以轻松地拉取它们:

git checkout foo
git pull

评论回复:

太好了 :) 如果我想对该分支进行自己的更改,我应该从 "foo" 创建第二个本地分支 "bar" 并在那里工作,而不是直接在我的 "foo" 上工作吗?

你不需要创建一个新分支,尽管我推荐这样做。你也可以直接提交到foo并让你的同事拉取你的分支。但是,该分支已经存在,你的分支foo需要设置为它的上游分支:

git branch --set-upstream foo colin/foo

假设 colin 是你的存储库(同事存储库的远程引用),并以类似的方式定义:

git remote add colin git://path/to/colins/repo.git

4
非常快速 :) 您可能希望补充说明他应该在//path/to/coworkers/repo.git的位置使用另一个人GitHub仓库页面中的git://URL。(描述这一点让我的答案变慢了 ;)) - Mark Longair
很酷 :) 如果我想对那个分支进行自己的更改,我应该从“foo”创建第二个本地分支“bar”,并在那里工作,而不是直接在我的“foo”上工作吗? - Colin O'Dell
还是直接在我的“foo”中工作,稍后再拉取/合并他的更改,这样安全吗?哪种做法是最佳实践? - Colin O'Dell
2
3分钟内给出的好答案! - Tieme
使用 Git 版本 2.19.1.windows.1,我需要将 git checkout --track coworker/foo 替换为 git checkout foo - Micheal Wells

196

所接受的答案是有效的,但是你不需要将它们添加为远程,因为每次这样做都很麻烦并且很痛苦。

获取他们的提交:

git fetch git://path/to/coworkers/repo.git theirbranch:ournameforbranch

这将创建一个名为ournameforbranch的本地分支,该分支与他们的theirbranch完全相同。 对于示例中的问题,最后的参数将是foo: foo

git://path/to/coworkers/repo.git部分应替换为其GitHub存储库页面上的URL。 SSH URL看起来像git@github.com:theirusername/reponame.git,HTTPS URL看起来像https://github.com/theirusername/reponame.git

请注意,如果想出一个名称,不与您自己的分支之一发生冲突,可以进一步省略:ournameforbranch部分。在这种情况下,可以使用称为FETCH_HEAD的引用。您可以git log FETCH_HEAD查看他们的提交,然后执行cherry-pick等操作以挑选他们的提交。

将更改推回给他们:

通常,您希望修复他们的某些内容并立即将其推回。 这也是可能的:

git fetch git://path/to/coworkers/repo.git theirbranch
git checkout FETCH_HEAD

# fix fix fix

git push git://path/to/coworkers/repo.git HEAD:theirbranch

如果在游离状态下工作让您担忧,那么请务必使用:ournameforbranch创建一个分支,并将上面的FETCH_HEADHEAD替换为ournameforbranch


3
谢谢您的询问,如果您和另一个人都有同名的分支(比如默认的“master”分支),那么另一种答案是不起作用的。 - Job
3
值得一提的是,如果您的GitHub帐户没有与SSH密钥等相关联的内容,则此方法将无法正常工作,请参见https://dev59.com/UGcs5IYBdhLWcg3wVyel。 - Przemek D
1
难道你不需要成为协作者才能推送到他们的仓库吗? - mfaani
1
@Honey 当然可以!推送假定您在远程端具有必要的权限来进行推送。获取同样假定路径是可访问的。 - antak
1
@hippietrail,我看到了我的答案哪里出错了。我已经更新了答案以澄清URL部分。我之前的措辞指导您使用SSH URL,但HTTPS也可以代替它。您还可以参考此答案进一步了解两种身份验证方式。 - antak
显示剩余5条评论

32
以下是与GitHub一起使用的不错的应急解决方案,可以从另一个用户的分叉中检出PR分支。您需要知道pull request ID(GitHub将其与PR标题一起显示)。
示例: Pull request #8
alice 想要将1个提交合并到 your_repo:masterher_repo:branch
git checkout -b <branch>
git pull origin pull/8/head
  • <branch>替换为从her_repo:branch中的分支名称。
  • 如果您使用不同于origin的远程名称,请进行替换。
  • 8替换为正确的拉取请求ID。

5
这需要更多的赞。它完美地起作用,避免了我在最受欢迎的答案中得到的“fatal: Couldn't find remote ref” 错误。谢谢! - Michael Romrell
2
两行简单的代码。谢谢分享!除此之外,唯一更甜美的事情就是以简单的方式将更新合并回他们的拉取请求中。 - klewis
1
这是最好的答案。 - gented
1
这个答案不清楚。 - thepirat000

22

如果 antak 的回答:

git fetch git@github.com:<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH> 

给你:

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

然后(根据Przemek D的建议)使用

git fetch https://github.com/<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH>

7
更新:这个方法似乎已经不再适用,因为Github更改了他们的用户界面,希望他们会恢复它。
GitHub有一个新选项与之前的答案相关,只需从PR中复制/粘贴命令行:
  1. 滚动到PR底部,查看MergeSquash and merge按钮
  2. 点击右侧的链接:view command line instructions
  3. 按下步骤1右侧的复制图标
  4. 将命令粘贴到您的终端中

6

如果被 fork 的仓库受到保护,你无法直接将更改推送到其中,而你的目标是对其 foo 进行修改,则需要通过以下方式将其 foo 分支获取到你的仓库中:

git remote add protected_repo https://github.com/theirusername/their_repo.git
git fetch protected_repo 
git checkout --no-track protected_repo/foo

现在你有了一个本地的foo副本,没有与之关联的上游。你可以提交更改(或不提交),然后将你的foo推送到自己的远程仓库。

git push --set-upstream origin foo

现在foo已经在你的GitHub仓库中,你本地的foo正在跟踪它。如果他们继续对foo进行更改,你可以获取他们的更改并合并到你的foo中。
git checkout foo 
git fetch protected_repo
git merge protected_repo/foo

-1

git fetch upstream pull/<pr_number>/head:<your_local_branch_name>

将上游的拉取请求(PR)编号为<pr_number>的分支拉取到本地分支<your_local_branch_name>中。


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