[英]How do I update or sync a forked repository on GitHub?
我分叉了一个项目,进行了更改,并创建了一个被接受的拉取请求。 新的提交后来被添加到存储库中。 我如何将这些提交放入我的分叉中?
在分叉存储库的本地克隆中,您可以将原始 GitHub 存储库添加为“远程”。 (“远程”就像存储库 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
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 更新分叉。 这在 2017 年 9 月仍然有效,但它会导致一个肮脏的提交历史。
Update from original
)。现在您有三个选项,但每个选项都会导致提交历史不太干净。
This branch is X commits ahead, Y commits behind <original fork>
。所以是的,你可以使用 GitHub Web UI 让你的 repo 更新到它的上游,但是这样做会破坏你的提交历史。 改用命令行- 这很容易。
这是 GitHub 关于Syncing a 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 分支存储在本地分支 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 上的存储库,请按照此处的说明进行操作
很多答案最终会将您的 fork 移到父存储库之前的一个提交。 此答案总结了此处找到的步骤,这些步骤会将您的 fork 移至与 parent 相同的提交。
将目录更改为您的本地存储库。
git checkout master
切换到 master 分支将父级添加为远程存储库, git remote add upstream <repo-location>
git fetch upstream
发出git rebase upstream/master
git status
检查是否提交了将要合并的内容发出git push origin master
有关这些命令的更多信息,请参阅步骤 3 。
如果像我一样,你从不直接向 master 提交任何东西,你真的应该这样做,你可以执行以下操作。
从 fork 的本地克隆,创建上游远程。 你只需要这样做一次:
git remote add upstream https://github.com/whoever/whatever.git
然后,每当您想赶上上游存储库主分支时,您需要:
git checkout master
git pull upstream master
假设你自己从来没有在 master 上做过任何事情,你应该已经完成了。 现在,您可以将本地 master 推送到您的源远程 GitHub 分支。 您还可以在您现在最新的本地 master 上重新设置您的开发分支。
通过初始上游设置和主节点结帐,您需要做的就是运行以下命令以将您的主节点与上游同步: git pull upstream master 。
前言:你的 fork 是“起源”,而你 fork 的存储库是“上游”。
假设您已经使用以下命令将 fork 克隆到您的计算机:
git clone git@github.com:your_name/project_name.git
cd project_name
如果给出了,那么您需要按以下顺序继续:
将“上游”添加到您的克隆存储库(“来源”):
git remote add upstream git@github.com:original_author/project_name.git
从“上游”获取提交(和分支):
git fetch upstream
切换到 fork 的“master”分支(“origin”):
git checkout master
存储“master”分支的更改:
git stash
将“上游”的“master”分支的更改合并到“origin”的“master”分支中:
git merge upstream/master
解决合并冲突(如果有)并提交合并
git commit -am "Merged from upstream"
将更改推送到您的 fork
git push
取回隐藏的更改(如果有)
git stash pop
你完成了! 恭喜!
GitHub 还提供了有关此主题的说明:同步分叉
自 2013 年 11 月以来,GitHub 收到了一个非官方的功能请求,要求他们添加一种非常简单直观的方法来保持本地分支与上游同步:
https://github.com/isaacs/github/issues/121
注意:由于功能请求是非官方的,因此建议您联系support@github.com
以添加您对要实现的此类功能的支持。 上面的非官方功能请求可以用作对此正在实施的兴趣量的证据。
GitHub 现在推出了一项功能,只需单击按钮即可同步分叉。
转到您的 fork,单击Fetch upstream
,然后单击Fetch and merge
以直接将您的 fork 与其父 repo 同步。
您也可以单击“ Compare
”按钮在合并之前比较更改。
参考:GitHub 的文档
有三种方法可以做到这一点:从 Web UI(选项 1)、从 GitHub CLI(选项 2)或从命令行(选项 3)。
选项 1 - 网页界面
在 GitHub 上,导航到要与上游存储库同步的分叉存储库的主页。
选择获取上游下拉菜单。
- 查看来自上游存储库的提交的详细信息,然后单击 Fetch and merge。
选项 2 - GitHub CLI
要从其父分支更新远程分支,请使用gh repo sync
子命令并提供您的分支名称作为参数。
$ gh repo sync owner/cli-fork
如果上游存储库的更改导致冲突,则 GitHub CLI 无法同步。 您可以设置-force
标志以覆盖目标分支。
选项 3 - 命令行
在将一个分支与上游存储库同步之前,必须在 Git 中配置一个指向上游存储库的远程。
1 打开 Git Bash。
2 将当前工作目录更改为您的本地项目。
3 从上游存储库获取分支及其各自的提交。 对 BRANCHNAME 的提交将存储在本地分支 upstream/BRANCHNAME 中。
$ git fetch upstream
> 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/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
> * [new branch] main -> upstream/main
4 检查你的 fork 的本地默认分支 - 在这种情况下,我们使用 main。
$ git checkout main
> Switched to branch 'main'
5 将上游默认分支(在本例中为 upstream/main)中的更改合并到本地默认分支中。 这将使您的 fork 的默认分支与上游存储库同步,而不会丢失您的本地更改。
$ git merge upstream/main
> 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/main
> Updating 34e91da..16c56ad
> Fast-forward
> README.md | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
注意:同步一个人的分叉只会更新一个人的本地副本。 要在 GitHub.com 上更新一个分支,必须推送一个更改。
如果您使用 GitHub for Windows 或 Mac,那么现在它们具有一键更新 forks 的功能:
实际上,可以从浏览器中上游的任何提交在您的 fork 中创建一个分支:
https://github.com/<repo>/commits/<hash>
,其中repo是您的 fork, hash是提交的完整哈希,您可以在上游 Web 界面中找到它。 例如,我可以打开https://github.com/max630/linux/commits/0aa0313f9d576affd7747cc3f179feb097d28990 ,它指向linux
master
作为写作时间。然后,您可以将该分支获取到您的本地克隆,当您在该提交之上推送编辑时,您不必将所有数据推送回 GitHub。 或者使用 Web 界面更改该分支中的某些内容。
它是如何工作的(这是一个猜测,我不知道 GitHub 到底是怎么做的):forks 共享对象存储并使用命名空间来分隔用户的引用。 因此,您可以通过您的 fork 访问所有提交,即使它们在分叉时不存在。
请按照以下步骤操作。 我尝试了它们,它帮助了我。
结帐到您的分行
语法: git branch yourDevelopmentBranch
示例: git checkout master
拉取源代码库分支以获取最新代码
语法: git pull https://github.com/tastejs/awesome-app-ideas master
示例: git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git BRANCH_NAME
我用这一行更新了我的分叉回购:
git pull https://github.com/forkuser/forkedrepo.git branch
如果您不想将另一个远程端点添加到您的项目中,请使用此选项,就像此处发布的其他解决方案一样。
作为对这个答案的补充,我正在寻找一种方法来一次从上游分支更新我克隆的 repo ( origin ) 的所有远程分支。 我就是这样做的。
这假设您已经配置了一个指向源存储库( origin从中分叉的地方)的上游远程,并已将其与git fetch upstream
同步。
然后运行:
for branch in $(git ls-remote --heads upstream|sed 's#^.*refs/heads/##'); do git push origin refs/remotes/upstream/$branch:refs/heads/$branch; done
该命令的第一部分列出了上游远程 repo 中的所有头,并删除了 SHA-1,后跟refs/heads/
分支名称前缀。
然后对于这些分支中的每一个,它将上游远程跟踪分支的本地副本(本地端的refs/remotes/upstream/<branch>
)直接推送到源端的远程分支(远程端的refs/heads/<branch>
)。
这些分支同步命令中的任何一个都可能由于以下两个原因之一失败:上游分支已被重写,或者您已将该分支上的提交推送到您的 fork。 在第一种情况下,您没有向 fork 上的分支提交任何内容,强制推送是安全的(添加-f开关;即git push -f
在上面的命令中)。 在另一种情况下,这是正常的,因为您的 fork 分支已经发散,并且在您的提交合并回upstream之前,您不能期望 sync 命令起作用。
“Pull”应用程序是一种自动设置和忘记的解决方案。 它会将你的 fork 的默认分支与上游存储库同步。
访问 URL,单击绿色的“安装”按钮并选择要启用自动同步的存储库。
该分支每小时直接在 GitHub 上更新一次,在您的本地机器上,您需要拉取 master 分支以确保您的本地副本是同步的。
如果你设置你的上游。 检查git remote -v
,就足够了。
git fetch upstream
git checkout master
git merge --no-edit upstream/master
git push
克隆分叉存储库后,转到克隆所在的目录路径和 Git Bash 终端中的几行。
$ cd project-name
$ git remote add upstream https://github.com/user-name/project-name.git
# Adding the upstream -> the main repo with which you wanna sync
$ git remote -v # you will see the upstream here
$ git checkout master # see if you are already on master branch
$ git fetch upstream
你可以走了。 主存储库中的所有更新更改都将推送到您的 fork 存储库中。
“fetch”命令对于在项目中保持最新是必不可少的:只有在执行“git fetch”时,您才会被告知您的同事推送到远程服务器的更改。
您仍然可以访问此处进行进一步查询
假设你的 fork 是https://github.com/me/foobar并且原始存储库是https://github.com/someone/foobar
访问https://github.com/me/foobar/compare/master...someone:master
如果您看到绿色文本Able to merge
然后按Create pull request
在下一页上,滚动到页面底部,然后单击Merge pull request和Confirm merge 。
使用此代码段生成链接以同步您的分叉存储库:
new Vue ({ el: "#app", data: { yourFork: 'https://github.com/me/foobar', originalRepo: 'https://github.com/someone/foobar' }, computed: { syncLink: function () { const yourFork = new URL(this.yourFork).pathname.split('/') const originalRepo = new URL(this.originalRepo).pathname.split('/') if (yourFork[1] && yourFork[2] && originalRepo[1]) { return `https://github.com/${yourFork[1]}/${yourFork[2]}/compare/master...${originalRepo[1]}:master` } return 'Not enough data' } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> Your fork URL: <input size=50 v-model="yourFork" /> <br /> Original repository URL: <input v-model="originalRepo" size=50 /> <br /> Link to sync your fork: <a :href="syncLink">{{syncLink}}</a> </div>
$ git remote add upstream https://github.com/....
$ git pull upstream main
$ git push
这取决于您的存储库的大小以及您如何分叉它。
如果它是一个相当大的存储库,您可能希望以一种特殊的方式来管理它(例如删除历史记录)。 基本上,您可以获得当前版本和上游版本之间的差异,提交它们,然后将它们挑选回 master。
试试看 这个。 它描述了如何处理大型 Git 存储库以及如何使用最新更改将它们上传到上游。
最初,分叉的存储库有一个名为master
的分支。 如果您正在开发新功能或修复,您通常会创建一个新的分支feature
并进行更改。
如果您希望分叉存储库与父存储库同步,您可以为Pull 应用程序(在功能分支中)设置一个配置文件( pull.yml
),如下所示:
version: "1"
rules:
- base: feature
upstream: master
mergeMethod: merge
- base: master
upstream: parent_repo:master
mergeMethod: hardreset
这使分叉存储库的master
分支与父存储库保持同步。 它通过合并相同的分叉存储库的master
分支来保持分叉存储库的feature
分支更新。 这假设feature
分支是包含配置文件的默认分支。
这里有两种合并hardreset
mergemethods
它有助于强制在分叉的 repo 的master
分支中与父 repo 同步更改,另一种方法是merge
。 此方法用于合并您在feature
分支中所做的更改以及由于master
分支中的强制同步而完成的更改。 在合并冲突的情况下,拉取应用程序将允许您在拉取请求期间选择下一个操作过程。
您可以在此处阅读有关基本和高级配置以及各种mergemethods
的信息。
保持分叉存储库始终保持更新有两个主要方面。
1. 从 fork master 创建分支并在那里进行更改。
因此,当您的Pull Request被接受时,您可以安全地删除分支,因为当您使用上游更新它时,您贡献的代码将存在于您的分叉存储库的主库中。 这样,您的 master 将始终处于干净状态,可以创建一个新分支来进行另一次更改。
2.为fork master创建一个计划的工作来自动更新。
这可以通过cron来完成。 如果您在 linux 中执行此操作,这是一个示例代码。
$ crontab -e
将此代码放在crontab file
中,以每小时执行一次作业。
0 * * * * sh ~/cron.sh
然后创建cron.sh
脚本文件和与ssh-agent和/或期望的git 交互,如下所示
#!/bin/sh
WORKDIR=/path/to/your/dir
REPOSITORY=<name of your repo>
MASTER="git@github.com:<username>/$REPOSITORY.git"
UPSTREAM=git@github.com:<upstream>/<name of the repo>.git
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent` && expect ~/.ssh/agent && ssh-add -l
git clone $MASTER && cd $REPOSITORY && git checkout master
git remote add upstream $UPSTREAM && git fetch --prune upstream
if [ `git rev-list HEAD...upstream/master --count` -eq 0 ]
then
echo "all the same, do nothing"
else
echo "update exist, do rebase!"
git reset --hard upstream/master
git push origin master --force
fi
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent -k`
检查您的分叉存储库。 它会不时显示此通知:
这个分支甚至与
<upstream>
:master 。
使用这些命令(在幸运的情况下)
git remote -v
git pull
git fetch upstream
git checkout master
git merge upstream/master --no-ff
git add .
git commit -m"Sync with upstream repository."
git push -v
如果你想让你的 GitHub 分支与各自的上游保持同步,还有专门为 GitHub 提供的这个 probot 程序: https ://probot.github.io/apps/pull/ 可以完成这项工作。 您需要在您的帐户中允许安装,这将使您的分叉保持最新。
如何在本地机器上更新你的分叉仓库?
首先,检查您的遥控器/主机
git remote -v
你应该有起源和上游。 例如:
origin https://github.com/your___name/kredis.git (fetch)
origin https://github.com/your___name/kredis.git (push)
upstream https://github.com/rails/kredis.git (fetch)
upstream https://github.com/rails/kredis.git (push)
之后转到主要:
git checkout main
并从上游合并到主要:
git merge upstream/main
rm -rf oldrepository
git clone ...
可能有更微妙的选择,但这是我确信我的本地存储库与上游相同的唯一方法。
从 github 页面删除您的远程开发人员
然后应用这些命令:
1) git branch -D dev
2) git fetch upstream
3) git checkout master
4) git fetch upstream && git fetch upstream --prune && git rebase upstream/master && git push -f origin master
5) git checkout -b dev
6) git push origin dev
7) git fetch upstream && git fetch upstream --prune && git rebase upstream/dev && 8) git push -f origin dev
要查看您的配置,请使用以下命令:
git remote -v
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.