将原始 GitHub 存储库中的新更新拉入分叉的 GitHub 存储库

Posted

技术标签:

【中文标题】将原始 GitHub 存储库中的新更新拉入分叉的 GitHub 存储库【英文标题】:Pull new updates from original GitHub repository into forked GitHub repository 【发布时间】:2011-04-23 15:51:15 【问题描述】:

我在 GitHub 上复制了某人的存储库,并希望使用在原始存储库中进行的提交和更新来更新我的版本。这些是在我 fork 副本之后制作的。

如何提取在源中所做的更改并将它们合并到我的存储库中?

【问题讨论】:

可能重复,或者只是相关:Merging between forks in GitHub. 如果您可能想要同步其他标签,请在建议的解决方案之后执行git push --force origin --tags How do I update a GitHub forked repository?的可能重复 非常古老但仍然:问题尚不清楚,不知道@why 是在询问通过 GitHub Web UI 将更改从主存储库拉入 fork,还是通过本地的 git 命令行。 @chrisimtown下面回答。最终结果是使用原始存储库所做的更改更新了“我的存储库”。现在,你可以通过 github.com 本身的 pull-request 来实现。 【参考方案1】:

如果你想在没有 cli 的情况下做,你可以在 Github 网站上完全做到。

    转到您的 fork 存储库。 点击New pull request。 确保将您的 fork 设置为基本存储库,并将原始(上游)存储库设置为头存储库。通常,您只想同步主分支。 Create a new pull request。 选择合并按钮右侧的箭头,并确保选择变基而不是合并。然后单击按钮。这样就不会产生不必要的合并提交。 完成。

【讨论】:

【参考方案2】:

您必须将原始存储库(您分叉的存储库)添加为远程。

来自GitHub documentation on forking a repository:

克隆完成后,您的 repo 将有一个名为“origin”的远程指向您在 GitHub 上的 fork。 不要让这个名字混淆你,这并不指向你分叉的原始仓库。为了帮助您跟踪该 repo,我们将添加另一个名为“upstream”的远程:

$ cd PROJECT_NAME
$ git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
$ git fetch upstream

# then: (like "git pull" which is fetch + merge)
$ git merge upstream/master master

# or, better, replay your local work on top of the fetched branch
# like a "git pull --rebase"
$ git rebase upstream/master

还有一个command-line tool (hub) which can facilitate the operations above。

这是它如何工作的视觉效果:

另见“Are Git forks actually Git clones?”。

【讨论】:

请参阅bassistance.de/2010/06/25/git-fu-updating-your-github-fork 以获得很好的总结。 @syedrakib 我更喜欢git rebase upstream/master,但我在答案中添加了两种可能性。 @PaBLoX 如果你已经分叉了一个 repo,你正在处理 your repo,在 your 分支:rebase 并强制推送:没有混乱涉及。即使是正在进行的拉取请求也会正确更新。 @PaBLoX 你不会弄得一团糟:你git push --force,用你刚刚重新定位的本地分支替换你在 GitHub 上的分支的历史记录。因为只有你在使用悲伤的分支,所以没有涉及到混乱。 我明白了。我仍然认为这很难,不平凡且不直观。仍然奇怪的是,我的更改总是在最前面(最后),而实际上它们是之前进行的。我之前发布的解决方案看起来更好(仍然很重要)。问题是提交哈希发生了变化(显然,因为有一个新的父级)并且在调用问题时会在 github 内部产生很多噪音。仍然让我感到惊讶的是,没有办法在不创建毫无意义的合并提交或对历史“撒谎”的情况下保持与上游的更新并管理自己的分叉。【参考方案3】:

要自动将您的分叉存储库与父存储库同步,您可以使用 GitHub 上的Pull App。

有关详细信息,请参阅Readme。

有关您希望保留对分叉存储库所做更改的高级设置,请参阅我对类似问题的回答 here。

【讨论】:

【参考方案4】:

如果没有什么可丢失的,您也可以删除您的分叉,只需转到设置...转到下面的危险区域部分,然后单击删除存储库。之后它将要求您输入存储库名称和密码。之后,您只需再次 fork 原始文件。

【讨论】:

【参考方案5】:

这个video 显示how to update a fork directly from GitHub

步骤:

    在 GitHub 上打开你的 fork。 点击Pull Requests。 点击New Pull Request。默认情况下,GitHub 会将原始版本与您的 fork 进行比较,如果您没有进行任何更改,则不应有任何可比较的内容。 点击switching the base。现在 GitHub 会将您的 fork 与原始版本进行比较,您应该会看到所有最新更改。 点击Create a pull request 进行比较,并为您的拉取请求指定一个可预测的名称(例如,从原始更新)。 点击Create pull request。 向下滚动并单击Merge pull request,最后单击Confirm 合并。如果您的分叉没有任何更改,您将能够自动合并它。

【讨论】:

不幸的是,这种漂亮的图形方法会在您的 fork 中产生额外的噪音,正如上面在 cmets 中为接受的答案所提到的那样。因此推荐使用命令行方式:help.github.com/articles/syncing-a-fork 我找不到switching the base 选项 2020 年 9 月的 Github Web UI 有一个“比较和拉取请求”按钮(以前有单独的按钮)。现在它有一个我必须使用的“跨分支比较”链接。因此,可以完成从 master 到 fork 的更新的获取和合并(即拉取)操作,但不能通过这些指令完成。即使这是一个快进,它也让历史变得混乱。【参考方案6】:

用途:

git remote add upstream ORIGINAL_REPOSITORY_URL

这会将您的上游设置为您从中分叉的存储库。 然后这样做:

git fetch upstream      

这将从原始存储库中获取包括 master 在内的所有分支。

在本地主分支中合并这些数据:

git merge upstream/master

将更改推送到您的分叉存储库,即到源:

git push origin master

瞧!您已完成原始存储库的同步。

【讨论】:

如何让上游主机覆盖所有本地文件(因此没有合并冲突)上游主机在这种情况下领先于代码,所以我们 100% 相信它......已经设法做到这一点 一种方法是简单地删除本地副本,然后重新克隆 :)【参考方案7】:

如果您使用的是 GitHub 桌面应用程序,右上角有一个同步按钮。点击它,然后点击左上角附近的Update from <original repo>

如果没有要同步的更改,这将处于非活动状态。

这里有some screenshots 让这一切变得简单。

【讨论】:

【参考方案8】:

除了 VonC 的答案,您还可以根据自己的喜好进一步调整。

从远程分支获取后,您仍然需要合并提交。我会替换

$ git fetch upstream

$ git pull upstream master

因为 git pull 本质上是 git fetch + git merge。

【讨论】:

如果我知道上游分支没有对现有文件进行任何更改,但只添加了几个资源文件 - 我还需要合并吗? 在这种情况下它肯定会快进 如何让 upstream master 覆盖所有本地文件(因此没有合并冲突)上游 master 在这种情况下领先于代码,因此我们 100% 信任它......设法做到这一点 @snh_nl git rebase upstream master 请注意,如果您与upstream/master 有足够的分歧,这并不是没有冲突的。请参阅git-scm.com/docs/git-rebase(tl;dr:这会将您的本地 master 硬重置为上游的 master,然后尝试从分歧点重新合并所有本地提交)

以上是关于将原始 GitHub 存储库中的新更新拉入分叉的 GitHub 存储库的主要内容,如果未能解决你的问题,请参考以下文章

将原始存储库更新合并到私有克隆/分叉存储库 [重复]

我可以使分叉的 github 存储库从原始版本中保持最新吗? [复制]

从分叉存储库中发布来自 GitHub 操作的评论的解决方法

如何将我的分叉回购返回到原始回购

setup.py 拉入非 Python github repos 并将它们放在正确的目录中?

分叉存储库上的原始存储库问题