Github Action从staging分支推送代码到prod分支失败求助
我配置了一个GitHub Action,当代码推送到staging分支时触发,先运行测试,测试通过后想把staging分支的代码推送到prod分支,但一直失败。
我的GitHub Action配置
name: Test and Deploy on: push: branches: - staging jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.10' cache: 'pip' # caching pip dependencies - name: Start Redis uses: supercharge/redis-github-action@1.5.0 - name: Update pip run: pip install --upgrade pip - name: Install requirements.txt run: pip install -r requirements.txt - name: Install test requirements run: pip install pytest pytest-cov sanic-testing==22.12.0 aiosqlite==0.18.0 - name: Test with pytest run: pytest tests deploy: needs: test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Deploy to prod run: | git push -u origin prod
遇到的错误情况
直接执行git push -u origin prod时的错误
error: src refspec prod does not match any
error: failed to push some refs to 'https://github.com/myproject/repo'
先执行git checkout -b prod后的错误
Switched to a new branch 'prod'
From https://github.com/myproject/repo
- branch prod -> FETCH_HEAD
- [new branch] prod -> origin/prod
fatal: refusing to merge unrelated histories
尝试git checkout -b prod && git pull origin prod && git push -u origin prod的错误
Run git checkout -b prod git checkout -b prod git pull origin prod
git push -u origin prod shell: /usr/bin/bash -e {0} Switched to a
new branch 'prod' From https://github.com/myproject/repo * branch
prod -> FETCH_HEAD * [new branch] prod ->
origin/prod hint: You have divergent branches and need to specify how
to reconcile them. hint: You can do so by running one of the following
commands sometime before hint: your next pull: hint: hint: git
config pull.rebase false # merge hint: git config pull.rebase truerebase hint: git config pull.ff only # fast-forward only hint: hint: You can replace "git config" with "git config --global"to set a default hint: preference for all repositories. You can also
pass --rebase, --no-rebase, hint: or --ff-only on the command line to
override the configured default per hint: invocation. fatal: Need to
specify how to reconcile divergent branches. Error: Process completed
with exit code 128.
尝试git checkout -b prod && git push -u origin prod的错误
git checkout -b prod git push -u origin prod shell:
/usr/bin/bash -e {0} Switched to a new branch 'prod' To
https://github.com/myproject/repo ! [rejected] prod -> prod
(fetch first) error: failed to push some refs to
'https://github.com/myproject/repo' hint: Updates were rejected
because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same
ref. You may want to first integrate the remote changes hint: (e.g.,
'git pull ...') before pushing again. hint: See the 'Note about
fast-forwards' in 'git push --help' for details.
疑问
请问我哪里操作有误?
核心问题分析
- 直接push失败:默认
actions/checkout@v3只拉取触发分支(staging),本地没有prod分支的引用,所以git push origin prod找不到对应分支。 - 创建新prod分支后push失败:如果远程已存在prod分支,本地新建的prod分支和远程prod分支无共同提交历史,导致无法合并推送;若远程无prod分支,新建后推送本应成功,但你的场景是远程已有prod分支且历史不关联。
修正后的Action配置
要实现staging到prod的单向同步,正确操作如下:
deploy: needs: test runs-on: ubuntu-latest steps: - name: 全量拉取代码 uses: actions/checkout@v3 with: fetch-depth: 0 # 拉取所有分支及完整历史,默认仅拉取当前分支最新提交 - name: 配置Git身份 run: | git config --global user.name "GitHub Actions" git config --global user.email "actions@github.com" - name: 同步staging到prod分支 run: | # 检查远程是否存在prod分支 if git ls-remote --exit-code --heads origin prod; then # 远程存在prod分支,切换后重置为staging最新状态 git checkout prod git reset --hard origin/staging else # 远程不存在prod分支,从staging创建新分支 git checkout -b prod staging fi # 强制推送到远程prod分支 git push -f origin prod
关键说明
fetch-depth: 0:必须配置,否则本地无法获取prod分支的历史信息。git reset --hard origin/staging:强制将prod分支同步为staging的最新状态,适合无自主修改的prod分支场景;若prod有独立修改,需改用合并并处理冲突(但通常staging到prod是单向发布)。-f参数:重置后需强制推送,确保远程prod分支完全对齐staging。- 配置Git身份:GitHub Action运行时需设置用户信息,否则git操作会因身份验证失败报错。
内容的提问来源于stack exchange,提问作者Cyril N.

