CI作业推送代码至仓库遇「stale data」等问题求助
问题
我尝试通过GitLab CI作业修改文件后将变更推送回代码仓库,配置如下:
changelog: stage: release variables: GIT_DEPTH: 100 before_script: - git config user.name "$GITLAB_USER_NAME" - git config user.email "$GITLAB_USER_EMAIL" - git remote remove $CI_PROJECT_NAME || true - git remote add $CI_PROJECT_NAME https://oauth2:$CI_ACCESS_TOKEN@$CI_SERVER_FQDN/$CI_PROJECT_PATH.git script: - < make my changes > - git add . - git commit --amend --no-edit - git push $CI_PROJECT_NAME HEAD:$CI_COMMIT_BRANCH -o ci.skip --dry-run --force-with-lease
未添加--force-with-lease时,收到报错:
Updates were rejected because a pushed branch tip is behind its remote
添加该参数后,收到报错:
[rejected] HEAD -> my-branch (stale info)
CI作业是基于分支最新提交运行的,为什么创建本地提交后会认为本地分支落后于远程?该如何解决?
原因分析
git commit --amend的特性:--amend会替换当前分支的最新提交,生成一个全新的提交哈希。此时远程分支上还是原来的旧提交,本地与远程的提交历史出现分叉,Git会判定本地分支"落后"。- 浅克隆的限制:配置中
GIT_DEPTH: 100是浅克隆,本地仓库没有完整的远程分支提交历史。当推送修改后的提交时,Git无法正确对比完整提交链,容易触发"stale info"错误。 --force-with-lease的校验逻辑:该参数会检查远程分支的当前提交是否与本地记录的远程分支提交一致。由于你修改了提交哈希,本地记录的旧提交哈希和远程实际的最新提交(虽和你初始拉取的是同一个,但本地已替换为新哈希)不匹配,因此被判定为"stale info"拒绝推送。
解决方法
方案1:创建新提交而非修改现有提交(推荐)
如果允许分支新增提交,修改CI脚本:
changelog: stage: release variables: GIT_DEPTH: 100 before_script: - git config user.name "$GITLAB_USER_NAME" - git config user.email "$GITLAB_USER_EMAIL" - git remote remove $CI_PROJECT_NAME || true - git remote add $CI_PROJECT_NAME https://oauth2:$CI_ACCESS_TOKEN@$CI_SERVER_FQDN/$CI_PROJECT_PATH.git script: - < make my changes > - git add . - git commit -m "Automated update via CI" - git pull $CI_PROJECT_NAME $CI_COMMIT_BRANCH --rebase - git push $CI_PROJECT_NAME HEAD:$CI_COMMIT_BRANCH -o ci.skip
git pull --rebase会将你的新提交放在远程最新提交之后,避免历史分叉-o ci.skip可避免触发新的CI流水线,防止循环执行
方案2:强制推送修改后的提交(谨慎使用)
如果必须修改现有提交(比如更新变更日志到当前提交),按以下步骤调整:
- 取消浅克隆:移除
GIT_DEPTH配置,或设置为0以拉取完整仓库 - 修改CI脚本的推送逻辑:
changelog: stage: release # 移除GIT_DEPTH或设置为0 # variables: # GIT_DEPTH: 0 before_script: - git config user.name "$GITLAB_USER_NAME" - git config user.email "$GITLAB_USER_EMAIL" - git remote remove $CI_PROJECT_NAME || true - git remote add $CI_PROJECT_NAME https://oauth2:$CI_ACCESS_TOKEN@$CI_SERVER_FQDN/$CI_PROJECT_PATH.git - git fetch $CI_PROJECT_NAME $CI_COMMIT_BRANCH script: - < make my changes > - git add . - git commit --amend --no-edit - git push $CI_PROJECT_NAME HEAD:$CI_COMMIT_BRANCH -o ci.skip --force
- 注意:
--force会直接覆盖远程分支的提交历史,仅在确认无其他开发者同时修改该分支时使用,避免丢失他人变更
内容的提问来源于stack exchange,提问作者jeremywat
相关产品推荐
相关产品推荐

