这是我参与更文挑战的第2天,活动详情查看: 更文挑战
使用场景
基于公司的项目会越来越多,常常需要提取一个公共的类库提供给多个项目使用,但是这个library怎么和git在一起方便管理呢?
在平时的软件开发过程中常常会有这样的场景,自己负责的某个模块会依赖其他模块或者第三方的library。这时你自己的模块是一个独立的代码仓库,你想要实现这样一种功能,当你从你的模块的代码仓库里把代码拉到本地来的时候,能自动的将你依赖的模块或第三方库都拉到指定的目录当中去。
我们需要解决下面几个问题:
- 如何在git项目中导入
library库? library库在其他的项目中被修改了可以更新到远程的代码库中?- 其他项目如何获取到
library库最新的提交? - 如何在clone的时候能够自动导入
library库?
解决以上问题,可以考虑使用git的 Submodule来解决。
什么是 Submodule
git Submodule 是一个很好的多项目使用共同类库的工具,他允许类库项目做为repository,子项目做为一个单独的git项目存在父项目中,子项目可以有自己的独立的commit,push,pull。而父项目以Submodule的形式包含子项目,父项目可以指定子项目header,父项目中会的提交信息包含Submodule的信息,再clone父项目的时候可以把Submodule初始化。
具体用例
目前有一个模块A,其代码仓库的地址为:demo_project_A.git, 它需要引用另一个模块B, 其代码仓库的地址为:module_B.git。
新增 submodule
假设模块A的本地目录为:demo_project_a
希望引用模块B为模块A的子模块,其在模块A目录下的路径为: demo_project_a/module_b
➜ submodule_test ll
total 0
drwxr-xr-x 5 mervinwang staff 160B 5 24 14:24 demo_project_a
➜ submodule_test tree
.
└── demo_project_a
├── README.md
└── module_b
└── README.md
2 directories, 2 files
这里我们通过 git 的submodule机制来实现。
比如在命令行里可以直接使用如下命令:
➜ submodule_test cd demo_project_a
➜ demo_project_a git:(master) ✗ git submodule add http://159.75.195.153/root/module_b.git module_b
添加位于 'module_b' 的现存仓库到索引
注: 这个submodule的 子目录指定时不能以 “/”结尾, 比如上面的命令,就不能写成 projectB/ 这个样子
就这么简单的一句git命令就可以搞定了,当然这还没完,运行完这个命令之后,在projectA目录执行git status命令,可以看到如下的结果:
➜ demo_project_a git:(master) ✗ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
要提交的变更:
(使用 "git restore --staged <文件>..." 以取消暂存)
新文件: .gitmodules
新文件: module_b
这时需要使用git commit命令和git push命令,将添加模块B为模块A的子模块的结果push到模块A的代码仓库里面去。
➜ demo_project_a git:(master) ✗ git commit -m "add module_b"
[master 831e9ee] add module_b
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 module_b
➜ demo_project_a git:(master) git push origin master
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 12 个线程进行压缩
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 379 字节 | 379.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
To http://159.75.195.153/root/demo_project_a.git
01d8e53..831e9ee master -> master
克隆 submodule
1 clone 仓库demo_projecy_A
[~/Tencent/Code/submodule_test]$ git clone http://159.75.195.153/root/demo_project_a.git
Cloning into 'demo_project_a'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), 544 bytes | 136.00 KiB/s, done.
[~/Tencent/Code/submodule_test]$ ls
demo_project_a
[~/Tencent/Code/submodule_test]$ tree
.
└── demo_project_a
├── README.md
└── module_b
2 directories, 1 file
此时,submodule module_b中文件为空
[~/Tencent/Code/submodule_test]$ cd demo_project_a
[~/Tencent/Code/submodule_test/demo_project_a]$ git submodule init
Submodule 'module_b' (http://159.75.195.153/root/module_b.git) registered for path 'module_b'
[~/Tencent/Code/submodule_test/demo_project_a]$ git submodule update
Cloning into '/Users/mervinwang/Tencent/Code/submodule_test/demo_project_a/module_b'...
Submodule path 'module_b': checked out 'da5cef17a5e650135f77466fce3cdfda3fdcaae9'
[~/Tencent/Code/submodule_test/demo_project_a]$ tree
.
├── README.md
└── module_b
└── README.md
1 directory, 2 files
删除 submodule
-
删除目录文件
[~/Tencent/Code/submodule_test]$ cd demo_project_a [~/Tencent/Code/submodule_test/demo_project_a]$ ls README.md module_b [~/Tencent/Code/submodule_test/demo_project_a]$ rm -fr module_b [~/Tencent/Code/submodule_test/demo_project_a]$ rm -fr .gitmodules -
删除config
vim .git/config [submodule "module_b"] url = http://xxxxxxx/root/module_b.git -
删除submodule相关的内容,然后提交到远程服务器
[demo_project_a] git commit -a -m 'remove module_b submodule' master ✗ [master 9be913f] remove module_b submodule 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 module_b [demo_project_a] git push master Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Delta compression using up to 12 threads Compressing objects: 100% (1/1), done. Writing objects: 100% (2/2), 241 bytes | 241.00 KiB/s, done. Total 2 (delta 0), reused 0 (delta 0), pack-reused 0 To http://159.75.195.153/root/demo_project_a.git 831e9ee..9be913f master -> master