1. 问题切入:这个报错到底卡住了多少人
只要在码云 Gitee 上折腾过代码推送,十有八九都见过这个红字:Incorrect username or password ( access token )。我最早遇到它时,第一反应是“密码打错了吧”,于是反复输入账号密码,甚至重置了好几轮登录口令,结果推送还是失败。后来才明白,这个提示虽然写着 username or password,但实际上它背后牵扯的是 Gitee 的认证机制——要么你用的是 HTTP 方式但 access token 没配对,要么你想走 SSH 却压根没让服务器认你的公钥。
这篇文章就是围绕“Gitee 公钥的设置和修改”来写的,核心目标是把手上的报错彻底解决,同时把公钥相关的原理讲明白。不管是第一次使用 Gitee 的新手,还是从别的平台迁过来的老手,只要遇到这个报错,按文章里的步骤走一遍基本都能处理掉。
先说一个容易被忽略的事实:Gitee 的 SSH 公钥和 Gitee 账号是绑定的,但每台电脑的私钥是独立的。如果换电脑、重装系统、或者复制错了公钥内容,都会导致服务端不认你这台机器。再加上很多开发者同时使用多个代码托管平台,公钥管理一乱,各种权限问题就全冒出来了。
这篇文章我不会只给“删掉旧 key、粘贴新 key”这种一句话方案,而是会从原理、实操、排错三个层面把公钥这块讲透,顺便把 HTTP 方式下的 access token 问题一并梳理清楚。这样你再遇到类似报错,起码能判断是公钥问题还是 token 问题,而不是盲目重装 Git。
2. 先搞懂 Gitee 的认证机制:SSH 和 HTTPS 是两条路
2.1 为什么报错信息里既有 username 又有 password
这个报错原文是Incorrect username or password ( access token ),关键词是括号里的access token。很多人看到“password”就以为 Git 在跟你要密码,实际上这个提示来自 Gitee 服务端对 HTTP/HTTPS 请求的拒绝响应。也就是说,当你使用 HTTPS 方式执行 clone 或 push 时,Git 会把你的账号信息发送过去,但码云检测到账号密码或 token 不匹配,于是抛出这句话。
这里先解释清楚一点:Gitee 的 HTTPS 方式,从 2020 年后就不推荐用账号密码直接推送了。现在常见做法是使用私人令牌,也就是 Personal Access Token。当你复制仓库的 HTTPS 地址时,Git 提示输入用户名和密码,这里的密码栏必须填 Token,而不是账号登录密码。很多人第一次操作不知道这一点,填了自己的登录密码,自然每次都报错。
那 SSH 方式呢?SSH 方式根本不走 username/password 这套逻辑,它靠的是公钥和私钥配对。你生成一对密钥,把公钥文本贴到 Gitee 后台,本机保留私钥。推送时 Git 用私钥签名,服务端用公钥验证,验证通过才放行。所以,如果你已经配好了 SSH 公钥,还一直看到这个报错,大概率是你 clone 的时候用了 HTTPS 地址,而本机没有对应的 token。
2.2 两种方式的取舍:什么时候该用 SSH,什么时候该用 HTTPS
以我个人的实践来看,SSH 是长期项目首选。原因很直接:配好之后一劳永逸,不需要定期刷新 token,也不怕密码策略变化。而且 Gitee 对 SSH 推送的支持已经很成熟,速度上也没有明显劣势。
HTTPS 也不是没用,它最大的优点就是门槛低。别人给你一个仓库地址,你直接git clone https://...就能拉代码,不需要先生成密钥。但如果要 push,就绕不开 token 问题。适合的场景是临时协作、开源项目提交 PR 前拉取代码、或者你不想在自己电脑上留密钥。
我的建议是:长期开发环境一律配 SSH,HTTPS 只用来应急拉取。这样既能避开 access token 的各种坑,也能统一管理模式。
2.3 公钥真正解决的是哪个环节
这个报错如果出现在 SSH 方式下,情况就完全不一样了。SSH 的报错通常是Permission denied (publickey),而不是Incorrect username or password。所以如果你看到的是 access token 的提示,先别急着去改公钥,应该先确认自己用的是不是 HTTPS 地址。
不过标题里提到了“公钥的设置和修改”,说明在很多实际场景中,两者会被混在一起。比如你原来一直用 HTTPS + token,某天想切换到 SSH,却在后台删掉了旧公钥、贴了新公钥之后,仍然发现推送失败。这时候问题往往出在:
- SSH agent 没启动,私钥没被加载
- 服务器上的公钥跟你本机的私钥不匹配
- 多个 SSH key 混用,Git 选错了私钥
这些我会在后面逐一讲实操方法。
3. 手把手配置 SSH 公钥:从生成到部署全流程
3.1 生成密钥前先检查环境是否干净
有很多人拿到项目第一件事就是跑ssh-keygen,结果密钥没生成成功,是因为之前残留过配置。所以我习惯在生成之前先看一下现状:
ls -la ~/.ssh如果你能看到id_rsa和id_rsa.pub这类文件,说明这台机器已经生成过密钥了。这时候有两个选择:继续沿用旧密钥,或者重新生成替换。
我个人的经验是:如果旧密钥在别的平台也在用,不要随便覆盖,因为你把公钥删了、重新生成之后,其他平台也要重新配置。更安全的办法是生成一个专门给 Gitee 用的密钥文件,比如id_rsa_gitee,然后在~/.ssh/config里面指定 Gitee 的 Host 使用这个密钥。
3.2 生成密钥的具体命令与参数解释
生成密钥的命令其实特别简单:
ssh-keygen -t rsa -C "你的邮箱或备注" -f ~/.ssh/id_rsa_gitee几个参数我先解释一下:
-t rsa:指定密钥类型为 RSA,Gitee 目前支持 RSA、ED25519 等,但 RSA 兼容性最好,也是官方文档里最常用的示例。-C:备注信息,可以填邮箱,也可以填“gitee-main”,它只是标识用途,不影响验证。-f:指定保存路径和文件名,这一步很多人会漏掉。不指定的话默认生成id_rsa,在只有一个平台时没问题,多平台混用就会出乱子。
执行之后系统会问你要不要设置 passphrase,也就是私钥口令。我建议这里直接回车跳过。原因很简单:设置了 passphrase 之后,每次 push 都会让你输一次口令,非常烦人。当然,如果你对安全性要求极高,比如在公用电脑上使用,那设置口令是合理的,但日常开发环境真没必要。
生成完成后,你会得到两个文件,一个是私钥id_rsa_gitee,一个是公钥id_rsa_gitee.pub。私钥绝不能外传,公钥要粘贴到 Gitee 后台。
3.3 查看公钥内容并正确复制
查看公钥内容的命令:
cat ~/.ssh/id_rsa_gitee.pub输出是一长串字符串,开头是ssh-rsa,结尾是你的备注邮箱。复制的时候一定要完整复制,不要漏字符。很多人粘贴公钥时是从中间某个位置开始的,结果后台保存的是一段残缺文本,验证自然失败。
复制方法建议用这个命令,直接输出到剪贴板:
# Linux 系统 xclip -sel clip < ~/.ssh/id_rsa_gitee.pub # macOS 系统 pbcopy < ~/.ssh/id_rsa_gitee.pub # Windows 的 Git Bash 环境 clip < ~/.ssh/id_rsa_gitee.pub不依赖图形界面操作,避免手动选择时复制不全。
3.4 在 Gitee 后台添加公钥的具体位置
登录 Gitee 之后,点击右上角头像,进入【设置】页面,左侧菜单找到【SSH 公钥】。页面里会有一个文本框让你填公钥内容,还有一个“标题”栏,可以写“我的主力机”或者“公司电脑”,方便日后管理。
把复制好的公钥粘贴到文本框,点击确定。Gitee 一般不会要求你输密码确认,直接就生效了。我提醒一句:添加成功后,Gitee 会返回一个公钥指纹列表,你最好核对一下指纹和本地是否一致。核对方法后面说。
3.5 配置多平台多密钥的文件拆分技巧
如果你同时使用 Gitee 和 GitHub,甚至还有 GitLab,那必须学会在~/.ssh/config文件里做分流。这个文件没有就新建:
touch ~/.ssh/config然后写入类似下面的内容:
Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_rsa_gitee IdentitiesOnly yes Host github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa_github IdentitiesOnly yes关键的是两个参数:IdentityFile指定对应域名使用哪个私钥,IdentitiesOnly告诉 SSH 只使用这里指定的密钥,不要尝试所有密钥。
这一步做完之后,你的 Gitee 操作就会自动走id_rsa_gitee,GitHub 走id_rsa_github,彼此不干扰。我见过很多同事没做这个配置,两个平台的私钥串着用,然后某天突然提示 Gitee 权限失败,一查才发现 SSH 拿 GitHub 的私钥去试 Gitee,被服务端毫不留情地拒绝了。
4. 验证连接与修改公钥的完整操作
4.1 用 ssh -T 测试 Gitee 是否已经认你的密钥
配置完公钥之后,先不要直接 push,先测试一下连接:
ssh -T git@gitee.com如果是第一次连接,会提示是否确认 host key,输入yes回车。如果一切正常,你会看到类似下面的提示:
Hi 你的用户名! You've successfully authenticated, but GITEE.COM does not provide shell access.这句话很重要,说明服务端已经接受你的公钥。如果报错Permission denied (publickey),那就是公钥没配对成功,需要回头检查。
4.2 修改公钥的高频场景:换电脑、重装系统、丢失私钥
公钥需要修改的场景,最常见的有三种:
- 第一次配的时候,粘贴错了内容,需要删掉重新添加
- 电脑重装系统或硬盘损坏,原私钥丢失,只能重新生成
- 在多台设备之间切换,想把某台旧设备踢出权限
操作逻辑其实很简单:登录 Gitee,找到旧公钥,删除,再添加新公钥。但这里面有一个关键点很多人没意识到——如果你用的是 HTTP 方式,那么 Gitee 后台删除公钥并不会影响你推送,因为公钥只对 SSH 生效。所以很多人删了公钥、加了公钥,发现报错没变,就以为公钥修改没用。实际上报错本来就不是公钥层面的问题。
4.3 ssh-agent 的坑:明明密钥是对的,却一直认证失败
有一类问题特别有意思:公钥在 Gitee 后台是对的,本地私钥也存在,但每次 push 都报权限错误。这种时候十有八九是 SSH agent 的问题。
ssh-agent是系统里的一个后台进程,用来缓存私钥。当你执行ssh-add把私钥加入之后,后续 SSH 连接会优先从 agent 里取密钥。有些终端会话里 agent 没启动,或者私钥没加进去,SSH 就会找不到可用的 identity。
处理办法如下:
# 查看 agent 是否在运行 echo $SSH_AUTH_SOCK # 启动 agent(如果上面没有输出) eval "$(ssh-agent -s)" # 添加私钥到 agent ssh-add ~/.ssh/id_rsa_gitee然后在当前终端里再测试一次ssh -T git@gitee.com。如果成功了,说明就是 agent 的问题。
这里我要再啰嗦一句:Windows 用户遇到的概率尤其大。很多人装了 Git for Windows,默认用的终端是 CMD 或 PowerShell,这两个环境里 SSH agent 不一定自动启动。建议在 Git Bash 里操作,或者手动启动 OpenSSH Authentication Agent 服务。
5. 实战排错手册:当报错依旧存在怎么办
5.1 分清报错来自 SSH 还是 HTTPS
这一节是全文最实用的部分,我会把常见的错误提示和对应处理方式整理成一个速查表,方便按图索骥。
| 报错信息 | 触发场景 | 处理方向 |
|---|---|---|
| Incorrect username or password ( access token ) | HTTPS 方式 clone/push | 改用 SSH 地址,或配置 Personal Access Token |
| Permission denied (publickey) | SSH 方式 push | 检查公钥是否配对、ssh-agent 是否加载私钥 |
| Could not read from remote repository | SSH 方式,提示见上一条 | 检查仓库地址是否为git@gitee.com:用户名/仓库.git格式 |
| Repository not found | 仓库不存在或没有权限 | 检查仓库可见性、是否登录了正确账号 |
| Host key verification failed | 首次连接或服务端指纹变化 | 执行ssh-keygen -R gitee.com后重新连接 |
如果你遇到的是第一条,跟着我做:把仓库的远程地址改掉。查看当前地址:
git remote -v如果输出的是https://gitee.com/xxx/xxx.git,那就改走 SSH:
git remote set-url origin git@gitee.com:xxx/xxx.git改完之后再 push 一次,大概率就正常了。
5.2 HTTPS 方式的正确姿势:用 Personal Access Token 替代密码
有时候仓库地址没法改成 SSH,比如你在别人电脑上临时提交代码。这个时候就必须掌握 HTTPS + Token 的用法。
登录 Gitee,进入【设置】->【私人令牌】,点击“生成新令牌”。这一步会要求你输入账号密码进行二次验证,然后选择令牌的权限范围。一般选择projects和user_info就够了,别把权限全选上,减少令牌泄露后的风险。
生成出的令牌是一串字符串,只在当前页面完整显示一次,务必复制保存。接下来有两种用法:
第一种,在命令行临时使用。当 Git 提示输入用户名和密码时,用户名填你的 Gitee 用户名,密码栏粘贴令牌而不是登录密码。
第二种,直接拼到仓库地址里:
git clone https://用户名:令牌@gitee.com/xxx/xxx.git我不太推荐第二种,因为令牌会明文保存在 shell 历史和 git 配置里,风险太高。如果你想一劳永逸,可以配置 Git 凭据管理器,让它记住令牌,但首次还是要输入一次。
5.3 排查公钥是否匹配的本地方法
如果你确认公钥已经添加成功,但 SSH 仍然认证失败,可以用下面的命令,让 SSH 打印详细的调试信息:
ssh -vT git@gitee.com输出日志里会有一段Offering public key: ...,你仔细看这一行。如果显示的路径不是你自己生成的那个密钥文件,说明 SSH 在连接时选错了密钥。原因通常是没有配置~/.ssh/config,或者IdentitiesOnly没设置。
另一种更直接的办法,是计算你本地公钥的指纹,然后到 Gitee 后台对比:
ssh-keygen -lf ~/.ssh/id_rsa_gitee.pub输出的指纹是类似2048 SHA256:xxxxxxxxxx ...的一行。Gitee 后台的 SSH 公钥列表里,每一条也都有对应的指纹。两者一致,说明添加的内容没有出错。
5.4 一个容易忽视的细节:仓库地址里的用户名大小写
Gitee 的用户名是区分大小写的。有些人的用户名是ZhangSan,但 clone 的时候仓库地址写成git@gitee.com:zhangsan/xxx.git,这种情况下的报错可能既不是公钥问题,也不是 token 问题,纯粹是路径错了。
判断方式很简单:复制 Gitee 仓库页面上显示的 SSH 地址,不要自己手敲。仓库页面右上角的“克隆/下载”按钮,点开之后可以直接复制,里面就是标准地址。
6. 我踩过的坑和后续维护建议
6.1 一次因为公钥没同步而导致的小事故
我印象比较深的一次,是在一台公司老服务器上部署项目。当时那台机器上已经有一套id_rsa,是另一个同事留下的,里面配过 GitHub 的密钥。我没多想,直接ssh-keygen生成新密钥,然后往 Gitee 后台添加公钥,但当时没写~/.ssh/config,导致 SSH 优先尝试了旧的 GitHub 密钥。
结果就是:公钥在 Gitee 后台是对的,本地密钥也是对的,但 SSH 每次拿错的私钥去认证,push 一次失败一次。后来我加了 config 文件、指定了 Gitee 使用专门生成的私钥,问题才彻底解决。
这个教训告诉我:公钥修改的关键不只在于 Gitee 后台,更在于本地如何管理密钥选择逻辑。如果你也遇到“明明配置了却还是失败”的情况,优先怀疑 SSH 有没有选错私钥,而不是反复删后台公钥。
6.2 公钥日常维护的三个建议
第一,给每个设备设置独立的密钥对,并且私钥文件命名清晰。公司电脑就叫id_rsa_company,家用电脑就叫id_rsa_personal。这样哪台设备失效,只需要去后台删除对应的条目就行。
第二,不要在多个平台复制同一份公钥。虽然技术上可以,但一旦某台设备被盗或泄露,你需要在所有平台同时撤销,非常麻烦。
第三,定期检查后台公钥列表。进入 Gitee 设置 -> SSH 公钥页面,看看里面有没有你不认识的条目。如果有,立刻删除。
6.3 关于 access token 报错的最终判断逻辑
最后总结一下判断流程,按照顺序检查:
- 先看
git remote -v,确认当前地址是 HTTPS 还是 SSH - 如果是 HTTPS,改用 SSH 地址或配置 token
- 如果是 SSH,先用
ssh -T git@gitee.com测试认证 - 如果认证失败,检查后台公钥、本地密钥、ssh-agent 三个环节
- 如果认证成功但 push 失败,检查仓库地址是否正确
这个流程能覆盖绝大多数情况,我从那次事故之后,一直按照这个顺序排查,基本没有在认证问题上再卡过壳。
6.4 一个小技巧:用别名简化日常推送
如果你经常在多个项目之间切换,可以在~/.ssh/config里给 Gitee 配一个别名。举个例子:
Host gitee HostName gitee.com User git IdentityFile ~/.ssh/id_rsa_gitee然后仓库地址可以写成:
git clone gitee:xxx/xxx.git这样看起来更简洁,而且不会跟 GitHub 的仓库混淆。我个人挺喜欢这种用法的,尤其在服务器上操作时,少敲几个字母也舒服。
整个公钥管理和 access token 问题,说穿了就是一套认证体系的事。只要你理解了 SSH 和 HTTPS 两条认证路径的区别,再按照上面的步骤一步步排查,大多数报错都能在几分钟内定位。希望这篇内容对你处理 Gitee 的认证问题有帮助。