如何更新 GitHub 分叉存储库?

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

几天后,另一位贡献者进行了另一项更改。因此,我的前叉不包含该更改。

我怎样才能把零钱放进我的叉子?当我有其他更改要贡献时,是否需要删除并重新创建我的 fork?还是有更新按钮?

答案

在您的分支存储库的本地克隆中,您可以将原始 GitHub 存储库添加为 “远程”。 (“Remotes” 就像是存储库 URL 的昵称 - 例如, 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

如果您不想重写 master 分支的历史记录(例如,因为其他人可能已经克隆了它),则应将最后一个命令替换为git merge upstream/master 。但是,为了发出更多尽可能干净的拉取请求,最好重新设置基准。


如果您已将分支重新建立到upstream/master ,则可能需要强制执行推送才能将其推送到 GitHub 上自己的分叉存储库中。您可以这样做:

git push -f origin master

重新设定基准后,您只需要在第一次使用-f

从 2014 年 5 月开始,可以直接从 GitHub 更新 fork。到 2017 年 9 月,它仍然有效, 但是会导致肮脏的提交历史。

  1. 在 GitHub 上打开 fork。
  2. 点击提取请求
  3. 点击New Pull Request 。默认情况下,GitHub 会将原始内容与您的 fork 进行比较,如果您未进行任何更改,则不应有任何可比较的内容。
  4. 如果看到该链接,请单击切换基础 。否则,请手动将基础货叉放置在您的货叉上,并将头货 放置在上游。现在,GitHub 将把您的 fork 与原始的进行比较,您应该会看到所有最新的更改。 在此处输入图片说明
  5. 创建拉取请求并为拉取请求分配一个可预测的名称(例如, Update from original )。
  6. 向下滚动到 “ 合并” 拉取请求 ,但不要单击任何东西。

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

  1. 默认将创建一个丑陋的合并提交。
  2. 如果单击下拉列表,然后选择 “压缩并合并”,则所有介入的提交将被压缩为一个。这通常是您不想要的。
  3. 如果您单击Rebase and merge ,所有提交都将与您一起进行,原始 PR 将链接到您的 PR,并且 GitHub 将显示This branch is X commits ahead, Y commits behind <original fork>

所以是的,您可以使用 GitHub Web UI 对其仓库进行上游更新,但是这样做可以确保您的提交历史记录。坚持使用命令行 - 这很容易。

这是 GitHub 上有关同步 fork的官方文档:

同步叉子

设置

在同步之前,您需要添加一个指向上游存储库的远程服务器。最初分叉时,您可能已经这样做了。

提示:同步 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

现在,我们将上游的 master 分支存储在本地分支中,上游 / 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 上更新存储库,请按照此处的说明进行操作

许多答案最终导致将叉子一次提交移到父存储库之前。该答案总结了此处找到的步骤这些步骤会将您的 fork 移至与父代相同的提交

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

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

  3. git fetch upstream发出git fetch upstream
  4. 发行git rebase upstream/master

    • 在此阶段,您可以通过键入git status来确认将要合并的内容
  5. 发行git push origin master

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

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

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

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

前言:您的 fork 是 “源”,而您从其派生的存储库是 “上游”。

假设您已经使用以下命令将 fork 克隆到了计算机上:

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

如果给出了,那么您需要按照以下顺序继续:

  1. 将 “上游” 添加到克隆的存储库(“起源”)中:

    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. 将更改推送到你的叉子

    git push
  8. 找回隐藏的更改(如果有)

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

GitHub 还提供了有关该主题的说明: 同步 fork

如果像我一样,您从未真正将任何事情直接提交给 master ,那么您应该执行以下操作。

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

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

然后,无论何时要赶上上游存储库主分支,都需要:

git checkout master
git pull upstream master

假设您自己从未对 master 做出任何承诺,那么您应该已经完成。现在,您可以将本地主机推送到源远程 GitHub 分支。您还可以将开发分支基于最新的本地主数据库。

在完成初始上游设置和 master 检出之后,您所需要做的就是运行以下命令将您的 master 与上游同步: git pull 上游 master

截至本答案发布之日,GitHub 在 Web 界面中尚未( 或我不再说吗? )此功能。但是,您可以要求support@github.com对此进行投票。

同时,GitHub 用户 bardiharborow 创建了一个工具来执行此操作: https ://upriver.github.io/

来源在这里: https : //github.com/upriver/upriver.github.io

如果您将 GitHub 用于 Windows 或 Mac,则现在它们具有一键式功能来更新 fork:

  1. 在用户界面中选择存储库。
  2. 单击顶部的 “从用户 / 分支更新” 按钮。

实际上,可以从浏览器中上游的任何提交在分支中创建分支:

在此处输入图片说明

然后,您可以将该分支获取到本地克隆,并且在该提交之上进行编辑时,不必将所有数据都推回 GitHub。或使用 Web 界面更改该分支中的某些内容。

它是如何工作的(猜测,我不知道 GitHub 如何做到这一点):fork 共享对象存储并使用命名空间来分隔用户的引用。因此,即使在派生时它们不存在,您也可以通过您的 fork 访问所有提交。