GitSubmodule使用说明

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

使用场景

基于公司的项目会越来越多,常常需要提取一个公共的类库提供给多个项目使用,但是这个library怎么和git在一起方便管理呢?

在平时的软件开发过程中常常会有这样的场景,自己负责的某个模块会依赖其他模块或者第三方的library。这时你自己的模块是一个独立的代码仓库,你想要实现这样一种功能,当你从你的模块的代码仓库里把代码拉到本地来的时候,能自动的将你依赖的模块或第三方库都拉到指定的目录当中去。

我们需要解决下面几个问题:

  • 如何在git项目中导入library库?
  • library库在其他的项目中被修改了可以更新到远程的代码库中?
  • 其他项目如何获取到library库最新的提交?
  • 如何在clone的时候能够自动导入library库?

解决以上问题,可以考虑使用git的 Submodule来解决。

什么是 Submodule

git Submodule 是一个很好的多项目使用共同类库的工具,他允许类库项目做为repository,子项目做为一个单独的git项目存在父项目中,子项目可以有自己的独立的commitpushpull。而父项目以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
    复制代码