GitHub Action使用rebase更新上游子模块冲突问题咨询
问题原因
1. 浅克隆确实是核心诱因
actions/checkout@v2默认执行浅克隆,仅拉取最近1次提交,子模块也默认采用浅拉取模式。你本地仓库是完整克隆,持有全量提交历史,git可以正常判断文件修改的继承关系,执行rebase时不会出现异常。而浅克隆环境下git缺少足够的历史信息,无法识别文件的修改脉络,会将两边同路径的正常文件误判为双方新增的冲突文件,也就是你看到的大量CONFLICT (add/add)报错。
2. 步骤逻辑冗余导致行为和本地不一致
你在Action中先执行了git submodule update --recursive --remote --merge --init --rebase,这个命令本身就会尝试将子模块同步到对应远程分支的最新提交,还附带了合并/变基参数,这个步骤在浅克隆环境下直接触发了冲突。而你本地操作时并没有执行这一步,是直接进入子模块拉取上游代码变基,两边执行的命令本身就不一样,自然运行结果不同。
修复方案
- 关闭浅克隆,拉取完整提交历史
修改actions/checkout配置,新增fetch-depth: 0拉取主仓库完整历史,checkout完成后补充子模块的完整历史拉取:
- uses: actions/checkout@v2 with: ref: '15.0' submodules: true fetch-depth: 0 ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} persist-credentials: true - name: 拉取子模块完整历史 run: | git submodule foreach --recursive git fetch --unshallow || true git submodule foreach --recursive git checkout 15.0
如果子模块体积过大,也可以根据你的提交间隔设置合理的拉取深度,比如fetch-depth: 100,只要覆盖两次更新之间的提交数即可。
删除冗余的子模块更新步骤
直接删掉Update submodules from origin对应的整个步骤,你后续已经会手动进入子模块拉取上游代码变基并推送到自己的fork仓库,不需要提前执行这步子模块更新操作,避免无意义的合并冲突。优化子模块操作逻辑(可选)
可以把重复的子模块上游配置、拉取、变基操作改成循环,同时避免remote重复添加的报错:
- name: 更新子模块并推送 run: | git config --global user.name 'bot' git config --global user.email 'bot@users.noreply.github.com' # 按 子模块路径:上游仓库地址 格式配置要更新的子模块 SUB_MODULES=("src/odoo:git@github.com:odoo/odoo.git" "src/enterprise:git@github.com:odoo/enterprise.git") for item in "${SUB_MODULES[@]}"; do sub_path=${item%%:*} up_url=${item##*:} cd $sub_path git remote add upstream $up_url || git remote set-url upstream $up_url git fetch upstream 15.0 git rebase upstream/15.0 git push origin 15.0 cd - done git add . git commit -m "[SUB] odoo/enterprise" || echo "No changes to commit" git push origin 15.0
内容的提问来源于stack exchange,提问作者Andrius
相关产品推荐
相关产品推荐

