主分支设为只读是平台级保护机制,强制通过PR合并保障质量;push失败因远程拦截而非Git本身限制;正确流程为功能分支开发→发起PR→CI通过+审批→自动合并;冲突需在本地解决并强制推送更新分支;发版依赖合并触发CI及推送tag。

主分支(如 main 或 master)设为只读后,你无法直接 git push 到它,必须走合并流程——这不是限制,而是强制保障代码质量的机制。
为什么 git push origin feature-x:main 会失败
错误信息通常是 remote: error: branch 'main' is protected 或 ! [remote rejected] main -> main (protected branch)。这不是 Git 本身报错,而是托管平台(GitHub/GitLab/Bitbucket)在服务端拦截了写操作。即使你本地能切到 main、能 git commit、能 git merge,只要远程分支启用了保护规则,git push 就会被拒绝。
- 保护规则由仓库管理员在平台设置中开启,常见于
Settings → Branches → Branch protection rules - 触发条件包括:禁止 force-push、要求 PR 审查、要求状态检查通过、禁止直接推送
- 本地
git push失败时,不会产生任何远程变更,也不会污染本地历史
正确提交流程:从开发到上线的四步闭环
核心逻辑是「改在功能分支 → 合并进主分支 → 平台自动执行保护动作」。所有操作都绕过直接推送主分支的需求。
- 在本地基于
origin/main新建功能分支:git checkout -b feature/login - 编码 →
git add→git commit -m "feat: add login modal" - 推送到远程功能分支:
git push origin feature/login - 在 GitHub/GitLab 页面上发起 Pull Request(或 Merge Request),目标分支选
main;等待 CI 通过、至少一人 approve 后,点击Merge
注意:git merge 本地操作对受保护分支无效——你不能先 git checkout main && git merge feature/login 再 push,因为 push 这一步仍会被拦截。
遇到冲突或合并失败,该在哪解决
冲突不是出现在 git push 阶段,而是在 PR/MR 的「Mergeability」检查里暴露。平台会明确提示 “This branch has conflicts that must be resolved”。这时你要在本地解决,而不是在网页上点“resolve in browser”(那只是临时编辑,不等价于真实 merge)。
- 切回你的功能分支:
git checkout feature/login - 拉取最新
main:git fetch origin && git rebase origin/main(推荐 rebase,保持线性历史)或git merge origin/main(保留 merge 提交) - 解决冲突 →
git add→git rebase --continue或git commit - 强制推送更新功能分支:
git push --force-with-lease origin feature/login(仅限未被他人基于该分支继续开发时)
关键点:rebase 后必须 --force-with-lease,否则 push 会因历史不一致被拒;但若该分支已被他人用于协作开发,应改用 merge 方式避免覆盖他人工作。
CI/CD 和标签发布怎么配合只读主分支
主分支只读不等于不能发版。实际发布靠的是「合并即触发」+「打 tag」。只要 PR 合并成功,CI 流水线(如 GitHub Actions)就能监听 push 到 main 的事件,自动构建、测试、部署。发版版本号通常用 Git tag 管理:
- 合并进
main后,本地执行:git checkout main && git pull && git tag -a v1.2.0 -m "release v1.2.0" - 推 tag:
git push origin v1.2.0(tag 不受分支保护规则限制) - CI 可配置为监听
git push --tags,触发正式环境部署
容易忽略的是:tag 必须推送到远程才生效;且如果团队用语义化版本,v1.2.0 这类 tag 名不能含空格或特殊字符,否则 CI 脚本可能解析失败。


















