赞
踩
当程序比较大参与开发人员较多时,代码管理就复杂起来。
代码如果全员可见,可以创建share分支维护共用代码,可以创建core分支维护核心算法代码,各进程分别占一个分支,定期同步share和core分支。
代码如果不能全员可见,可以仓库中包含子仓库,子仓库管理模块代码,主仓库定时更新。
7.11 Git 工具 - 子模块
Git Submodule管理项目子模块
git clone <repository> --recursive 递归的方式克隆整个项目
git submodule add <repository> <path> 添加子模块
git submodule init 初始化子模块
git submodule update 更新子模块
git submodule foreach git pull 拉取所有子模块
我们尝试使用 Git 来维护一个项目的代码。这个项目的结构比较复杂:
项目包含由多个子模块,每个子模块是一个独立的 Git 仓库,子模块还允许继续嵌套包含子模块。 例如,主工程依赖 common、framework、react_native 等多个子模块,而 react_native 子模块又依赖 node_modules、HFCommon、HFModules 等多个嵌套子模块。
[-] app_android/
|-[+] HFUIKit
|-[+] channel
|-[+] common
|-[+] framework
|-[+] hybrid
|-[+] messagecenter
|-[-] react_native
|-[+] HFCommon
|-[+] HFModules
|-[+] node_modules
主工程和子模块允许存在多个分支,且相互之间有依赖关系。例如,主工程的 jilin 分支同时依赖 common 子模块的 master 分支,以及 framework 子模块的 jilin 分支。
Git 提供了 submodule 来支持子模块的需求,使用它可以很方便的将多个独立仓库包含到同一个主工程中:
$ git init
$ git submodule add http://xxx.xxx/common.git
$ git submodule add http://xxx.xxx/framework.git
Git submodule 还支持嵌套添加子模块:
$ git submodule add http://xxx.xxx/react_native.git
$ cd react_native
$ git submodule add http://xxx.xxx/HFCommon.git
$ git submodule add http://xxx.xxx/HFModules.git
$ git submodule add http://xxx.xxx/node_modules.git
通过子模块,这些子模块既可以各自独立的修改和提交代码,又可以将改动作用到依赖它的父工程。这听起来是个很棒的特性,然而 Git submodule 也存在着一些让人抓狂的坑。
首先,主工程并不直接跟踪子模块的代码,而仅仅只跟踪子模块的 commit id 的改动。在执行 git submodule update 更新子模块代码时,Git 就是根据主工程所维护的 commit id 来更新子模块到指定状态的。
bash-3.2$ git diff react_native
diff --git a/react_native b/react_native
index 3a9c5b1..ad68a28 160000
--- a/react_native
+++ b/react_native
@@ -1 +1 @@
-Subproject commit 3a9c5b14c45b199e2e6863d2b6da22dabc2a54f5
+Subproject commit ad68a28c13d4196df531c7df8523d07358288297
(END)
因此,如果你只在子模块中修改并提交了代码,而没有到主工程上面再把子模块的 commit id 提交一下,其他人拉取工程代码的时候会发现子模块的代码依然停留在老的 commit id 所指向的状态。对于嵌套子模块,这种工作尤为繁琐,提交代码后要逐层往上提交 commit id ,否则其他人无法正确更新代码。
其次,如前面所说,使用 git submodule update 更新子模块后,子模块将被切换到一个指向父工程维护的 commit id 所指定的游离状态:
bash-3.2$ git submodule update react_native
bash-3.2$ cd react_native
bash-3.2$ git branch
* (detached from 3a9c5b1)
master
jilin
TaiShan
一旦代码处于游离分支,你就要时刻警惕在游离分支上的提交有没有即时合并到非游离分支上。如果你直接在游离分支上开发并提交了代码,之后在父工程里再次 git submodule update ,你所有未合并的提交都会丢失!
最后还有一个非常麻烦,但也极容易出现的问题:如果团队里有人只提交了主工程该子模块的 commit id ,却忘了进入该模块提交模块真正的代码,那么当推送到中央仓库之后,其他人就会因为找不到与该 commit id 对应的代码而无法正确更新代码:
bash-3.2$ git submodule update
error: pathspec 'ad68a28c13d4196df531c7df8523d07358288297' did not match any file(s) known to git.
Did you forget to 'git add'?
Unable to checkout 'ad68a28c13d4196df531c7df8523d07358288297' in submodule path 'react_native'
对于熟练的用户,这些坑自然可以轻松越过。但考虑到团队里大都是 Git 新手,我们发现子模块的引入对他们造成了很大的负担,频繁出现子模块代码没有更新到最新状态,或者更新出错的情况。
子模块的维护者提交了更新后,使用子模块的项目必须手动更新才能包含最新的提交。
在项目中,进入到子模块目录下,执行 git pull更新,查看git log查看相应提交。
完成后返回到项目目录,可以看到子模块有待提交的更新,使用git add,提交即可。
有时子模块的项目维护地址发生了变化,或者需要替换子模块,就需要删除原有的子模块。
删除子模块较复杂,步骤如下:
rm -rf 子模块目录 删除子模块目录及源码
vi .gitmodules 删除项目目录下.gitmodules文件中子模块相关条目
vi .git/config 删除配置项中子模块相关条目
rm .git/module/* 删除模块下的子模块目录,每个子模块对应一个目录,注意只删除对应的子模块目录即可
执行完成后,再执行添加子模块命令即可,如果仍然报错,执行如下:
git rm --cached 子模块名称
git remote update
git rev-parse origin/master:PathToSubModule
// suppose we get this 6b7ad40e8287d7e452c29e0e2cffa0d46e49f077
git ls-files --stage PathToSubModule
// 160000 8ad2765f410bbac1805ca931cb5abcf8b3986c15 0 SubModuleName
// done the job
git update-index --add --cacheinfo 160000 6b7ad40e8287d7e452c29e0e2cffa0d46e49f077 SubModuleName
[submodule "xxx"]
url = git@github.com:zzz/xxx.git
active = false
ignore = all
之后的 git submodule 操作都会忽略掉 xxx 项目了。
这些配置可以通过 git help config 来找到,比如搜索 submodule..ignore。
from:「IOT物联网小镇」的原创文章
事情发生在功能机的时代,我们项目组开发一款手机,软件开发成员大概有 20 人左右吧。结果在手机发布的一周后,另一家小厂就推出了软件界面、功能几乎完全一样的手机,除了开机界面。
因为那个时代,大家几乎都是使用 MTK、高通提供的解决方案,都是统一的菜单式功能,你没法拿出有力的证据来说明别人偷窃了你的代码。
后来内部查明,的确是有开发人员把代码泄漏出去了,于是后来所有的电脑上 USB 口全部被禁掉了。
这是我亲身经历的真实故事,当时每个人负责一个模块,比如:A 负责通话管理和电话簿,B 负责系统设置,C 负责短信和彩信。。。在编译的时候,是需要所有的代码放在一起,统一编译的,这也就意味着所有的软件人员都可以拿到全部源代码,这也就为代码泄漏埋下了隐患,出现了这次严重的事件,毕竟人为财死、鸟为食亡!
现在项目中,都强调要分层、分模块,这是从软件工程的角度来考虑的。如果再进一步, 把这些模块都划分为一个小的子系统**,每个开发人员只负责自己的模块,并且只能有权限拉取自己的代码**,这样他就没法获取到一个项目中所有模块的代码了。
只有项目整合人员(管理员),才有全部权限来拉取所有源代码来构建整个系统,这样的话,就可以对代码的安全问题有更好的掌控了。
要实现这样的代码管控,使用 git 工具中的 submodule 就可以完成。
1、7.11 Git 工具 - 子模块
2、子模块相关操作
3、Git 管理实践(一):多分支子模块依赖管理
4、Git Submodule管理项目子模块
5、子模块相关操作
6、git中submodule子模块的添加、使用和删除
7、git submodule没有权限时如何更新到某个提交
8、使用Jenkins + git submodule 实现自动化编译,解决代码安全性问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。