Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Github进行fork后如何与原仓库同步:重新fork很省事,但不如反复练习版本合并 #67

Open
liujuanjuan1984 opened this issue Mar 15, 2019 · 48 comments

Comments

@liujuanjuan1984
Copy link
Contributor

liujuanjuan1984 commented Mar 15, 2019

下面2楼和3楼,都可能是你需要的。

@liujuanjuan1984 liujuanjuan1984 changed the title guideline for merge Github进行fork后如何与原仓库同步/重新fork很麻烦?试试合并吧。。 Mar 15, 2019
@liujuanjuan1984
Copy link
Contributor Author

liujuanjuan1984 commented Mar 15, 2019

Github进行fork后如何与原仓库同步

实在是……有太多人同时在帮忙修订错别字或优化 xiaolai 的 the-craft-of-selfteaching 了。如果你提交的 pull request 未被接受且得到回复说:“重新fork”,其实是你遇到一个问题:

  • 在你 fork 之后, xiaolai 的仓库又更新了;
  • 但 github 不会自动帮你把 xiaolai 的仓库 同步给你 fork 后的仓库;
  • 导致你提交 pull request 时的版本和 xiaolai 的版本不一致。

这个问题,用显得更“专业点”的说法,叫做:Github进行fork后如何与原仓库同步。那到底怎么做呢?

最省事的办法可能是:

  • 在你fork的仓库setting页翻到最下方,然后delete这个仓库;
  • 然后重新fork xiaolai 的仓库,并 git clone 到你的本地。

有时候,你需要用到这个省事的办法,比如 xiaolai 的仓库再次整理了 commit 。但在更多情况下,删掉自己fork的库,应该是你的最后选择,而不应该是首选。

和很多人一起向 xiaolai 提交 pull request,这实在是一个反复练习 merge (中文说法:合并,或版本合并)的机会。毫不夸张地讲,版本管理是软件工程极其重要的规范,也是极其基础的必备技能。而 merge 则是版本管理中最必须也最常用的场景。

那要不然,就多练练?以下是傻瓜版操作步骤,还细心配了截图,保管你从 0 也能上手。至于原理嘛,慢慢再搞懂吧。

merge前的设定

step 1、进入到本地仓库的目录。

下面所有操作,如无特别说明,都是在你的本地仓库的目录下操作。比如我的本地仓库为/from-liujuanjuan-the-craft-of-selfteaching

image

step 2、执行命令 git remote -v 查看你的远程仓库的路径:

image

如果只有上面2行,说明你未设置 upstream (中文叫:上游代码库)。一般情况下,设置好一次 upstream 后就无需重复设置。

step 3、执行命令 git remote add upstream https://github.com/selfteaching/the-craft-of-selfteaching.git 把 xiaolai 的仓库设置为你的 upstream 。这个命令执行后,没有任何返回信息;所以再次执行命令 git remote -v 检查是否成功。

image

step 4、执行命令 git status 检查本地是否有未提交的修改。如果有,则把你本地的有效修改,先从本地仓库推送到你的github仓库。最后再执行一次 git status 检查本地已无未提交的修改。

git add -A 或者 git add filename
git commit -m "your note"
git push origin master
git status

注1:这一步作为新手,建议严格执行,是为了避免大量无效修改或文本冲突带来的更复杂局面。

注2:如果你已经在fork后的仓库提交了大量对 xiaolai 的仓库并没有价值的修改,那么想要pull request,还是重新回到本文最初的“最省事办法”吧。

merge 的关键命令

以下操作紧接着上面的步骤。

step 5、执行命令 git fetch upstream 抓取 xiaolai 原仓库的更新:

image

step 6、执行命令 git checkout master 切换到 master 分支:

image

step 7、执行命令 git merge upstream/master 合并远程的master分支:

image

step 8、执行命令 git push 把本地仓库向github仓库(你fork到自己名下的仓库)推送修改

如果担心自己不小心改了哪里,可以再次执行命令 git status 检查哪些文件有变化。这个操作仅是检查,不会改变任何状态,放心用。

image

现在你已经解决了fork的仓库和原仓库版本不一致的问题。可以放心向 xiaolai 发起 pull request 了。如果以上操作你花了不少时间,而 xiaolai 的仓库 又恰好更新了。很好,一次新的练习机会来了……

@ZoomQuiet
Copy link
Contributor

是也乎,( ̄▽ ̄)

增补之前想增补到 ipynb 中的阐述

PS: 如何优雅的获得上游最新内容?

... 必须重新弄一个当前最新版本到本地

这是一个常见 github 操作, 但是, 其操作涉及复杂的 git 概念,
所以, 在此简要描述一下最小过程(MVP):

1: 首先, 新增 remote (远程上游仓库), 即, 将本书仓库, 追加为 fork 仓库的上游仓库

git remote add upstream https://github.com/selfteaching/the-craft-of-selfteaching.git

此时检验本地工作复本仓库的配置就可以看到变化:

$  cat .git/config

...

[branch "master"]
	remote = origin
	merge = refs/heads/master
[remote "upstream"]
	url = https://github.com/selfteaching/the-craft-of-selfteaching.git
	fetch = +refs/heads/*:refs/remotes/upstream/*

在底部追加了 upstream (上游)仓库信息, 可以用 branch 命令来检验

$  git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/upstream/master

2: 同步上游修订, 使用 fetch 命令

$  git fetch upstream
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Total 12 (delta 2), reused 2 (delta 2), pack-reused 10
Unpacking objects: 100% (12/12), done.
From https://github.com/selfteaching/the-craft-of-selfteaching
   7b3aeea..4646cc8  master     -> upstream/master

然后, 在此基础上进行修订, 以及 Pull-Request 才是正义的.

简单的说:

  • 声明上游仓库
  • 每次进行修订前先 fetch 上游修订
  • 如果和本地有冲突, 先在本地解决冲突

PPS:

软件工程中协同方式原则

在哪些情况下可以直接使用master branch来提交Pull Request:

你只想为主项目贡献某一处代码,贡献完自己的repo就可以扔的那种。
你打算为主项目长期贡献代码,而且希望追随原项目的主线开发,不保留自己的特性。
你打算为主项目长期贡献代码,默认master branch追随原项目主线,把自己的特性放到别的branch中。

在哪种情况下应该使用主题branch来提交Pull Request:

想用master branch完全来做自己的开发。在这种情形下:会从上游库合并更新,但是这些merge本身的commits显然不可能作为返还到上游库的Pull Request的一部分。
存在自己的(未被merge或者不想被merge到上游库的)commits。

鉴于Git的分布式开发哲学,每一个库均可以看作是一个独立的项目,显然是后一种(为每一个新特性建立一个专门的主题branch来向主项目推送Pull Request)的贡献方式更可取。
解释完毕(`・ω・´)

引用自: 如何参与Tianchi(天池)项目以及如何贡献代码 - QTCN开发网 - Powered by phpwind

@liujuanjuan1984 liujuanjuan1984 changed the title Github进行fork后如何与原仓库同步/重新fork很麻烦?试试合并吧。。 Github进行fork后如何与原仓库同步:重新fork很省事,但不如反复练习版本合并 Mar 15, 2019
@yingca1
Copy link

yingca1 commented Mar 16, 2019

如果远程主仓库的历史 commits 被修改整理过,而自己在未同步远程主仓库的情况下有新的 PR 需要提交,可以有两个方案处理:

  1. fork 最新的远程主仓库,重新提交
    1.1 备份自己的改动
    1.2 删除自己的 fork 的仓库,重新 fork 远程主仓库
    1.3 将最新改动的应用到新 fork 的仓库,然后提交 PR

  2. 强制同步远程主仓库的所有历史 commits,处理冲突,再次提交
    1.1 备份自己的改动(可以选择用一个新的分支或者直接将问题复制到本地存储的其他文件目录)
    1.2 添加远程主仓库为自己本地仓库的一个 upstream(如命名为 origin),使用以下命令强制同步
    git fetch origin && git reset --hard origin/master && git clean -f -d
    1.3 将自己的改动应用到强制同步过的分支,如果使用的其他分支备份,可以使用 rebase 命令合并过来,如果有冲突,处理冲突
    1.4 检查自己的 commits 是否正确合理,无问题则可重新提交 PR

@zhzja
Copy link

zhzja commented Mar 16, 2019

反复练习

@gantrol
Copy link
Contributor

gantrol commented Mar 16, 2019

分享一个命令,直接强制同步源仓库(upstream),就不用删了。。

git fetch upstream && git reset --hard upstream/master && git push -f

git push -f确实是很粗暴,这种方法也只适用于不用保存自己的版本的情况而已。

@blockchain-onlooker
Copy link

#144

@realcaiying 我就纳闷为啥楼主会作死去用rebase,原来是你挖的坑……

楼上 git push -f 其实也不是很可取的方案,虽然比直接删除仓库强。真不怕初学者习惯了,然后用这招破坏掉多人协作库么,为了防止这种情况,企业内部gitlab我都默认master分支不允许 git push -f

@frostming
Copy link

frostming commented Mar 17, 2019

不明白为啥要push -f, 如果你打算用git reset --hard upstream/master让master永远与上游同步的话。完全不用推到自己的fork,我本地开发一般都是这样的:以上游为主

git clone <upstream_repo_url>
git remote add fork <fork_repo_url>
git fetch origin
git reset --hard origin/master
git checkout -b feature-1
# do some change, commits
git push -u fork

每次同步上游就切到master执行git fetch origin && git reset --hard upstream/master,并不push 回去的啊。feature分支的冲突再用merge/rebase解决就好了。所以一般fork的master都是落后上游并从不更新。

PS: 此用法仅针对使用github-flow贡献的情况,即每次PR都是从feature分支发起,不适用上文提到的用master进行fork开发(不返回上游库)。

@yingca1
Copy link

yingca1 commented Mar 17, 2019

#144

@realcaiying 我就纳闷为啥楼主会作死去用rebase,原来是你挖的坑……

楼上 git push -f 其实也不是很可取的方案,虽然比直接删除仓库强。真不怕初学者习惯了,然后用这招破坏掉多人协作库么,为了防止这种情况,企业内部gitlab我都默认master分支不允许 git push -f

git push -f 确实是很危险的操作,主仓库也只会开放给少数人这个权限。

显然本地仓库与主仓库的历史不一致是经常会出现的,在企业开发中,如果开发人数达到一定规模,代码回滚、整理历史 commits、测试主分支切换功能测试等可能造成自己仓库和主仓库历史不一致。

使用 git 达到同一个目的的方案有很种。提交 PR 的人不一定需要 git push -f 更改自己的远程仓库,其实楼主这个情况,只需要保证提交 PR 的分支与远程主仓库历史 commits 同源即可,方案很多可以选择。

@richardchen0954
Copy link
Contributor

在自己的 fork 页面 PullRequest,然后把 base 和 head 顺序调换一下,把源头的更新 merge 到自己 fork 的版本中,然后,pull 到本地也能同步。只不过节点看上去没有“一条龙”的样子好看。
反pull

@sxuya
Copy link
Contributor

sxuya commented Apr 11, 2019

这些 fetch、commit 的命令操作,和在图形化应用 Github Desktop 上面进行点击操作,效果是一样的吧?

难道觉得这种点击操作太 low 了?

@sxuya
Copy link
Contributor

sxuya commented Apr 11, 2019

远程的master分支
应该就是指的是
upstream 的 master
吧?

介绍里面同一个内容,用不同的名字进行称呼,看得真的凌乱。

@sxuya
Copy link
Contributor

sxuya commented Apr 11, 2019

origin vs upstream 的说明 这篇文章的解释,总结出合并的简要过程:

版本一:fork 后未做任何改动

fork xiaolai 老师的 repository 后,直接 clone 到自己的电脑上,没有做任何改动,那么,
做完 liujuanjuan 的步骤后,提交 pull requests 的方法:

  1. 创建一个自己玩耍、测试、修改用的分支,随便怎么折腾;
  2. 发现有什么想要修改 xiaolai 老师的原始内容后:
    1. 切换回到 master 分支;
    2. 使用命令 git fetch upstream,把 xiaolai 最新的内容进行更新。
    3. 如果自己想要修改的内容已经被别人修改了,恭喜,你迟了。【下面的步骤就不用做了】。
  3. 在自己电脑上进行修改,提交到自己的 master 中。
  4. 在网页上,按照 xiaolai 老师介绍的方法提交 pull requests 就好了。

版本二:fork 后做了改动

  1. 先把自己的改动 push 到自己的 repository 中。
  2. 从 版本一 中的 2.1 开始操作。(解释:这样应该会把自己做的修改覆盖掉,所以,两个选择:1)备份自己的修改内容先;2)建立一个 branch 进行保留。【注意】:如果使用 delete repository 原始方法,branch 的方法保留的备份也没有啦,虽然现在自己的修改内容可以一点价值都没有,消失掉就消失掉吧/微笑)

可能的意外情况:

  1. 发生了 conflict(冲突)。应该是操作慢了,xiaolai 的版本又更新了,那么重新操作版本一,也就是一个不断重复的循环操作
  2. 无关紧要的变动,比如 Python 版本不一致,导致很多没用的变动。我是把自己电脑的原来的程序全部重新安装了一遍,遇到了超级多的问题,一度很爆炸,但是过来了。你也可以的。

@sxuya
Copy link
Contributor

sxuya commented Apr 12, 2019

Github进行fork后如何与原仓库同步

实在是……有太多人同时在帮忙修订错别字或优化 xiaolai 的 the-craft-of-selfteaching 了。如果你提交的 pull request 未被接受且得到回复说:“重新fork”,其实是你遇到一个问题:

  • 在你 fork 之后, xiaolai 的仓库又更新了;
  • 但 github 不会自动帮你把 xiaolai 的仓库 同步给你 fork 后的仓库;
  • 导致你提交 pull request 时的版本和 xiaolai 的版本不一致。

这个问题,用显得更“专业点”的说法,叫做:Github进行fork后如何与原仓库同步。那到底怎么做呢?

最省事的办法可能是:

  • 在你fork的仓库setting页翻到最下方,然后delete这个仓库;
  • 然后重新fork xiaolai 的仓库,并 git clone 到你的本地。

有时候,你需要用到这个省事的办法,比如 xiaolai 的仓库再次整理了 commit 。但在更多情况下,删掉自己fork的库,应该是你的最后选择,而不应该是首选。

和很多人一起向 xiaolai 提交 pull request,这实在是一个反复练习 merge (中文说法:合并,或版本合并)的机会。毫不夸张地讲,版本管理是软件工程极其重要的规范,也是极其基础的必备技能。而 merge 则是版本管理中最必须也最常用的场景。

那要不然,就多练练?以下是傻瓜版操作步骤,还细心配了截图,保管你从 0 也能上手。至于原理嘛,慢慢再搞懂吧。

merge前的设定

step 1、进入到本地仓库的目录。

下面所有操作,如无特别说明,都是在你的本地仓库的目录下操作。比如我的本地仓库为/from-liujuanjuan-the-craft-of-selfteaching

image

step 2、执行命令 git remote -v 查看你的远程仓库的路径:

image

如果只有上面2行,说明你未设置 upstream (中文叫:上游代码库)。一般情况下,设置好一次 upstream 后就无需重复设置。

step 3、执行命令 git remote add upstream https://github.com/selfteaching/the-craft-of-selfteaching.git 把 xiaolai 的仓库设置为你的 upstream 。这个命令执行后,没有任何返回信息;所以再次执行命令 git remote -v 检查是否成功。

image

step 4、执行命令 git status 检查本地是否有未提交的修改。如果有,则把你本地的有效修改,先从本地仓库推送到你的github仓库。最后再执行一次 git status 检查本地已无未提交的修改。

git add -A 或者 git add filename
git commit -m "your note"
git push origin master
git status

注1:这一步作为新手,建议严格执行,是为了避免大量无效修改或文本冲突带来的更复杂局面。

注2:如果你已经在fork后的仓库提交了大量对 xiaolai 的仓库并没有价值的修改,那么想要pull request,还是重新回到本文最初的“最省事办法”吧。

merge 的关键命令

以下操作紧接着上面的步骤。

step 5、执行命令 git fetch upstream 抓取 xiaolai 原仓库的更新:

image

step 6、执行命令 git checkout master 切换到 master 分支:

image

step 7、执行命令 git merge upstream/master 合并远程的master分支:

image

step 8、执行命令 git push 把本地仓库向github仓库(你fork到自己名下的仓库)推送修改

如果担心自己不小心改了哪里,可以再次执行命令 git status 检查哪些文件有变化。这个操作仅是检查,不会改变任何状态,放心用。

image

现在你已经解决了fork的仓库和原仓库版本不一致的问题。可以放心向 xiaolai 发起 pull request 了。如果以上操作你花了不少时间,而 xiaolai 的仓库 又恰好更新了。很好,一次新的练习机会来了……

自己的 repository 的 master 和 upstream 不一样,但是执行完这些操作之后,内容还是不一样呀,难道只能重新删除再 fork?

@sxuya
Copy link
Contributor

sxuya commented Apr 12, 2019

是也乎,( ̄▽ ̄)
。。。
鉴于Git的分布式开发哲学,每一个库均可以看作是一个独立的项目,显然是后一种(为每一个新特性建立一个专门的主题branch来向主项目推送Pull Request)的贡献方式更可取。
解释完毕(`・ω・´)

引用自: 如何参与Tianchi(天池)项目以及如何贡献代码 - QTCN开发网 - Powered by phpwind

强烈建议看上面的 天池 的链接的内容,

liujuanjuan 同学和 xiaolai 老师漏掉了一个最关键的内容:要用 branch 提交 pull requests,而不能用 master 分支进行,要不然一些不顺利的情况发生(比如没有采纳merge、误删文件等等)都无法进行 upstream 的同步。

为什么按照 liujuanjuan 和 xiaolai 的步骤全部做完之后,只有第一次是成功的、后面的提交就会出现问题,就是这个原因。

连接里面有个很关键的信息:

  1. 无论被 merge 了还是 拒绝了,都可以单独对 branch进行操作,无论成功与否,delete 掉提交 PR 的 branch 是完全无害的;
  2. 且这样,master 的同步才不会出现问题。

PS:为什么会知道这些?因为创建了两个帐号,互相进行各种可能的操作(upstream 删除了但是 origin 没有操作等等各种组合),捯饬了一个下午,一直在纠结所有分类情况里面的剩下的两种无法解决的:

upstream 删除内容,我的 master 怎么就 fetch 不过来?

我删除了的内容,如何用 upstream 的进行还原?

总结:全都是用分支 branch 进行隔离,这样,永远不会发生 delete 原始 fork。(除非不玩这个项目了)

@wengyangjie
Copy link

谢谢

@XiaosongWen
Copy link

感谢感谢

@qwfys
Copy link

qwfys commented Apr 8, 2020

不错。

@WLyKan
Copy link

WLyKan commented Jun 29, 2020

直接反向发起PR也可以,把主仓库的PR到自己fork的仓库

@JasonKitty
Copy link

先mark

@wwwxj123
Copy link

wwwxj123 commented Jul 30, 2020 via email

@JornShen
Copy link

JornShen commented Sep 1, 2020

界面操作方法,不需要重新fork

从主库中提个mr到的fork仓库

比如:

image

注意左边是的仓库,然后create pull request。创建了完了以后,在你的仓库点击merge。

image

链接:JornShen/kubernetes#2

然后你就可以直接用的你自己的仓库了。

@Caffreyfans
Copy link

Mark

@iFHiGM
Copy link

iFHiGM commented Nov 10, 2020

@sxuya

是也乎,( ̄▽ ̄)
。。。
鉴于Git的分布式开发哲学,每一个库均可以看作是一个独立的项目,显然是后一种(为每一个新特性建立一个专门的主题branch来向主项目推送Pull Request)的贡献方式更可取。
解释完毕(`・ω・´)
引用自: 如何参与Tianchi(天池)项目以及如何贡献代码 - QTCN开发网 - Powered by phpwind

强烈建议看上面的 天池 的链接的内容,

liujuanjuan 同学和 xiaolai 老师漏掉了一个最关键的内容:要用 branch 提交 pull requests,而不能用 master 分支进行,要不然一些不顺利的情况发生(比如没有采纳merge、误删文件等等)都无法进行 upstream 的同步。

为什么按照 liujuanjuan 和 xiaolai 的步骤全部做完之后,只有第一次是成功的、后面的提交就会出现问题,就是这个原因。

连接里面有个很关键的信息:

1. 无论被 merge 了还是 拒绝了,都可以单独对 branch进行操作,无论成功与否,delete 掉提交 PR 的 branch 是完全无害的;

2. 且这样,master 的同步才不会出现问题。

PS:为什么会知道这些?因为创建了两个帐号,互相进行各种可能的操作(upstream 删除了但是 origin 没有操作等等各种组合),捯饬了一个下午,一直在纠结所有分类情况里面的剩下的两种无法解决的:

upstream 删除内容,我的 master 怎么就 fetch 不过来?

我删除了的内容,如何用 upstream 的进行还原?

总结:全都是用分支 branch 进行隔离,这样,永远不会发生 delete 原始 fork。(除非不玩这个项目了)

在搜索github相关操作时,无意间看到这个issue,对你的评论中提到的

要用 branch 提交 pull requests,而不能用 master 分支进行,要不然一些不顺利的情况发生(比如没有采纳merge、误删文件等等)都无法进行 upstream 的同步。

2. 且这样,master 的同步才不会出现问题。

产生了一些疑问,当然我也点进上面天池的链接查找原因,但遗憾的是并没有找到(没有说明原因)

Step 2: 创建你的主题(topic)branch
这一步非常重要。GitHub的帮助里没有提到创建主题branch的必要性,你当然可以直接在原项目的默认branch(如master)上进行工作,但实际上:
如果打算为原项目作贡献,强烈建议你为每个主题创建一个单独的branch。
举例:如果需要修复原项目的一个和Unicode相关的issue:
$ git branch fix-unicode-error$ git checkout fix-unicode-error
然后在自己的主题branch(这里是fix-unicode-error)下进行工作。

故而对此进行了一些验证(下面描述下步骤,截图太杂就不贴了)。

  1. 我创建了第二个github(后面简称two_account)账户。
  2. 在第一个github账户(后面简称first_account)上创建了一个测试仓库(后面简称test_repo)。
  3. 在two_account fork了first_account的仓库test_repo,这里命名为test_repo_fork。
  4. 在test_repo_fork上新提交一个commit(fork_1_commit),然后使用test_repo_fork的master分支对test_repo发起了一个Pull request(PR1)。
  5. 在first_account上close掉PR1,之后为test_repo提交一个新的commit(1_commit)。
  6. 在test_repo_fork上pull upstream master(merge方式),成功同步了test_repo的1_commit。
  7. 之后又对test_repo_fork做了一次commit,并再一次向test_repo提出pull request,成功提交。
  8. 上面个的情况是将PR关闭,同时之后又对直接merge PR做了两次测试,同样对upstream与origin(local)之间的同步没有影响。

此外,针对

upstream 删除内容,我的 master 怎么就 fetch 不过来?

这种情况,我也做了测试,测试显示upstream库删除文件(或者内容),fork库可以通过fetch操作更新(在前面操作的基础上,并且两个库都只涉及到mater分支)。
而fork库删除内容用upstream恢复,私以为应该同理,就没做测试。

以上。

所以测试完成之后,就更加疑惑了,如能交流,不胜感激。
当然,也有可能是我没get到你的具体错误的场景,如有错误,可以指出哈哈,我只是对单纯的对你提到的场景很感兴趣emmm。

@baddate
Copy link

baddate commented Nov 19, 2020

Github进行fork后如何与原仓库同步

实在是……有太多人同时在帮忙修订错别字或优化 xiaolai 的 the-craft-of-selfteaching 了。如果你提交的 pull request 未被接受且得到回复说:“重新fork”,其实是你遇到一个问题:

  • 在你 fork 之后, xiaolai 的仓库又更新了;
  • 但 github 不会自动帮你把 xiaolai 的仓库 同步给你 fork 后的仓库;
  • 导致你提交 pull request 时的版本和 xiaolai 的版本不一致。

这个问题,用显得更“专业点”的说法,叫做:Github进行fork后如何与原仓库同步。那到底怎么做呢?

最省事的办法可能是:

  • 在你fork的仓库setting页翻到最下方,然后delete这个仓库;
  • 然后重新fork xiaolai 的仓库,并 git clone 到你的本地。

有时候,你需要用到这个省事的办法,比如 xiaolai 的仓库再次整理了 commit 。但在更多情况下,删掉自己fork的库,应该是你的最后选择,而不应该是首选。

和很多人一起向 xiaolai 提交 pull request,这实在是一个反复练习 merge (中文说法:合并,或版本合并)的机会。毫不夸张地讲,版本管理是软件工程极其重要的规范,也是极其基础的必备技能。而 merge 则是版本管理中最必须也最常用的场景。

那要不然,就多练练?以下是傻瓜版操作步骤,还细心配了截图,保管你从 0 也能上手。至于原理嘛,慢慢再搞懂吧。

merge前的设定

step 1、进入到本地仓库的目录。

下面所有操作,如无特别说明,都是在你的本地仓库的目录下操作。比如我的本地仓库为/from-liujuanjuan-the-craft-of-selfteaching

image

step 2、执行命令 git remote -v 查看你的远程仓库的路径:

image

如果只有上面2行,说明你未设置 upstream (中文叫:上游代码库)。一般情况下,设置好一次 upstream 后就无需重复设置。

step 3、执行命令 git remote add upstream https://github.com/selfteaching/the-craft-of-selfteaching.git 把 xiaolai 的仓库设置为你的 upstream 。这个命令执行后,没有任何返回信息;所以再次执行命令 git remote -v 检查是否成功。

image

step 4、执行命令 git status 检查本地是否有未提交的修改。如果有,则把你本地的有效修改,先从本地仓库推送到你的github仓库。最后再执行一次 git status 检查本地已无未提交的修改。

git add -A 或者 git add filename
git commit -m "your note"
git push origin master
git status

注1:这一步作为新手,建议严格执行,是为了避免大量无效修改或文本冲突带来的更复杂局面。

注2:如果你已经在fork后的仓库提交了大量对 xiaolai 的仓库并没有价值的修改,那么想要pull request,还是重新回到本文最初的“最省事办法”吧。

merge 的关键命令

以下操作紧接着上面的步骤。

step 5、执行命令 git fetch upstream 抓取 xiaolai 原仓库的更新:

image

step 6、执行命令 git checkout master 切换到 master 分支:

image

step 7、执行命令 git merge upstream/master 合并远程的master分支:

image

step 8、执行命令 git push 把本地仓库向github仓库(你fork到自己名下的仓库)推送修改

如果担心自己不小心改了哪里,可以再次执行命令 git status 检查哪些文件有变化。这个操作仅是检查,不会改变任何状态,放心用。

image

现在你已经解决了fork的仓库和原仓库版本不一致的问题。可以放心向 xiaolai 发起 pull request 了。如果以上操作你花了不少时间,而 xiaolai 的仓库 又恰好更新了。很好,一次新的练习机会来了……

请教一个问题:如果原仓库新建了很多分支,该怎么同步这些分支到远程啊?有没有什么简单的方法?还是说只能一个分支一个分支去push?

@ahern88
Copy link

ahern88 commented Jan 14, 2021

mark,学习到了

@youngjuning
Copy link

感谢分享,用到了

@kooroEZP
Copy link

mark-fork synchronized explain

@JornShen
Copy link

一般往开源上提代码,不需要一直同步主库的代码。

你只需 clone 主库代码仓,然后 git remote add XXX 你的仓库地址。
然后 checkout 一个新分支,然后 push XXX 分支名。
之后github上提交 merge request合代码。

@youngjuning
Copy link

一般往开源上提代码,不需要一直同步主库的代码。

你只需 clone 主库代码仓,然后 git remote add XXX 你的仓库地址。
然后 checkout 一个新分支,然后 push XXX 分支名。
之后github上提交 merge request合代码。

你这也行,就是放弃自己分支的 main 分支。

@JornShen
Copy link

你这也行,就是放弃自己分支的 main 分支。

如果是仅仅看,学习,不需要fork到自己的仓库,除非你想二次开发,或者贡献社区。

@youngjuning
Copy link

你这也行,就是放弃自己分支的 main 分支。

如果是仅仅看,学习,不需要fork到自己的仓库,除非你想二次开发,或者贡献社区。

额,看有啥意思,直接撸源码

@hermitcai
Copy link

界面操作方法,不需要重新fork

朋友 你的图 好像给反了
是需要在fork的仓库操作merge 你给的图示是在主仓库操作merge

@zhaopan
Copy link

zhaopan commented May 7, 2021

mark fork

@zpc7
Copy link

zpc7 commented May 29, 2021

当前可以在网页上简单操作了,类似于代码回合. 在你的 fork仓库 中可以直接通过Fetch upstream功能, 来完成跟你的上游同步!

本质就是提了一个 PR, 但是需要注意, 因为是使用的PR的方式, commit历史记录没办法完全跟上游一样: 使用merge合入会产生一个merge commit,使用rebase 会导致每个commit的作者是上游的作者,但是提交者是你自己(最后一张图).
image
image
image

如果你只是想简单快速的同步一次(commit也没有任何变化), 推荐这位兄弟的方法 #67 (comment)

@lemonbox
Copy link

mark

@dengnan123
Copy link

学习了

@gmt710
Copy link

gmt710 commented Dec 6, 2021

学会了

@lhmwzy
Copy link

lhmwzy commented Apr 17, 2022

学习

@HelloAndyZhang
Copy link

学会了

@clyuz
Copy link

clyuz commented Sep 20, 2022

mark

@gyt95
Copy link

gyt95 commented Nov 6, 2022

有用

@willzhang
Copy link

不明白为啥要push -f, 如果你打算用git reset --hard upstream/master让master永远与上游同步的话。完全不用推到自己的fork,我本地开发一般都是这样的:以上游为主

git clone <upstream_repo_url>
git remote add fork <fork_repo_url>
git fetch origin
git reset --hard origin/master
git checkout -b feature-1
# do some change, commits
git push -u fork

每次同步上游就切到master执行git fetch origin && git reset --hard upstream/master,并不push 回去的啊。feature分支的冲突再用merge/rebase解决就好了。所以一般fork的master都是落后上游并从不更新。

PS: 此用法仅针对使用github-flow贡献的情况,即每次PR都是从feature分支发起,不适用上文提到的用master进行fork开发(不返回上游库)。

我以为fork的仓库必须要始终和上游同步,原来完全没必要,只搞分支即可。

@An-Jhon
Copy link

An-Jhon commented Dec 29, 2022

在网页上使用Fetch upstream功能更新代码,如果代码有冲突需要怎么解决呢?

@ruixuan-ray-zhang
Copy link

thanks

@Jackeriss
Copy link

@wuduande
Copy link

wuduande commented Dec 25, 2023 via email

@wenjunmo
Copy link

wenjunmo commented Dec 25, 2023 via email

@Hu-shaojie
Copy link

Hu-shaojie commented Dec 25, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests