使用git子模块实现代码复用

Git Submodule

在做不同的项目,但是又都会使用到一些常用的方法组件代码块等等。
作为一个追求优雅的开发人员,肯定不能接受一段代码到处复制粘贴的操作。而且一旦这段代码日后需要更新,到处粘贴的话就需要全局搜索然后含泪修改了。
那么有没有一种办法,能够作为一些公共代码的“栖息地”,可以做到一处编写,到处使用呢?

答案是有的,使用git内置功能submodule即可。

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。
Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

新建SubModule

要为父仓库添加子仓库,首先你需要创建父仓库和子仓库。
将父仓库克隆至本地:

 git clone https://gitee.com/xiaomumaozi/SubModule_Test.git

然后使用命令添加:

//git submodule add <仓库地址> <本地路径>
git submodule add https://gitee.com/xiaomumaozi/SubModule.git src/SubModule

添加成功后,在项目src目录中能够看到新增的文件夹SubModule。

SubModule

另外新增了文件.gitmodules,在里面增加了对SubModule的一些描述。

SubModule

除此之外,执行命令

cat .git/config

可以发现在父仓库的git 配置文件(.git/config)中加入了submodule段。

SubModule

到这里新增SubModule就完成了。

  • clone有SubModule的项目

如果要clone一个附带submodule的项目,submodule的文件
不会自动随父项目clone出来(其实只会clone出 .gitsubmodle 这个描述文件),
还需要执行如下命令取出submodule里的文件:

# 用来初始化本地配置文件
git submodule init
# 从该项目中抓取所有数据并检出父项目中列出的合适的提交(指定的提交)。
git submodule update

(以上两条命令也可以合并成一条组合命令:git submodule update --init --recursive)
------------------更好的方式---------------------
# clone 父仓库的时候加上 --recursive,会自动初始化并更新仓库中的每一个子模块
git clone --recursive https://gitee.com/xiaomumaozi/SubModule_Test.git

更新SubModule

在父仓库目录下git pull之后,立即执行

git status

如果发现submodule有修改,

SubModule

立即执行

git submodule update --remote

在主仓库下执行git submodule update --remote等价于进入 submodule 目录内,然后执行 git pull, 这两个操作都会把 submodule 目录中的文件更新到最新。
更复杂一些,如果你的submodule又依赖了submodule,那么很可能你需要在git pull 和 git submodule update之后,再分别到每个submodule中再执行一次git submodule update,
这里可以使用 git submodule foreach命令来实现:

git submodule foreach git submodule update

修改Submodule

有些时候你需要对submodule做一些修改,很常见的做法就是切到submodule的目录,然后做修改,然后commit和push。

这里的坑在于,默认git submodule update并不会将submodule切到任何branch,
所以,默认下submodule的HEAD是处于游离状态的(‘detached HEAD’ state)。

所以在修改前,记得一定要用

git checkout master

将当前的submodule分支切换到master,
然后才能做修改和提交。

如果你不慎忘记切换到master分支,又做了提交,可以用cherry-pick命令挽救。具体做法如下:

  • 1.用 git checkout master 将HEAD从游离状态切换到 master 分支, 这时候,git会报Warning说有一个提交没有在branch上,记住这个提交的change-id(假如change-id为 aaaa)
  • 2.用 git cherry-pick aaaa 来将刚刚的提交作用在master分支上
  • 3.用 git push 将更新提交到远程版本库中

删除子仓库

  • 1.删除.gitsubmodule里相关部分
  • 2.删除.git/config 文件里相关字段
  • 3.删除子仓库目录。

然后执行命令:

 git rm --cached <本地路径>

即可完成删除。

posted @ 2021-08-21 17:15  axl234  阅读(211)  评论(0编辑  收藏  举报