git 子模块应用

目录

单项目组子模块应用

项目添加子模块

Clone带有Submodule的仓库

修改Submodule

更新主项目的Submodules

总结

针对单一项目不同成员对子模块的修改步骤如下:

针对单一项目不同成员对子模块同步到最新步骤如下:

假如有另外一个项目project2也要用到lib1和lib2

子模块删除


单项目组子模块应用

../../../_images/image-20200924140745352.png

项目添加子模块

现在项目组人员A要为project1工程添加lib1和lib2作为其子模块

【project1 目录】
git submodule add [要添加子模块的远程仓库地址]  [本地路径]

eg:
# 为工程project1添加lib1子模块,并提交远程仓库
git submodule add  ../../repos/lib1.git  libs/lib1 

git commit -a -m "project1 新增lib1子模块"

git push



此时在project1目录下会有个.gitmodules文件,用来记录子模块信息,内容如下:

[submodule "libs/lib1"]
	path = libs/lib1
	url = ../../repos/lib1.git

	

Clone带有Submodule的仓库

现在项目组人员B要clone下progect1带有子模块的项目,并存放在project1-B目录下

方法一:
git clone ../repos/project1.git project1-B
cd project1-B
git submodule
git submodule init
git submodule update

方法二:
git clone --recursive ../repos/project1.git

修改Submodule

现在项目组人员B发现lib1里面有bug。要修复下提交,cd到libs/lib1目录后发现,HEAD处于游离状态,如下:

【project1-B 目录】
project1-B/libs/lib1 ((6e60852...))
$ git status
HEAD detached at 6e60852
nothing to commit, working tree clean

其实就算是项目组成员A在project1里面查看libs/lib1 也是一样的情况。为什么不是默认的master分支?

Git对于Submodule有特殊的处理方式,在一个主项目中引入了Submodule其实Git做了3件事情:

  • 记录引用的仓库地址
  • 记录主项目中Submodules的目录位置
  • 记录引用Submodule的commit id

在project1中push之后其实就是更新了引用的commit id, 然后project1-B在clone的时候获取到了submodule的commit id,当执行git submodule update的时候, git就获取submodule的commit id,最后获取submodule的文件,所以clone之后不在任何分支上; 但是master分支的commit id和HEAD保持一致。我们可以用git log命令查看验证下:

【project1-B/libs/lib1 目录】
$ git log
commit 6e60852976c613302f98371141bd1c36c55eb7ea (HEAD, origin/master, origin/HEAD, master)
Author: FlyRobot <xyan_m@163.com>
Date:   Thu Sep 24 09:41:35 2020 +0800

    lib1 新增readme

现在我们要修改lib1的文件需要先切换到lib1的master分支,修改后再push到远程仓库

【project1-B/libs/lib1 目录】
git checkout master
修复bug
git add .
git commit -m "developer B 修改lib1 bug"


注意:
此时如果我们查看project1-B的状态,会发现下面的提示:说明lib1有个新的提交。

【project1-B 目录】
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   libs/lib1 (new commits)

no changes added to commit (use "git add" and/or "git commit -a")


注意:如果现在在project1-B (master)工程下执行了git submodule update操作那么libs/lib1的commit id又会还原到以前的版本,

这样的话刚刚的修改是不是就丢死了呢?不会,因为lib1修改已经提交到了master分支,只要在libs/lib1 下执行git checkout master即可。


现在我们可以提交lib1的修改到远程仓库了
【project1-B/libs/lib1 目录】
cd project1-B/libs/lib1 (master)
git push 

切换到project1-B目录,把project1-B工程引用lib1的id更新到刚才提交的版本
【project1-B 目录】
git add .

git commit -m "修复lib1 bug,developer B更新 lib1 id到最新版本"

更新主项目的Submodules

项目组人员A要更新子模块内容,怎么操作

【project1 目录】
git pull
git submodule init
git submodule update

注意:当需要更新子模块的内容时请先确保已经运行过git submodule init

总结

../../../_images/image-20200924140745352.png

针对单一项目不同成员对子模块的修改步骤如下:

例如开发人员A想修改lib1子模块的内容,并提交到远端,且更新自己仓库关于lib1的到刚提交的最新版本

  • cd project1-A/lib1子模块
    • git checkout master
    • 修改内容
    • git add .
    • git commit -m “日志”
    • git push
  • cd project1-A
    • git add .
    • git commit -m “修改子模块id”
    • git push

针对单一项目不同成员对子模块同步到最新步骤如下:

例如开发人员A提交了lib1到远程仓库,开发人员B想同步下来:

  • cd project1-B
  • git pull
  • git submodule init
  • git submodule update

假如有另外一个项目project2也要用到lib1和lib2

../../../_images/image-20200924140651748.png

情景1:现在项目开发人员C在自己的project2-C下修改了lib1子模块,并提交到远端。如果同项目组的开发人员D向同步下项目组人员C提交的关于lib1的修改,上面已经讲到如何更新(git pull、 git submodule init 、git submodule update)。

情景2:假如现在另外一个项目组的开发人员A想同步下lib1的最新版本,此时A和C根本处于两个项目组,我们不可能在project1-A项目里面执行git pull、 git submodule init 、git submodule update了。

此时项目组progect1开发人员A操作步骤如下:

  • cd project1-A/lib1
  • git checkout master
  • git pull
  • cd project1-A
  • git add .
  • git commit m “拉取最新的lib1”
  • git push #推送到远端

试想一下,如果项目中有N个子模块,我们难道都要一一的执行上面操作完成子模块的更新吗,显然很不现实。故而,我们可以下面的命令完成所有子模块的更新。

git submodule foreach git pull

该命令意思是:递归去找该项目下的所有子模块,并拉取最新的代码到本地,一行命令搞定,是否很爽。

不过需要注意的是:项目本身需要再次执行git add .、 git commit才能把项目中刚更新到最新版本的子模块id给记住。

子模块删除

假如要删除项目progect1-A里面的lib1子模块

../../../_images/image-20200924145201944.png

步骤如下:

  • cd progect1-A
  • git rm -r –cached lib1
  • rm -rf lib1
  • 删除掉.gitmodules关于lib1的内容
  • 删除.git/config的submodule配置关于 lib1内容
  • 删除.git/modules的关于 lib1内容
  • 提交本次修改即可
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值