fork后代码和源代码同步
为何要fork第三方库
开发中我们经常会用到一些第三方库。如SDWebImage,AFNetWorking等等。
这些第三方库不需要做任何修改,基本都能满足我们的需求。最多就是在根据业务简单的封装一下。 但是在某些情况下又不得不对一些第三方库修改,如遇到以下情况:
- 第三方库存在bug不能及时fix(这经常出现在SDK系统刚升级的时候)
- 第三方库不够灵活,不能很好满足一些个性化的定制,需要我们修改源码
- 第三库写的比较周全,我们只需要一些部分功能,为了追求一些性能需要精简一些代码
- 其他种种
Tips:
不建议直接修改第三方源码。如果能通过再次封装或者写一些扩展方法来实现就不要直接修改源码。因为可能以后第三方库升级了之后可能和我们以前的修改代码不兼容。
虽然是不建议,但是在实际开发中我们还是经常需要直接修改源码。修改源码一般有下面两种方式:
- 方式一 下载源码,直接加入工程并修改。
- 方式二 拷贝代码仓库(连同git,svn等)放到一个服务器上如github。
如果第三方库有版本控制的话,建议采用方式二,因为如果以后第三方库升级之后,我们可以用我们copy的仓库对比。根据情况处理我们修改的代码和第三方库的更新的代码。现在大多数第三方库都可以在github上找到,在github上实现方式二,只需要fork一下(点击一下fork按钮)。clone自己fork的仓库并进行修改,然后把修改代码提交到我们fork的仓库。
后面我们用fork库指代那些我们fork过来的仓库,源库指代第三方开源的仓库。
fork库和源库同步
为什么需要同步
假设我们fork的一个仓库,做了一些修改,并提交到我们fork后的仓库(后面简称fork库)。过了些时间第三方库的作者fix了一些bug或者优化了性能,也提交到他的仓库(后面简称源库)。我们发现我们需要保留fork库上修改的代码 ,但是同时需要同步源库最新代码。(如我们修改是为了定制一些功能和第三方库跟新不冲突。当然如果你的改动只是为了fix一个bug,第三方库把这个bug fix了,我们就可以删除fork了。)
如何同步
下面主要介绍利用SoreceTree 同步git仓库。只要两个仓库有一个相同的基点可以rebase就行(不必非要是fork的仓库) 。
下面会提到:
- MLLabel(源库) 源库,在别人仓库上(https://github.com/molon/MLLabel.git)
- SourceMLLabel 本博客操作时源库的备份,因为源库随时可能升级,为了保证和截图统一特意做了一个备份。也就是在写这个博客时候源库的copy(既特定时刻的源库)。(https://github.com/upworldcjw/SourceMLLabel.git)
- OldForkMLLabel 若干年/月前的fork库的备份。(https://github.com/upworldcjw/OldForkMLLabel.git)
- MLLabel(fork库同步后) 若干年/月前的fork库,然后同步一源库的修改。这个是我们最终同步的结果。(https://github.com/upworldcjw/MLLabel.git)
如果还不是很明白他们的关系,可以用SoreceTree clone下来看看。
我们可以把fork库和源库的同步过程理解如下:
** fork库 + 源库 => fork库**,fork库即是输入,也是输出。为了可以清晰的看到同步前的源库 。我特意做了一个fork库同步前备份(copy库)即OldForkMLLabel库。SourceMLLabel库是MLLabel(源库)的一个copy(时间点基于写博客时)。所以后面
我做介绍的时候基本上是基于OldForkMLLabel(fork后修改一些东西) + SourceMLLabel(源库升级了) 两个库来做演示。
下面用 OldForkMLLabel 模拟fork库,用SourceMLLabel模拟源库;
forkGitURL指代https://github.com/upworldcjw/OldForkMLLabel.git
sourceGitURL指代https://github.com/upworldcjw/SourceMLLabel.git
clone fork库
git clone forkGitURL
![](https://img.haomeiwen.com/i1668119/ff291c71378f2a7a.png)
图1-2的源URL 输入forkGitURL
![](https://img.haomeiwen.com/i1668119/8887c98fd2c7d325.png)
图1-3标记的是基于fork库(当时最新代码),做了修改,并提交到fork库。
![](https://img.haomeiwen.com/i1668119/93db629cfb01a0cc.png)
clone 源库
点击 红色标记1(设置)->点击红色标记2(远程仓库)->点击红色标记3(添加)->点击确定,弹出图2-2。
![](https://img.haomeiwen.com/i1668119/b120795ec7c6affc.png)
在图2-2的红色框标记处填上sourceGitURL,其他默认就行。然后点击确定。会弹出图2-3。
![](https://img.haomeiwen.com/i1668119/014a5cbf16db009f.png)
图2-3中 红色框标记1为forkGitURL,红色标记2为sourceGitURL,核对后无误,就点击确定,进入图2-4。
![](https://img.haomeiwen.com/i1668119/fb71bfb35688ca2c.png)
在图2-4中,右键单击SourceMLLabel,选中从SourceMLLabel拉取
![](https://img.haomeiwen.com/i1668119/e702398665a3fdde.png)
操作完之后SourceMLLabel右侧有个小三角,点击小三角,显示如下图,
![](https://img.haomeiwen.com/i1668119/6bb7a21faee79379.png)
双击SourceMLLabel的master分支,拉取代码,对应本地分支名称为:source_master由于区别和fork库的master分支
![](https://img.haomeiwen.com/i1668119/9da20dfbe21cb786.png)
代码拉取完之后显示界面如下,红色框的标记为。fork库所没有的代码即为源库后来更新的代码。这部分代码,我们也想把它同步到fork库。下面我们将展示如何把这部分代码同步的我们的fork库。
![](https://img.haomeiwen.com/i1668119/effe8bce413dc2dc.png)
rebase
双击选中图3-1的红色框标记的master分支
![](https://img.haomeiwen.com/i1668119/15f74d736c64fc3f.png)
右键单击source_master分支,然后选中将当前变更变基到source_master
![](https://img.haomeiwen.com/i1668119/0f1fc7a0b15d7a5d.png)
如果fork库的修改和源库更新没有冲突会直接进入图3-6。否则会弹出3-3弹框。
![](https://img.haomeiwen.com/i1668119/fff33b5bba9f089c.png)
在图3-3的弹框中点击确定,然后我们解决冲突完之后,点击红色框标记1(提交),后面会弹出图3-5
![](https://img.haomeiwen.com/i1668119/84bd96fa19212988.png)
在图3-5中选中继续变基,然后界面更新为图3-6
![](https://img.haomeiwen.com/i1668119/c39c168ac2c38243.png)
![](https://img.haomeiwen.com/i1668119/5a789a1dc3b2d1da.png)
提交新的分支
图3-6中的master分支(本地master分支)中可以看出,源库的更新代码已经出现在master分支,我们在fork库的跟新也出现在最上面那部分。现在我们如何把master分支同步到我们的fork库(这里指OldForkMLLabel库)?
- 方式一 把图3-6蓝色选中的master 修改名称为masterUpdate,然后推送到origin(即OldForkMLLabel远端)
- 方式二 强制删除origin(即OldForkMLLabel远端) 的master,然后把master推送到origin(即OldForkMLLabel远端)
实际操作中方式二存在问题,OldForkMLLabel远端的master强制删除不成功。
写在后面
利用方式一虽然实现了代码的同步(但是推到一个新的分支),但是没发把更新的代码提交到fork库的master远端分支。其实理想的情况是把更新代码提交到master分支,暂时还没有好的解决办法。先写到这,有好办法之后再更新吧