git push 是什么
git push 把本地提交送到远端仓库并更新远端分支引用。默认行为由 push.default 决定,simple 模式下只推当前分支到它的上游同名分支;还没建立跟踪关系的新分支首次推送会报错,需要显式写出远端与分支。推送是唯一会改动远端的日常操作,误推的代价比误提交高,所以推送前先确认会推什么。
推送为什么会被拒
被拒通常分两类:一类是远端已有你本地没有的提交,Git 报 non-fast-forward 或 fetch first,正确做法是先 fetch 再集成;另一类是权限与规则问题,例如分支受保护、需要评审通过才能合入、或账号没有写权限。强推只能解决历史分叉这一种情况,用错场景会把别人的提交覆盖掉。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git push [选项] [远端] [本地引用:远端引用] |
| 默认行为 | push.default=simple,只推当前分支到上游同名分支 |
| 常用参数 | -u 建立跟踪;--dry-run 演练;--tags 推标签;--delete 删远端分支 |
| 高危参数 | --force / --force-with-lease,覆盖远端历史 |
| 是否需要网络 | 是,必须能访问远端仓库 |
典型使用场景
- 提交后同步:把本地提交推给远端,供协作者与流水线取用
- 首次推送新分支:用 -u 同时建立跟踪,之后可直接 git push
- 演练确认:加 --dry-run 先看会推哪些引用再执行
- 发布版本:用 --tags 或指定标签名把版本标签推上去
- 清理远端分支:合并完成后用 --delete 删掉已合入的功能分支
- 变基后覆盖:改写历史后用 --force-with-lease 安全覆盖远端
常用示例
常用示例
git push # 推送当前分支到上游
git push origin main # 显式指定远端与分支
git push -u origin feature/login # 首次推送并建立跟踪
git push origin HEAD:refs/heads/review # 推到另一个远端分支名
git push --dry-run # 演练,不真正推送
git push origin --tags # 推送全部未上传的标签
git push origin --delete feature/login # 删除远端分支
git push --force-with-lease origin feature # 变基后的安全强推常见推送结果
| 输出 | 含义 | 处理 |
|---|---|---|
| Everything up-to-date | 远端已是本地状态 | 无需动作 |
| rejected non-fast-forward | 远端有本地没有的提交 | 先 fetch 集成,不要直接强推 |
| src refspec does not match | 分支名写错或本地无此分支 | 用 git branch 核对名称 |
| remote: Permission denied | 无写权限或凭据失效 | 检查密钥、令牌与仓库权限 |
| protected branch declined | 受保护分支禁止直推 | 改走 PR 或 MR 合入流程 |
| new branch 提示 | 同时新建了远端分支 | 用 -u 建立跟踪关系 |
新分支推送一次后建议立刻建立跟踪(-u)。有了上游关系,git status 会显示领先落后数,之后直接执行 git push 语义清晰,不易推错目标。
强推会覆盖远端的提交。优先用 --force-with-lease:它只在远端仍是你上次看到的位置时才覆盖,能挡住「别人刚推了新提交」这种最常见的丢代码场景。
推错分支且尚未合并时,可用 git push origin --delete <分支> 删掉远端分支再重推,前提是账号对该分支有删除权限。
推送的对象是提交,不是工作区文件。改动必须先 commit 才有可推的内容;未提交的本地改动不会随 push 出现在远端。
推送前值得核对的两件事
推送前建议做两步核对:用 git log origin/main..HEAD --oneline 看看这次究竟会推哪些提交,用 git status -sb 确认当前分支的领先与落后数。前者能发现误提交或漏提交,后者能发现本地已经落后于远端,避免在过期的基线上继续开发。分支越多人共用,这两步越省事。
如果远端分支在你上次 fetch 之后已被其他人更新,推送会先被拒绝,这其实是保护机制。按提示先 fetch 集成,再推送,比事后用强推修补安全得多。