美文网首页
git submodule

git submodule

作者: 老虎爱吃母鸡 | 来源:发表于2017-07-06 00:27 被阅读0次

目的

  1. 分开管理
  2. 如果是添加公共的库到当前项目中,比起直接复制代码,submodule能追踪上游的更新

添加submodule

git submodule add <repository> [<path>]

添加后会多一个.gitmodules文件,文件的内容只是保存submodule的引用信息,包括路径和repo地址

[submodule "simple-todos"]
    path = simple-todos
    url = git@github.com:GuoQichen/simple-todos.git

添加完后需要在主项目git commit提交新增子项目文件夹以及.gitmodules文件的修改

在子项目加入到项目的时候,其实做了这样三件事:

  1. 记录引用的子项目仓库,在.git/config
  2. 记录当前项目中子项目的目录位置,在生成的.gitmodules
  3. 记录子项目的commit id

所以在当前项目push到remote repository的时候,只是更新了引用的commit id,那么在其他人clone项目的时候,就可以获取子项目的commit id,然后在git submodule update的时候获取子项目commit id所表示的commit

clone带有submodule的项目

查看子模块的commit id,如果子模块没有被checkout,前面会有-,那么就需要git submodule initgit submodule update

git submodule
// result
b6bf4d6a6cbaaff39e4e4d4f3108d16267354844 simple-todos (heads/master)
// or
-b6bf4d6a6cbaaff39e4e4d4f3108d16267354844 simple-todos (heads/master)

clone带有submodule的项目的两种方法:

  1. 第一种
git clone <repository>
git submodule init
git submodule update
  1. 第二种
git clone <repository> --recursive

其实相当于

git submodule update --init --recursive

注意,在clone之后,cd submodule/,然后git status,你会看到这样的状态

HEAD detached at b6bf4d6
nothing to commit, working tree clean

也就是说,现在是detached HEAD,使用git branch就可以查看到

> * (HEAD detached at b6bf4d6)
> master

所以需要git checkout master到master分支,然后在master分支上修改

为什么呢?因为父项目不记录子模块的修改,只记录commit id,所以clone的时候只获取到对应的commit,而不在任何分支上,但是master分支的commit id和HEAD保持一致,所以只要git checkout master,而不需要新建分支

修改submodule

注意:只有子项目内容更新,就需要更新父项目引用的子项目的commit id

其实子项目和父项目只是独立的git项目,所以其他操作和一般git项目一样,在子项目修改,需要

cd submodule/
git add .
git commit - m 'xxx'
git push

其实普通的git项目一样操作,然后需要在父项目更新引用的子项目commit id,有一种方法:

  1. git submodule update
    但是现在的子模块指向的不是master分支,而是commit id表示的commit,所以还需要
cd submodule/
git checkout master
// todo

为什么这种方法不行呢,其实是个坑!就是你git submodule update之后,你的子项目会恢复到你父项目引用的那个commit,也就是不是最新的commit,此时git status是干净的,就像第一次git clone项目然后git submodule initgit submodule update一样,子项目指向的是父项目引用的那个commit,所以此时把子项目git checkout master之后,再切回到父项目,使用git status,你会发现提示子项目有新的commit,所以还是需要父项目更新引用的子项目的commit id

  1. 在父项目更新引用的子项目commit id
git commit -m 'update submodule commit id'
git push

更新submodule

注意:如果更新submodule的时候有新的commit id产生,需要在父项目产生一个提交,用来更新对子项目commit id的引用
两种方法:

  1. git submodule foreach git pull
    直接在父项目运行,这样能一次性把所有子项目都更新
  2. 到子项目中去更新
cd submodule/
git pull

总结

子项目一旦产生变动,有新的commit id,父项目必需产生一个提交,更新对子项目commit id的引用

参考

Git Submodule使用完整教程
使用Git Submodule管理子模块
Git submodule的坑

相关文章

网友评论

      本文标题:git submodule

      本文链接:https://www.haomeiwen.com/subject/galchxtx.html