Git 笔记

子模块

git submodule - 子模块,允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持这两个项目提交的独立性。

比如:工作中的某个项目需要包含并使用另一个项目, 也许是第三方库,或者你独立开发的用于多个父项目的库。通过子模块就可以把它们当做两个独立的项目,同时又在一个项目中使用另一个。

常用操作

  • 添加
# 进入父级仓库中,如果想强制重新添加,可以使用参数 -f
git submodule add <submodule_url> [submodules_path]

命令执行后,会 clone submodule_urlsubmodules_path下,然后会在父仓库根目录下创建 .gitmodules 文件记录了submodule_url与本地目录之间的映射信息,如果有多个子模块,则该文件中会有多条记录。

[submodule "submodules_path/sub"]
	path = submodules_path/sub
	url = submodule_url

并且会在 .git/config文件中增加 submodule 的信息

[submodule "submodules_path/sub"]
	url = submodule_url
	active = true
  • 检出

    克隆一个含有子模块的项目后,默认只是克隆了 .gitmodules 文件和会包含该子模块目录,但其中还没有任何文件,需要执行如下命令取出子模块中的文件:

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

​ 或者一条组合命令:

# 组合命令
git submodule update --init
# 如需初始化、抓取并检出任何嵌套的子模块,可增加参数 `--recursive`
git submodule update --init --recursive
  • 更新

    子模块的维护者提交了更新后,使用子模块的项目必须手动更新才能包含最新的提交。

    在项目中,进入到子模块目录下,执行 git pull 更新,查看 git log 查看相应提交。

    完成后返回到项目目录,可以看到子模块有待提交的更新,使用git add,提交即可

  • 删除

# 如果未指定 path 或者 --all 参数,并不会删除所有而是报错,以防止误删除
# --force 参数将强制移除子模块的工作树,及时它包含了本地修改
git submodule deinit [-f|--force] (--all|[--] <path>…)
# 从工作树和索引中删除文件
git rm --cached <submodules_path/submodule_name>

​ 上述命令可以卸载一下子模块,会自动将 .git/config.gitmodules 文件中的相关子模块内容移除。

  • 克隆带有子模块的项目
# 递归克隆整个项目
git clone <repository> --recursive
  • 子模块遍历

    foreach 子模块命令,它能在每一个子模块中运行任意命令。 如果项目中包含了大量子模块,这会非常有用。

git submodule [--quiet] foreach [--recursive] <command>

​ 例如:

# 拉取所有子模块
git submodule foreach git pull
# 创建一个新分支,并将所有子模块都切换过去
git submodule foreach 'git checkout -b featureA'
# 生成一个主项目与所有子项目的改动的统一差异
git diff; git submodule foreach 'git diff'

参考

git stash用法总结 - 收手吧阿祖 - 博客园 (cnblogs.com)

发表评论