GitHub显示可自动合并但Actions执行Rebase时出现冲突的排查
问题描述
部署分支落后开发分支(dev)2个提交,GitHub显示该分支可自动合并,但在GitHub Actions工作流中执行Rebase操作时出现冲突。
工作流配置如下:
jobs: rebase: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 with: ref: deployment ssh-key: ${{secrets.SSH_PRIVATE_KEY}} - name: Rebase UAT onto main run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git fetch origin dev git rebase origin/dev
本地执行git rebase origin/dev可成功完成,但Actions runner中出现如下错误:
Auto-merging .github/workflows/main.yml CONFLICT (add/add): Merge conflict in .github/workflows/main.yml warning: Cannot merge binary files: .pnp.cjs (HEAD vs. 1806843 (Deployment specific commit)) Auto-merging .pnp.cjs CONFLICT (add/add): Merge conflict in .pnp.cjs warning: Cannot merge binary files: .pnp.loader.mjs (HEAD vs. 1806843 (Deployment specific commit)) ...
原因分析
- 合并与Rebase的冲突逻辑不同:GitHub显示的「可自动合并」是针对merge操作的检测,它找最近公共祖先做三方合并;而Rebase是把当前分支的提交逐个重演到dev分支顶端,线性重放的过程可能触发merge不会遇到的冲突。
- 本地与Runner环境差异:本地可能已经处理过
.pnp.cjs这类二进制文件的跟踪规则,或者配置了自动忽略其冲突,但Actions Runner是全新环境,没有这些本地配置,Rebase时就会触发冲突。 - Checkout不完整:
actions/checkout@v3默认只拉取单个分支的最新提交,没有完整仓库历史,Rebase时Git缺少足够的上下文,导致合并逻辑异常。
解决方法
方法一:拉取完整仓库历史
修改Checkout步骤,添加fetch-depth: 0拉取全量历史,让Rebase有足够的上下文:
- name: Checkout code uses: actions/checkout@v3 with: ref: deployment ssh-key: ${{secrets.SSH_PRIVATE_KEY}} fetch-depth: 0 # 拉取完整仓库历史
方法二:配置二进制文件合并策略
在工作流中添加Git配置,让Git自动处理二进制文件的冲突,直接采用dev分支的版本:
- name: Rebase deployment onto dev run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" # 全局配置二进制文件合并策略为保留目标分支版本 git config --local merge.binary.driver "true" git fetch origin dev git rebase origin/dev
也可以在仓库根目录添加.gitattributes文件并提交,永久生效:
echo ".pnp.cjs merge=binary" >> .gitattributes echo ".pnp.loader.mjs merge=binary" >> .gitattributes
方法三:改用Merge替代Rebase
既然GitHub显示可自动合并,直接用Merge操作替换Rebase,避开线性重放的冲突:
- name: Merge dev into deployment run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git fetch origin dev git checkout deployment git merge origin/dev --no-ff git push origin deployment
内容的提问来源于stack exchange,提问作者David Min
相关产品推荐
相关产品推荐

