如何正确使用git submodule复用Spring核心应用避免合并冲突
方案可行性结论
该方案完全可落地,相比你当前使用的多remote分支合并流程,能彻底解决coreApp迭代同步时的大量合并冲突问题。只要严格遵守「不直接修改子模块目录内容」的规则,既可以实现coreApp版本的快速同步,也能通过Maven配置支持两套源码、资源目录的正常构建与Spring上下文加载。
落地操作步骤
- 第一步:清理旧流程遗留内容
先移除之前配置的coreApp关联远程仓库,清理历史合并到当前项目src目录下的coreApp通用代码(这部分代码统一移回coreApp独立仓库维护),确保当前项目无coreApp相关的路径残留:git remote remove coreapp - 第二步:引入coreApp作为Git子模块
在新项目根目录执行命令,将coreApp仓库作为子模块存放到独立路径(示例使用core-app作为目录名,注意不要和项目自身业务代码路径重名):git submodule add <coreApp仓库Git内网地址> core-app
执行完成后根目录会自动生成.gitmodules配置文件,记录子模块路径与远程仓库映射关系。其他开发人员拉取新项目代码后,只需执行git submodule update --init --recursive即可拉取对应版本的coreApp代码。 - 第三步:配置Maven构建规则,支持双源码目录打包
通过Maven多模块+构建插件配置,让构建流程同时扫描项目自身和coreApp子模块的源码、资源文件:- 在项目根pom.xml的
<modules>节点添加子模块引用:
<modules> <module>core-app</module> </modules>- 引入build-helper插件,将coreApp的源码、资源目录加入构建路径,可根据实际目录结构调整路径值:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.5.0</version> <executions> <execution> <id>add-core-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>core-app/src/main/java</source> </sources> </configuration> </execution> <execution> <id>add-core-resource</id> <phase>generate-resources</phase> <goals> <goal>add-resource</goal> </goals> <configuration> <resources> <resource> <directory>core-app/src/main/resources</directory> </resource> </resources> </configuration> </execution> </executions> </plugin>- 若新项目启动类的根包路径与coreApp根包路径无上下级包含关系,需要在启动类的
@ComponentScan注解中显式添加coreApp的根包,保证coreApp中的Spring Bean能被正常扫描注册。
- 在项目根pom.xml的
- 第四步:规范日常开发与版本同步流程
日常业务开发仅在项目自身的src目录下编写代码,禁止修改core-app子模块目录下的任何文件,所有通用能力迭代全部在coreApp独立仓库完成提交。需要同步coreApp最新迭代版本时,进入子模块目录拉取对应分支的最新代码,回到项目根目录提交子模块指针变更即可,整个过程不会产生合并冲突:cd core-app git checkout master git pull cd .. git add core-app git commit -m "chore: 同步coreApp最新迭代版本"
注意事项
- 禁止直接在子模块目录提交代码修改,否则会触发子模块detached HEAD异常,所有coreApp的变更必须走coreApp独立仓库的提交流程
- 构建过程中如果出现同路径同名类、同名配置文件冲突,Maven会优先生效新项目自身路径下的文件,可利用该特性直接覆写coreApp的默认逻辑,无需侵入修改coreApp源码
- CI/CD流水线配置时,需要在代码拉取步骤后增加
git submodule update --init --recursive命令初始化子模块,否则会因缺失coreApp源码导致构建失败 - coreApp自身的依赖配置可在根pom的
<dependencyManagement>节点中统一管理版本,避免依赖版本冲突
内容的提问来源于stack exchange,提问作者Slobodan Margetić
相关产品推荐
相关产品推荐

