题 如何更新GitHub分叉存储库?


我最近分叉了一个项目并应用了几个修复程序。然后我创建了一个拉取请求,然后被接受。

几天后,另一位撰稿人做出了另一项改变。所以我的fork不包含那个改变。

我怎样才能把这个改变变成我的叉子?当我进行进一步的更改时,是否需要删除并重新创建我的分支?或者是否有更新按钮?


2834
2017-08-30 13:53


起源


这也可以从github UI完成。我想给[另一张海报] [1]。 [1]: stackoverflow.com/a/21131381/728141 - Mike Schroll
关于此的另一篇好博文 - 保持GitHub Fork更新 - Arup Rakshit
在Github帮助文章中找到了这个: help.github.com/articles/syncing-a-fork - Pranav
这是重复的吗? stackoverflow.com/questions/3903817/... ? - David Cary
这是一个使用两个github帐户执行此操作的视频演示 youtube.com/watch?v=kpE0gTX4ycE - lifebalance


答案:


在forked存储库的本地克隆中,可以将原始GitHub存储库添加为“远程”。 (“遥控器”就像存储库网址的昵称一样 - origin 例如,是一个。)然后,您可以从该上游存储库中获取所有分支,并重新定义您的工作以继续处理上游版本。在命令方面可能如下所示:

# Add the remote, call it "upstream":

git remote add upstream https://github.com/whoever/whatever.git

# Fetch all the branches of that remote into remote-tracking branches,
# such as upstream/master:

git fetch upstream

# Make sure that you're on your master branch:

git checkout master

# Rewrite your master branch so that any commits of yours that
# aren't already in upstream/master are replayed on top of that
# other branch:

git rebase upstream/master

如果您不想重写主分支的历史记录(例如因为其他人可能克隆了它),那么您应该用最后一个命令替换 git merge upstream/master。但是,为了进一步提供尽可能干净的拉取请求,最好重新设置。


如果你已经将你的分支重新定位到 upstream/master 你可能需要强制推送才能将它推送到GitHub上你自己的分叉存储库。你这样做:

git push -f origin master

你只需要使用 -f 在你重新定位之后的第一次。


3103
2017-08-30 14:01



由于你的fork只存在于github上,并且github没有通过web界面进行合并的工具,所以正确的答案是在本地进行上游合并并将更改推送回fork。 - Tim Keating
这是我在使用github时发现的一个很棒的教程: gun.io/blog/how-to-github-fork-branch-and-pull-request - Tim Keating
快速说明,您可能应该在单独的分支上工作,而不是必须重新设置自己的主分支以确保从干净状态开始。这可以使您的主人保持清洁,以便将来合并,并且它可以阻止您重写历史记录 -f 这会搞砸每个可以克隆你版本的人。 - Mateusz Kowalczyk
我没有使用rebase命令,而是使用了以下内容: git merge --no-ff upstream/master 这样你的提交就不再是最重要的了。 - Steckdoserich
另一个Git失败了。如果这个工具应该支持分布式协作,那么为什么执行基本工作流程如此困难? 400万人和2200人表示该工具失败。 “你可以将原来的GitHub存储库添加为”远程“  - 为什么一个人甚至必须这样做?为什么在分叉期间没有完成?关于这个工具怎么样? - jww


从2014年5月开始,可以直接从GitHub更新分支。这仍然有效2017年9月,  它将导致脏的提交历史。

  1. 在GitHub上打开你的fork。
  2. 点击 请求
  3. 点击 新的拉动请求。默认情况下,GitHub会将原始文件与您的fork进行比较,如果您没有进行任何更改,则不应该进行任何比较。
  4. 点击 切换基地 如果你看到那个链接否则,手动设置 基础叉 下降到你的叉子,然后 头叉 到上游。现在GitHub会将你的分叉与原始分析进行比较,你应该看到所有最新的变化。 enter image description here
  5. 创建拉取请求 并为您的拉取请求指定一个可预测的名称(例如, Update from original)。
  6. 向下滚动到 合并拉取请求,但不要点击任何东西。

现在您有三个选项,但每个选项都会导致一个不太干净的提交历史记录。

  1. 默认情况下会创建一个丑陋的合并提交。
  2. 如果单击下拉列表并选择“Squash and merge”,则所有干预提交将被压缩为一个。这通常是你不想要的。
  3. 如果你点击 重新基础和合并,所有提交将与您“,”原始PR将链接到您的公关,GitHub将显示 This branch is X commits ahead, Y commits behind <original fork>

所以,是的,您可以使用GitHub Web UI保持您的repo更新其上游,但这样做会玷污您的提交历史记录。依照 命令行 相反 - 这很容易。


642
2018-05-25 07:31



这次工作很棒。第二次此过程的工作方式不同:“切换基础”链接未显示。当我点击“Click to create pull request”时,它在SOURCE repo上创建了一个PR。不是我想要的.. - javadba
仍然有效(Marchi 2015),尽管“切换基础”链接已不再存在。您必须更改“基数”下拉菜单,以便指向您的分叉,然后您将收到“比较跨回购”的提示,这将带您到达您想要的位置。 - mluisbrown
2015年4月。作品。谢谢。我确实得到了“切换到基地”。但是,第6步是“创建拉取请求” - >输入注释 - >“创建拉取请求”。最终提前1次提交原件。 - cartland
@cartland(或其他人) - 是的,它说“这个分支提前1次提交......”这有什么值得担心的吗?有可能摆脱那条消息吗? - RenniePet
只需更新或同步按钮就不会更好! - transformer


这是GitHub的官方文档 同步一个分叉

同步一个分叉

安装程序

在进行同步之前,需要添加指向上游存储库的远程数据库。您最初分叉时可能已经这样做了。

提示:同步fork只会更新存储库的本地副本;它不会在GitHub上更新您的存储库。

$ git remote -v
# List the current remotes
origin  https://github.com/user/repo.git (fetch)
origin  https://github.com/user/repo.git (push)

$ git remote add upstream https://github.com/otheruser/repo.git
# Set a new remote

$ git remote -v
# Verify new remote
origin    https://github.com/user/repo.git (fetch)
origin    https://github.com/user/repo.git (push)
upstream  https://github.com/otheruser/repo.git (fetch)
upstream  https://github.com/otheruser/repo.git (push)

同步

将存储库与上游同步需要两个步骤:首先必须从远程获取,然后必须将所需的分支合并到本地分支中。

从远程存储库中获取将引入其分支及其各自的提交。它们存储在特殊分支下的本地存储库中。

$ git fetch upstream
# Grab the upstream remote's branches
remote: Counting objects: 75, done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 62 (delta 27), reused 44 (delta 9)
Unpacking objects: 100% (62/62), done.
From https://github.com/otheruser/repo
 * [new branch]      master     -> upstream/master

我们现在将上游的主分支存储在本地分支上游/主服务器中

$ git branch -va
# List all local and remote-tracking branches
* master                  a422352 My local commit
  remotes/origin/HEAD     -> origin/master
  remotes/origin/master   a422352 My local commit
  remotes/upstream/master 5fdff0f Some upstream commit

合并

现在我们已经获取了上游存储库,我们希望将其更改合并到我们的本地分支中。这将使该分支与上游同步,而不会丢失我们的本地更改。

$ git checkout master
# Check out our local master branch
Switched to branch 'master'

$ git merge upstream/master
# Merge upstream's master into our own
Updating a422352..5fdff0f
Fast-forward
 README                    |    9 -------
 README.md                 |    7 ++++++
 2 files changed, 7 insertions(+), 9 deletions(-)
 delete mode 100644 README
 create mode 100644 README.md

如果您的本地分支没有任何唯一的提交,git将改为执行“快进”:

$ git merge upstream/master
Updating 34e91da..16c56ad
Fast-forward
 README.md                 |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

提示:如果要在GitHub上更新存储库,请按照说明进行操作 这里


365
2017-10-21 23:04



这会更新我的本地分支,但我在Github.com上的分支仍然说“43后面提交”。我不得不使用lobzik的技术为自己创建一个pull请求,将主更改合并到我的Github.com fork中。 - Michael McGinnis
@MichaelMcGinnis在本地合并之后,你必须将你的更改推送到github。 git push origin master - jumpnett
可能很聪明推动 --follow-tags: stackoverflow.com/a/26438076/667847 - kenny
我必须分别为所有分支机构做这件事 git merge upstream/master,然后检查开发分支和做 git merge upstream/develop - Shobi P P
stackoverflow.com/a/14074925/470749 对我很有帮助,因为我得到了 Permission denied (publickey). fatal: Could not read from remote repository. 当试图从Facebook的Github帐户上游获取时。 - Ryan


很多答案最终会移动你的叉子 一提前 父存储库。这个答案总结了找到的步骤 这里 会的 将fork移动到与父级相同的提交

  1. 将目录更改为本地存储库。

    • 如果不是,请切换到主分支 git checkout master
  2. 将父级添加为远程存储库, git remote add upstream <repo-location>

  3. 问题 git fetch upstream
  4. 问题 git rebase upstream/master

    • 在此阶段,您将检查是否通过键入提交将要合并的内容 git status
  5. 问题 git push origin master

有关这些命令的更多信息,请参阅 第3步


81
2017-08-05 14:59



@MT:你在哪里输入这些命令?正如我所理解的那样,问题的要点是如何重新同步你的个人 GitHub上 fork与主项目,和 从GitHub做这一切。换句话说,如何更新远程分支 无 本地存储库? - John Y
@JohnY使用GitHub将始终创建额外的提交。您需要在本地存储库的shell中执行所有这些操作以避免额外提交。 - Jonathan Cross


自2013年11月以来,GitHub开启了一个非官方的功能请求,要求他们添加一个非常简单直观的方法来保持本地分支与上游同步:

https://github.com/isaacs/github/issues/121

注意:由于功能请求是非官方的,因此建议您联系 support@github.com 添加对此类功能的支持以实现。上面的非官方特征请求可以用作对此实施的兴趣量的证据。


39
2018-02-21 10:42





前言: 您的fork是“origin”,您分叉的存储库是“上游”。

让我们假设您已经使用以下命令将叉子克隆到计算机:

git clone git@github.com:your_name/project_name.git
cd project_name

如果给出了那么你需要继续这个顺序:

  1. 将“upstream”添加到克隆的存储库(“origin”):

    git remote add upstream git@github.com:original_author/project_name.git
    
  2. 从“上游”获取提交(和分支):

    git fetch upstream
    
  3. 切换到fork的“master”分支(“origin”):

    git checkout master
    
  4. 存储“主”分支的更改:

    git stash
    
  5. 将“上游”的“主”分支中的更改合并到“原点”的“主”分支中:

    git merge upstream/master
    
  6. 解决合并冲突(如果有)并提交合并

    git commit -am "Merged from upstream"
    
  7. 将更改推送到fork

    git push
    
  8. 取回你的藏匿变化(如果有的话)

    git stash pop
    
  9. 你完成了!恭喜!

GitHub还提供了有关此主题的说明: 同步一个分叉


29
2018-03-16 12:24



部分帮助:是 git remote add upstream git@github.com:original_author/project_name.git 只是一个别名 git remote add upstream https://github.com/original_author/project_name.git ? - Wolf
狼,猜测你现在知道这个,但对后人来说......这是ssh的格式。 help.github.com/articles/configuring-a-remote-for-a-fork - Brad Ellis


如果像我一样,你 永远不会直接提交任何东西你真的应该这样做,你可以做到以下几点。

从fork的本地克隆中,创建上游远程。你只需要这样做一次:

git remote add upstream https://github.com/whoever/whatever.git

然后,只要您想要了解上游存储库主分支,您需要:

git checkout master
git pull upstream master

假设你自己从未对主人做过任何事情,你应该已经完成​​了。现在,您可以将本地主服务器推送到原始远程GitHub fork。您还可以在现在最新的本地主服务器上重新设置开发分支。

因此,在初始上游设置和主校验之后,您只需运行以下命令将主服务器与上游同步: git pull上游大师


22
2018-01-03 16:59