查看“Git:子模块”的源代码
←
Git:子模块
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Git]] == 关于 == 有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。 Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。 可以使用 '''<code>git submodule --help</code>''' 查看所有相关命令。 <syntaxhighlight lang="bash"> git clone <repository> --recursive //递归的方式克隆整个项目 git submodule add <repository> <path> //添加子模块 git submodule init //初始化子模块 git submodule update //更新子模块 git submodule foreach git pull //拉取所有子模块 </syntaxhighlight> == 添加 == 关联项目子模块: <syntaxhighlight lang="properties"> git submodule add https://github.com/test/subb.git modules/subb </syntaxhighlight> # 默认情况下,子模块会将子项目放到一个与仓库同名的目录中,果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径(如:modules/subb)。 项目根目录下有一个.gitmodules文件,即子模块关联文件,如: <syntaxhighlight lang="properties"> [submodule "modules/suba"] path = modules/suba url = https://github.com/test/suba.git </syntaxhighlight> 每添加一个子模块就会新增一条记录,如果是第一次添加Git子模块会自动生成。 == 克隆 == 当一个 git 项目包含子模块(submodule) 时,克隆这样的项目时,默认会包含该子模块目录,但子模块目录里面是空的。有两种方法解决: # 如果项目已经克隆到了本地,执行下面的步骤: ## 初始化本地子模块配置文件:<syntaxhighlight lang="bash"> git submodule init </syntaxhighlight> ## 更新项目,抓取子模块内容:<syntaxhighlight lang="bash"> git submodule update </syntaxhighlight> # 对于未克隆项目,使用“--recursive”参数,可以自动初始化并更新每一个子模块。 #: <syntaxhighlight lang="bash"> git clone --recursive 仓库地址 # 或者 git clone --recurse-submodules 仓库地址 </syntaxhighlight> Note: * “--recursive”,用于的嵌套(项目中的子模块,子模块中的子模块)。 * <syntaxhighlight lang="bash" inline>git submodule init</syntaxhighlight> 和 <syntaxhighlight lang="bash" inline>git submodule update</syntaxhighlight> 可以合并成一步: *: <syntaxhighlight lang="bash"> git submodule update --init # 当有子模块嵌套时: git submodule update --init --recursive </syntaxhighlight> == 更新 == 同时在主项目和子模块项目上与队员协作开发时: === 从子模块的远端拉取上游修改 === 在项目中使用子模块的最简模型,就是只使用子项目并不时地获取更新,而并不在你的检出中进行任何更改。<br/> # 如果想要在子模块中查看新工作,可以进入到目录中运行 git fetch 与 git merge,合并上游分支来更新本地代码: #: <syntaxhighlight lang="bash"> # 进入子模块目录 cd modules/suba # 拉取更新 git fetch # 合并分支 git merge origin/master </syntaxhighlight> # 如果不想在子目录中手动抓取与合并,那么可以采取另一种方式进行抓取和更新: #: <syntaxhighlight lang="bash"> git submodule update --remote <submodule_name> </syntaxhighlight> #: 此命令默认更新并检出子模块仓库的 master 分支,如果需要操作其他分支: #: 需要修改分支配置【既可以在 .gitmodules 文件中设置 (这样其他人也可以跟踪它),也可以只在本地的 .git/config 文件中设置(本地有效)】。 #: <syntaxhighlight lang="bash"> # 在.gitmodules 文件中设置,使用DbConnector模块的stable分支 $ git config -f .gitmodules submodule.DbConnector.branch stable # 拉取子模块更新 $ git submodule update --remote </syntaxhighlight> === 从项目远端拉取上游更改 === 作为主项目协作开发者来说,一般情况下会使用 git pull 来拉取项目更新,但是:'''默认情况下,git pull 命令会递归地抓取子模块的更改,然而,它不会更新子模块!'''这点可通过 git status 命令看到,它会显示子模块“已修改”,且“有新的提交”。<br/> 为了完成更新,需要运行 git submodule update: <syntaxhighlight lang="bash"> # 拉取项目更新 git pull # 更新子模块代码 git submodule update --init --recursive </syntaxhighlight> # “--init”:是为了防止 提交中有新的子模块,未初始化而不能更新 的情况; # “--recursive”:是为了 子模块中有嵌套子模块 的情况; 如果想要自动化以上过程: <syntaxhighlight lang="bash"> git pull --recurse-submodules </syntaxhighlight> # 这会让 Git 在拉取后运行 git submodule update,将子模块置为正确的状态; # 如果要让 Git 总是以 --recurse-submodules 拉取,可以将配置选项 submodule.recurse 设置为 true; 在为父级项目拉取更新时,还会出现一种特殊的情况:可能 .gitmodules 文件中记录的子模块的 URL 发生了改变(如,子模块项目改变了它的托管平台),此时,若父级项目引用的子模块提交不在仓库中本地配置的子模块远端上,那么执行 <code>git pull --recurse-submodules</code> 或 <code>git submodule update</code> 就会失败。 此时需要: <syntaxhighlight lang="bash"> # 将新的 URL 复制到本地配置中 $ git submodule sync --recursive # 从新 URL 更新子模块 $ git submodule update --init --recursive </syntaxhighlight> == 编辑 == 切换子模块到开发分支,如: <syntaxhighlight lang="bash"> cd modules/subb/ git checkout -b feature/some-change origin/dev </syntaxhighlight> 进行修改 == 推送 == 推送子模块修改到远程,如: <syntaxhighlight lang="bash"> git commit -am 'test commit submodule' git checkout dev git merge feature/some-change git push origin dev git branch -d feature/some-change </syntaxhighlight> 提交子模块修改之后,主项目会有一些修改: <syntaxhighlight lang="bash"> cd ../../ git diff > diff --git a/subb b/subb index 433859c..b78179a 160000 --- a/subb +++ b/subb @@ -1 +1 @@ -Subproject commit 433859c90e539d2a1b9fda27b32bef0d0acae9e6 +Subproject commit b78179adab252a524ff2a41d6407a7daa6dad34f </syntaxhighlight> 此时需要提交主项目该修改,才能在其他用户使用git submodule update时拉取新的代码: <syntaxhighlight lang="bash"> git commit -am "test commit submodule" git push origin dev </syntaxhighlight> == 删除 == git没有直接删除子模块的命令,所以只能逐步删除相关文件。 # 在版本控制中删除子模块: #: <syntaxhighlight lang="bash"> git rm -r modules/subb </syntaxhighlight> # 在编辑器中删除如下相关内容,也可以使用命令'''“vi .gitmodules”'''在vim中删除: #: <syntaxhighlight lang="bash"> [submodule "modules/subb"] path = modules/subb url = https://github.com/test/subb.git branch = dev </syntaxhighlight> # 在编辑器中删除如下相关内容,也可以使用命令'''“vim .git/config”'''在vim中删除: #: <syntaxhighlight lang="bash"> [submodule "modules/subb"] path = modules/subb url = https://github.com/test/subb.git active = true </syntaxhighlight> # 删除.git下的缓存模块: #: <syntaxhighlight lang="bash"> rm -rf .git/modules/subb </syntaxhighlight> # 提交修改: #: <syntaxhighlight lang="bash"> git commit -am "delete subb" git push origin dev </syntaxhighlight> == 发布项目 ==
返回至“
Git:子模块
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息