Git submodule & pull request ! 让我们啃下这块骨头!
实际上submodule 与 pull request,并没有什么直接关系。
比如一些团队采用code-review的方式进行协作,那么他们可能只用到pull request。
这里之所以放在一起,是因为很多场景用到了其中一个,就少不了另一个。
那么,什么情况下我们需要用到 submodule 和 pull request呢?!
假设我们的项目是用git来管理,这时我们需要添加一个第三方库的源码(以下简称lib),而这个lib,也是通过git来管理。
这种情况,一般有两种选择:
- 把lib的源码复制到我们的项目中,把它作为当前项目的源码进行管理。
- 通过git clone的方式,把lib整个放到我们的项目中(保留它自身的git信息),作为git的submodule。
这两种方式各有利弊,接下去就来好好分析一下。
方式1—只复制源码
第一种方式对于项目自身的管理来说,非常简单,没有引入额外的概念。
如果我们需要修改第三方库的功能,直接改就可以了。
但这种方式在以下几种情况,会显得非常糟糕:
更新lib的源码到最新版本
如果我们已经在自己的项目仓库对这lib进行了很多修改。
然后某一天,lib的官方github发布了许多非常有用的更新,那这时候的合并工作,就必须得借助第三方工具。为lib贡献自己的代码
当我们在使用lib时,发现了一个bug,并解决了。我们很难把修复这个bug的commit,告诉官方的github。
有悖开源的目的。
所以接下去,本文将着重介绍方法2的操作方式!!!
方式2—submodule & pull request
方式1中遇到的问题,通过采用 submodule 就可以很好的解决,但是submodule本身特别绕。
所以本文将以我的博客仓库作为案例来分析。
背景介绍
博客主题是一个独立的模块,所以我有以下两个仓库,theme作为blog的submodule来管理。
- 我的博客仓库为 xtutu/blog.git
- 博客的主题仓库 xtutu/theme.git ===> fork from official/theme.git
这里可以看到xtutu/theme.git 是一个从官方仓库 fork出来的分支!
xtutu/blog.git储存在我们自己的git仓库里.(所以仓库的前缀是xtutu/)。
如果你对submodule、pull request 都有一定了解,可以直接看2.4的小结内容!!!
那里有我目前的操作流程!
submodule 部分
添加 submodule
1 | # clone blog仓库到本地 |
注意!!!
blog仓库中的 theme 文件夹下面的内容并没有提交到blog仓库,而是只提交了一个空的theme目录。
可以理解为:在blog.git中,只记录了submodule的状态,而不是实际内容!
从图中可以看到,blog仓库会记录submodule,对应在theme仓库中的commit id
对submodule进行git操作
1 | # Administrator at USER-20160613SI in /f/blog on git:master o [14:18:52] |
切换到theme下面之后,执行的各种git操作(包括cmmit、push等),都是只针对 xtutu/theme.git进行的。
这与普通的git操作并没有什么不同。
但需要这注意的是:对theme.git执行了修改操作之后,blog.git会察觉到theme文件夹的commit id发生了变化!
所以需要在blog仓库中,进行一次常规的commit,用于提交 submodule 状态修改!
同步一个包含submodule的仓库
1 | $ git clone xxxxxxx/blog.git blog2 |
注意!!!
默认clone下来的submodule不属于任何branch,处于游离状态,所以一定要记得执行下面的操作!
1 | # Administrator at USER-20160613SI in /f/blog2 on git:master o [14:45:37] |
当最后一条命令执行完毕之后,可以在命令行上看到。我们已经进入到了master分支!
小结
了解了上面这些内容之后,使用submodule应没什么太大问题了。
但是方式1提到的两个问题,还是没有涉及到!
接下去的内容就是来解决这两个问题。
pull request 部分
pull request 大致浏览
下面的内容,实际上和submodule已经没有任何关系。
pull request & update 等操作,都是针对于 xutut/theme.git 以及 official/theme.git (原始的官方仓库)。
- 进入xtutu/theme.git主页,如图所示
- 点击pull request
从图中可以看到,当我们点击Create pull request之后,就会把自己仓库的修改提交到official/theme.git。
准确的说:应该是发起一个提交的请求。最后由官方仓库的拥有者,觉得是否接受提交。
但是在这个页面会列出所有的修改,包括不是用于修复这个bug的commit!
所以如果我们只是想pull request一个(或者几个)修复bug的commit,而不是所有的commit。那该怎么做呢?!
我在搜索资料的时候大致看了下,用cherry-pick命令应该可以完成这一效果。不过这里不采用这种方式
pull request的正确姿势
在自己的仓库中,新建一个专门用于修复这个bug的branch。
当这个bug修复了之后,我们再通过网页,在这个branch上 pull request!
这样pull request里面的commit全都是为了修复这个bug而提交的。
当然了,不管最后官方仓库,要不要接受这个pull request。
我们自己使用的xtutu/theme.git master分支,都可以把这个修复bug的分支合并过来!(就是普通的merge操作,相信大家都已经很熟悉了)
注意事项
我们用于pull request的的分支,最好更新到official/theme.git的最新状态,并保持HEAD一致(git rebase & reset命令)!再进行提交!
下面就讲一讲如何从official/theme.git 拉取最新的状态。
同步官方仓库的最新修改
1 | # 添加一个新的远程仓库 |
这里做的就是普通的merge操作,不同之处在于是从一个新的remote上进行merge。
小结
我目前的做法是在xtutu/theme.git中,一直保存着2个分支。
master:针对自己的需求,进行的所有修改,都会提交到这里
比如在现有主题上,更改显示效果,添加自己的信息等。latest-from-upstream: 永远与官方的master保持一致!
该分支主要用于创建 执行pull request操作的 分支,该分支要保持干净。
(注意:该分支不是为了创建pull reqeust,而是为了创建(执行pull request操作的)分支)
保持干净是为了:在pull request时,避免出现不相干的commit id。
当需要提交一个新的pull request时,可以执行以下操作。
1 | $ git checkout latest-from-upstream |
最后的最后
写了这么多,大家在用的时候肯定还会遇到不少问题。不过了解了上面这些知识点,再去搜索下,应该可以比较容易的解决。
上面的操作流程,也只是我自己摸索出来的方式,如果有更好的建议,可以给我留言,大家一起讨论。
最后,附上一张截图:这是我采用这种方式,给hexo-theme-next提的一个pull request。
哈哈哈,成功merge!
转载本站文章请注明作者(xtutu)和出处 xtutu