git本身不存密码,真正起作用的是系统级ssh-agent——它在内存中缓存解密后的私钥,使git pull/push等操作免输密码;未启动或配置错误时,git每次都会提示输入。

Git 本身不存密码,也不“记住”SSH密钥密码;真正起作用的是系统级的 ssh-agent —— 它在内存中缓存解密后的私钥,让后续 Git 操作(如 git pull、git push)免输密码。配置错或没启动它,Git 就每次都要你输。
ssh-agent 没启动,Git 就永远要输密码
很多用户以为只要 git clone 成功一次,下次就自动了,其实不是。Linux 默认不自动启动 ssh-agent,它不会随终端自启,也不会跨会话存活。
- 运行
ssh-add -l,如果报Could not open a connection to your authentication agent,说明ssh-agent根本没运行 - 正确启动方式是:
eval "$(ssh-agent -s)"(注意必须用eval才能导入环境变量) - 只运行
ssh-agent不加eval,输出的SSH_AUTH_SOCK和SSH_AGENT_PID只是打印出来,没生效 - 如果你用的是 systemd-based 系统(如 Ubuntu 22.04+、Fedora),可启用
ssh-agent.socket,但普通终端仍需手动eval一次
ssh-add 添加私钥后,为什么 Git 还要输密码?
常见原因是:私钥没被 ssh-add 加载,或加载了但没设对路径,或用了错误的密钥文件名。
- 默认
ssh-add只尝试加载~/.ssh/id_rsa、id_ecdsa、id_ed25519等固定名字;如果你用的是~/.ssh/github_key,必须显式指定:ssh-add ~/.ssh/github_key - 添加后检查是否成功:
ssh-add -l应该列出指纹,而不是空或报错 - 如果私钥有密码但
ssh-add没弹出提示,可能因为终端未连接到 TTY(比如在某些 IDE 内置终端或 tmux 中),可临时改用ssh-add -c ~/.ssh/xxx强制确认 -
ssh-add -t 3600可设 1 小时有效期,避免长期驻留敏感私钥;但超时后 Git 又会卡住等你重输
如何让每次开终端都自动加载?别硬写 .bashrc 里的 eval
直接在 ~/.bashrc 或 ~/.zshrc 里无条件写 eval "$(ssh-agent -s)" 是错的——它会重复启动多个 ssh-agent 进程,造成环境变量混乱、旧代理残留、Git 认证失败。
- 正确做法是先检查代理是否已存在:
if [ -z "$SSH_AUTH_SOCK" ]; then eval "$(ssh-agent -s)"; fi - 再自动加载密钥:
ssh-add -l >/dev/null || ssh-add ~/.ssh/id_ed25519 2>/dev/null(用||避免重复 add 报错) - 更健壮的写法是封装成函数,配合
ssh-add -D清理旧密钥(尤其换密钥后) - 注意:图形桌面环境(GNOME/KDE)通常自带
ssh-agent管理,终端继承其环境,此时再手动eval反而冲突;可先echo $SSH_AUTH_SOCK看是否已有值
Git 操作仍失败?重点查这三处
即使 ssh-add -l 显示密钥已加载,Git 仍连不上,问题往往不在 Git 本身。
- 确认 Git 使用的是 SSH URL:
git remote get-url origin输出应为类似git@github.com:user/repo.git,不是https://... - 用
ssh -T git@github.com测试底层连接,看是否走到了ssh-agent;若提示Permission denied (publickey),说明代理没生效或密钥不匹配 - 检查
~/.ssh/config是否误配了IdentityFile或IdentitiesOnly yes,后者会强制忽略ssh-agent,只认磁盘文件
最常被忽略的一点:私钥权限必须是 600(chmod 600 ~/.ssh/id_*),否则 OpenSSH 会直接拒绝加载,连 ssh-add 都不报错,只静默跳过——这是 Git 无法认证却找不到原因的高频陷阱。











