# 子模块 开发个人网站的过程中需要用到主题仓库,所以会在一个仓库的里面嵌套另一个仓库,如果直接将子仓库加入版本管理,很多文件无法进行版本化,所以想到了子模块的操作 ## 创建子模块 使用`git submodule`命令添加子模块 $ git submodule add git@github.com:zjZSTU/hexo-theme-next.git blogs/themes/next Cloning into 'blogs/themes/next'... remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 5402 (delta 0), reused 0 (delta 0), pack-reused 5401 Receiving objects: 100% (5402/5402), 5.29 MiB | 1.03 MiB/s, done. Resolving deltas: 100% (3294/3294), done. Checking connectivity... done. 除了添加子仓库之外,还生成了一个配置文件`.gitmodules` $ git status On branch dev Your branch is ahead of 'origin/dev' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: (use "git reset HEAD ..." to unstage) new file: .gitmodules new file: blogs/themes/next `.gitmodules`里面保存了子模块的地址和远程仓库链接 $ cat .gitmodules [submodule "blogs/themes/next"] path = blogs/themes/next url = git@github.com:zjZSTU/hexo-theme-next.git ## 管理子模块 主仓库只能提示子模块中的文件修改,必须子模块自己进行添加和上传 比如在`next`文件夹内新建文件`hellogit` # 对于主模块而言 $ git status On branch dev Your branch is up-to-date with 'origin/dev'. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) (commit or discard the untracked or modified content in submodules) modified: next (untracked content) no changes added to commit (use "git add" and/or "git commit -a") # 对于子模块而言 $ git status HEAD detached at 0c5ed6f Untracked files: (use "git add ..." to include in what will be committed) hellogit nothing added to commit but untracked files present (use "git add" to track) ## 克隆子模块 克隆主仓库后子模块的文件夹在但是没有文件,还需要进一步克隆子仓库 # 初始化本地配置文件 $ git submodule init # 拉取远程仓库 $ git submodule update 集成代码如下: $ git submodule update --init --recursive ## 更新子模块 如果子模块有更新,可以进入子模块路径进行更新 $ git pull 或者在主仓库更新所有子模块 $ git submodule foreach git pull 可能会遇到如下错误: ``` Entering 'blogs/themes/next' You are not currently on a branch. Please specify which branch you want to merge with. See git-pull(1) for details. git pull Stopping at 'blogs/themes/next'; script returned non-zero status. The command "git submodule foreach git pull" failed and exited with 1 during . ``` 需要指定哪个分支,要么修改更新语句如下: ``` $ git submodule foreach git pull origin master ``` 要么设置远程关联分支 ``` $ git branch --set-upstream-to=origin/remote_branch your_branch # 或 git branch --set-upstream your_branch origin/remote_branch ``` ## 忽略子模块 参考:[submodule..ignore ](https://git-scm.com/docs/gitmodules#Documentation/gitmodules.txt-submoduleltnamegtignore) 当在子模块执行完成修改提交后,在主模块仍会显示子模块待提交 ``` $ git status On branch dev Your branch is up-to-date with 'origin/dev'. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: blogs/themes/next (new commits) ``` 需要修改`.gitmodule`的`ignore`属性,用于定义何种情况下使用`git status`或者`diff`命令会显示子模块的修改状况 有`4`个可选的属性值 1. `all`:子模块永远不会被认为是已修改的(但是当它处于暂存阶段时仍旧会在状态和提交命令的输出中) 2. `dirty`:子模块工作树上的所有改变都会被忽略,只考虑子模块的`HEAD`与其在父项目中记录的状态之间的差异 3. `untracked`:仅仅子模块未追踪的文件会被忽略。对于已追踪文件的提交差异和修改会显示 4. `none`:默认选项。不会忽略所有对于子模块的修改,会显示所有的对于提交差异以及对于已追踪或未追踪的文件修改 所以设置属性`ignore`为`all`就能忽略子模块变化 ``` [submodule "blogs/themes/next"] path = blogs/themes/next url = https://github.com/zjZSTU/hexo-theme-next.git ignore = all ``` ## 相关阅读 * [7.11 Git 工具 - 子模块](https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97)