把本地仓库第一次推到 Origin,失败点基本集中在三处:远程名(通常叫 origin)绑的地址不对、本地分支和远端目标分支名不一致、凭证或分支权限被拦。这三件事都能用命令回显验证,所以关键动作不是反复重试 push,而是先把它们各自确认一遍,再决定要不要推、往哪推。
第一次推送可以按这个顺序走:用 git status 和 git branch 确认本地状态与当前分支,用 git remote add 加远程、git remote -v 核对地址,用 git push -u <远程名> <分支名> 明确推送目标,最后用 git ls-remote 或远端页面反查引用是否真的出现。认证失败和分支被拒是两类不同错误,凭证问题换对凭证再试,分支被拒要改的是提交历史或权限,重试不会有不同结果。
在本地确认仓库状态和当前所在分支
cd 到仓库根目录后先执行 git status。干净工作区的回显大致是:
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
看到 working tree clean,说明没有未提交改动,本次 push 传的是已经存在的提交,内容可预期。如果回显里出现 Changes not staged for commit 或 Changes to be committed,需要清楚这些改动不会被本次 push 带上——push 只传提交对象,不传工作区。要么先 commit,要么明确接受远端暂时不包含这部分内容。
如果 git status 直接报 fatal: not a git repository (or any of the parent directories): .git,说明当前目录还不是 Git 仓库,先 git init,再按后面的步骤走。接着确认当前分支:
$ git branch
* main
dev
带星号的是当前所在分支。这一步的意义在于:后面 push 时写错分支名,推上去的就是另一个分支的内容。首次推送前执行 git branch -a 通常也只能看到本地分支,远程跟踪分支要等推送成功或 fetch 之后才出现。
添加远程并核对远程名与地址
远程名约定用 origin,但不是强制。添加时把地址换成你自己的仓库地址:
git remote add origin git@github.com:yourname/yourrepo.git
添加之后不要直接 push,先核对一遍:
$ git remote -v
origin git@github.com:yourname/yourrepo.git (fetch)
origin git@github.com:yourname/yourrepo.git (push)
fetch 和 push 两行应当指向同一个仓库。如果两行地址不同,说明单独配过 pushurl,或地址被改过,需要确认哪一行才是真正写入的位置。如果执行 git remote add 时报 error: remote origin already exists,不要重复添加,先 git remote -v 看现有地址;要改址用:
git remote set-url origin git@github.com:yourname/newrepo.git
只想改推送地址时用 git remote set-url `--push` origin <新地址>。修改后再执行一次 git remote -v 复核,确认回显已经更新。
确认默认分支名与推送目标分支
本地分支叫 master、远端平台默认分支叫 main,或者反过来,是第一次推送最常见的对不上。先看本地分支名,再决定推到远端哪个名字。常规写法:
git push -u origin main
本地是 master、远端要落到 main 时,写明“本地:远端”:
git push -u origin master:main
-u 即 `--set-upstream`,成功后会把本地分支与远端分支的跟踪关系写进配置。执行成功后的回显里,有两行值得确认:
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
[new branch] 表示远端之前没有这条分支、这次新建了;set up to track 表示跟踪关系已建立,之后直接 git push 即可。如果报错是 failed to push some refs 并提示 non-fast-forward,通常说明远端已经有提交(例如建仓库时生成了 README),此时先 git fetch origin,再把远端提交合并或变基到本地,不要在同一个命令上反复重试。
推送后用远端状态反查是否真的成功
命令行没报错,只说明这次请求被远端接受了,不代表你正在浏览的那个仓库页面上出现了这条分支。用 ls-remote 拿第二处证据:
$ git ls-remote origin
a1b2c3d4e5f6... HEAD
a1b2c3d4e5f6... refs/heads/main
9f8e7d6c5b4a... refs/heads/dev
第二列是引用名,refs/heads/ 开头的就是分支。把 refs/heads/main 前面的 SHA 与本地对比:
$ git rev-parse `--short` HEAD
a1b2c3d
两处一致,说明远端那条分支正指向你刚推的提交(上面的 SHA 仅作占位示意,实际以本机输出为准)。再打开仓库页面的分支列表或分支下拉框对照:页面显示的分支名应当与 refs/heads/ 后面的名字相同,最后一次提交时间应当是刚才。若命令行显示成功、页面却没有这条分支,优先回查 git remote -v 里 origin 的地址是不是你正在浏览的那个仓库。
认证失败和分支被拒分开处理
这两类失败的文本特征不同,处理方向也不同,混在一起反复重试通常不会推进进度。凭证相关的报错片段一般是:fatal: Authentication failed for 'https://...'、remote: Support for password authentication was removed、Permission denied (publickey)、fatal: Could not read from remote repository。对应检查项:remote 地址是 https 还是 git@ 形式,两者走不同的凭证来源;HTTPS 需要的是访问令牌而不是登录密码;SSH 可以用 ssh -T git@github.com 这类命令确认密钥是否被接受;本地凭证管理器或钥匙串里是否还存着旧令牌。地址和凭证确认之后,再执行一次 push。
分支被拒的报错片段一般是:! [rejected] main -> main (non-fast-forward)、! [remote rejected] main -> main (protected branch hook declined)、error: failed to push some refs to ...。排查顺序是先看前缀:non-fast-forward 属于远端有本地没有的提交,先 git fetch origin,再用 git log `--oneline` origin/main 查看远端提交,决定 pull 合并还是 rebase,然后再推;remote rejected 或 protected branch 则是远端接受连接但拒绝了这次引用更新,需要确认当前账号在该仓库的角色权限和分支保护规则,常见做法是改推一条新分支,再从页面发起合并请求。
判断依据很直接:认证失败意味着请求没能按你的身份完成,换凭证之前重试没有意义;分支被拒意味着身份已通过、远端明确拒绝了这次引用更新,重试同样不会有不同结果,要改的是提交历史或权限。