分享 Fork 开源项目之后

tiseheaini · 2014年08月23日 · 最后由 allenfantasy 回复于 2014年08月27日 · 4261 次阅读

github 上面有很多我们能用的开源代码,比如开源的社区代码,clone 下来跑一下,放到自己的服务器上。

过一段时间会对代码删删改改,可之前代码作者也在提交新的代码,两个代码仓库在 clone 下来那一刻就注定没办法走到一起了,话虽是这么说,可并不是说两个分支就从此路人了。代码还是能相互借鉴一下。

上面图是两个分支,两个分支都有提交新的代码,如果在这时把两个分支合并,冲突文件会特别多,相同一个文件会被修改多次。

无论是 Linux 还是 Git,得一即可得天下。 -- 池建强 http://zhuanlan.zhihu.com/mactalk/19796979

这是题外话,我想说的是,linus 有先见之明,在设计 Git 时就帮我们想好了解决方法。 git 可以给代码打补丁,我们可以把其他仓库的代码生成很多补丁,然后把补丁代码添加到自己的仓库中。ps: 关键字 git patch

git 补丁的基本原理就是把两次提交中的改动部分在分支上重新提交一次。

###git 有两种格式的 patch

####使用 git diff 生成标准的 patch

比较上图中 git init0.1 version 两个 commit 中得不同

$ git diff 61343f9..94ce1b5

diff --git a/views/index.erb b/views/index.erb
index ea5c291..5f414c8 100644
--- a/views/index.erb
+++ b/views/index.erb
@@ -7,7 +7,7 @@
   <link rel="stylesheet" href="style/normalize.css" media="all">
   <link rel="stylesheet" href="style/index.css" media="all">
   <link rel="stylesheet" href="style/small.css" type="text/css" media="screen and (max-width:768px)" />
-  <script src="script/jquery.min.js"></script>
+  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
   <script src="script/main.js"></script>
 </head>
 <body>

输出的内容就是一个补丁文件。

执行 git diff 61343f9..94ce1b5 >> patch.txt 生成一个文件就能将生成的补丁保存下来。

我们使用 git apply 来应用这个补丁

git apply patch.txt
git commit -am "Patch Apply"

git 标准 patch 就是将别人的提交内容装到 git 缓存区,然后重新提交一次。git diff 生成的 patch 还有一个好处就是将多次提交使用 git diff 生成一个 patch 文件,然后一次性提交就完成了。

git format-patch 生成的 git 专用补丁

还是比较上图中 git init 和 0.1 version 两个 commit 中的不同

git format-patch 61343f9..94ce1b5 

命令会生成一个 0001-jquery-cdn.patch 文件这个文件和之前 git diff 生成的文件作用是一样的,只是格式不同,当然使用补丁的方式也不一样,git 专用格式的补丁需要使用 git am 命令。

执行 git am 0001-jquery-cdn.patch 来应用这个补丁。 看看 git log 是不是多了一次提交。如果有冲突需要使用 google 解决。

###结语 两个方式中比较推荐使用git format-patch,由于 git format-patch 生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。因此,目前使用 Git 的开源社区往往建议大家使用 format-patch 生成补丁。

EOF

http://tise.c2qu.com/index.php/2014/08/21/27.html

[1]: http://tise.c2qu.com/usr/uploads/2014/08/3738176363.jpg

官方推荐的方法是用 rebase 或者 merge

用 rebase 或者 cherrypick 一般我会设置两个 remote,一个是 origin,另一个是 upstream,fetch upstream 就可以监视源的变动了

#1 楼 @letho
#2 楼 @jasl
rebase 之前用过,不过觉得过程不够清晰,刚开始时用这种方法比较容易明白原理。 而且 rebase 会把所有的改动提交进仓库,使用 patch 添加容易控制代码,把不希望改动的代码舍弃掉。 对于跟进一个仓库,我觉得使用 patch 的方式更合适。

#3 楼 @tiseheaini 如果这个需求的话 cherrypick 更优雅一些,可以把某个提交单独插过来

#4 楼 @jasl 这样的话一定要学习一下 cherrypick

Git 开发速度很快 各种新特性 来不及学啊

#6 楼 @iBachue 正在关注 Rei 的 Campo 需要了解如何跟进开源项目,用的到就学,用不到的先放一下

关键的关键是 upsteam 改动要及时拉下来,origin 改动要及时 PR,补丁或者 cherrypick 只是官方不接受你的 PR 的补充。

#8 楼 @ericguo 你理解错了,我是在 Campo 基础上更改,但不想错过原仓库的改动,并不是提交代码到 github

#9 楼 @tiseheaini 那就应该严格区分应该递交到 upstream 的修改和自己的定制,自己的定制尽量少,然后及时拉 upsteam 的 master,然后 rebase 自己的修改 branch 到 master

小步多次的 merge master 加上 cherry-pick 是比较好的办法吧~

需要 登录 后方可回复, 如果你还没有账号请 注册新账号