Git 试用 submodule 管理子项目
- 1 准备事项
- 1.1 安装git
- 1.2 配置用户名和邮箱
- 1.3 仓库位置
- 2 主仓库引入子仓库
- 2.1 初始化子仓库
- 2.2 引入子仓库到主仓库中
- 2.3 删除外部的项目
- 3 修改子项目更新后本地主仓库
- 3.1 更新子项目
- 3.2 更新主仓库
- 4 如何同步别人的更改
- 4.1 当其他人更新了子项目(未更新主项目)
- 4.2 当其他人更新了子项目(并更新了主项目)
- 4.3 当其他人新增了子项目
- 5 在新的电脑上克隆主仓库
这两天学习了一下git的submodule子项目管理功能,记录一下学习的东西。
以下示例都是在win的powershell中,linux下一样
1 准备事项
1.1 安装git
win: 下载安装官网的git
centos: yum install git
ubuntu: apt install git
1.2 配置用户名和邮箱
打开powershell
# 配置用户名
git config --global user.name "myname"
# 配置邮箱
git config --global user.email "mymail@139.com"
1.3 仓库位置
仓库的初始化位置,我这里测试时都是全新建的空仓库。
- 主仓库: git@git.myserver.cn:project_name
- 子仓库1: git@git.myserver.cn:library1
- 子仓库2: git@git.myserver.cn:library2
2 主仓库引入子仓库
只需要第一次运行一次即可。
2.1 初始化子仓库
这里的初始化不是git init命令这种初始化。由于将子仓库添加到主仓库中需要确保子仓库不是空仓库,所以需要在子仓库中随便添加一些东西,让他不为空。其实根本原因可能是git init的仓库没有分支,所以无法添加,这里生成一个文件并推送,以确保远程仓库上主分支存在。
所以,如果你的子仓库不是空的,就不需要这一步。
# 找一个位置来存放git仓库,比如我的电脑上为 E:\git
# 进入git目录
cd E:\git
# 克隆子仓库
git clone git@git.myserver.cn:library1 library1
# 进入子仓库目录
cd library1
# 随意生成一个名为 init 的文件
echo 'init' > init
# git 暂存文件
git add .
# git 提交更改
git commit -m 'init'
# git 更新到远程服务器
git push
以上便实现了克隆library1仓库,添加了名为 init 的文件,并推送到远程服务器。然后需要做的是将library1仓库添加到主仓库中
2.2 引入子仓库到主仓库中
# 克隆主仓库
git clone git@git.myserver.cn:project_name project_name
# 进入主仓库
cd project_name
# 将library1仓库引入主仓库
git submodule add git@git.myserver.cn:library1 library1
# 如果子项目为空, 会无法添加到索引, 需要更新子项目不为空, 然后在这里的子项目pull后, 再运行 submodule add
# 更新主仓库
# 查看git状态
git status
# git 暂存变更信息
git add .
# git 提交更改
git commit -m '添加子项目 library1'
# git 推送到远程服务器
git push
以上便实现了将子项目引入到主仓库中。
2.3 删除外部的项目
由于已经将项目添加进了主仓库中,之前克隆的子仓库(E:\git\library1)可以删除了。当然这个随便了。
3 修改子项目更新后本地主仓库
这里指的是直接在主项目中修改。
在主仓库中的子项目,也可以作为一个独立的仓库看待,所以一般的add、commit、push操作都正常进行。然后再在主仓库中进行更新操作。
3.1 更新子项目
子项目路径为 E:\git\project_name\library1
,子项目的更新方法与常规的操作一致。
# 进入子项目
cd E:\git\project_name\library1
# 查看当前分支状态 *号标明的为当前所在分支
git branch -v
# 确保当前不在一个 detached 的分支下 我这里切换到主分支 再在主分支下进行一系列操作
git checkout master
# 这里作演示随便生成一个文件
echo 'test' > test.txt
# push三连
git add .
git commit -m '测试'
git push
这样完成了子项目的更新。
3.2 更新主仓库
# 返回主仓库目录
cd E:\git\project_name
# 查看状态
git status
# 暂存仓库变化
git add .
# 提交
git commit -m '更新子仓库引用'
# 推送到远程
git push
# 查看更新后的状态
git status
我这里提示信息如下
PS E:\git\project_name\library1> git commit -m 'update git submodule '
[master 1c4b134] update git submodule
1 file changed, 1 insertion(+)
PS E:\git\project_name\library1> git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
To git.myserver.cn:project_name/library1
7271e29..1c4b134 master -> master
PS E:\git\project_name\library1> cd ..
PS E:\git\project_name> git add .
PS E:\git\project_name> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: library1
PS E:\git\project_name> git commit -m 'update submodule library1'
[master af2a40f] update submodule library1
1 file changed, 1 insertion(+), 1 deletion(-)
PS E:\git\project_name> git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 252 bytes | 252.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
To git.myserver.cn:project_name
27deb61..af2a40f master -> master
4 如何同步别人的更改
当其他人更新了子项目后 或者 添加了新的子项目,如何同步自己这边的主仓库。
4.1 当其他人更新了子项目(未更新主项目)
使用git submodule foreach
命令。这个命令其实就是加在常规的git命令前面,表示是对每个子项目执行,所以一般git操作前面都可以加这个前缀
# 进入主仓库目录
cd E:\git\project_name
# 切换子项目的分支为 master
git submodule foreach git checkout master
# 获取所有子项目的更新
git submodule foreach git pull
# 查看主仓库状态
git status
# 暂存主仓库变化
git add .
# 提交
git commit -m 'update sub repo'
# 推送主仓库的变化到远端
git push
4.2 当其他人更新了子项目(并更新了主项目)
# 进入主仓库目录
cd E:\git\project_name
# 获取主仓库的更新
git pull
# 更新submodule引用
git submodule update
4.3 当其他人新增了子项目
比如有人新增了子项目 library2
# 进入主仓库目录
cd E:\git\project_name
# 拉取主仓库的更新信息,主项目不会同步子项目的内容,所以目录 library2 为空
git pull
# 同步library2的内容
git submodule update --init
运行提示信息如下
PS F:\git\project_name> git submodule update --init
Submodule 'library2' (git@git.myserver.cn:library2) registered for path 'library2'
Cloning into 'F:/git/project_name/library2'...
Submodule path 'library2': checked out '00f77e54a94c7a2803f6d36e2c7cdd7c29cf22a6'
5 在新的电脑上克隆主仓库
在新的电脑上使用,先确定一个仓库存放的位置,比如存放到 F:\git
中。
# 创建一个git目录
mkdir F:\git
# 进入git目录
cd F:\git
# 克隆 main 主仓库到本地的 project_name 目录
git clone git@git.myserver.cn:project_name project_name
# 进入主仓库
cd project_name
# 初始化并更新子项目
git submodule update --init
我的提示信息如下
PS F:\git\project_name> git submodule update --init
Submodule 'library1' (git@git.myserver.cn:project_name/library1) registered for path 'library1'
Submodule 'library2' (git@git.myserver.cn:project_name/library2) registered for path 'library2'
Cloning into 'F:/git/project_name/library1'...
Cloning into 'F:/git/project_name/library2'...
Submodule path 'library1': checked out 'a7fc9483a7b982e8f6529fc12b69dba5479508ae'
Submodule path 'library2': checked out '00f77e54a94c7a2803f6d36e2c7cdd7c29cf22a6'
目前能想到的场景就这么多。以后如果遇到新的再来更新。
子项目只需要添加一次,后面的日常更新主要参考3 4 5这几部分。
完毕。