◆

Git pull push 免输入账号密码的配置方法

2023-02-02 01:370

git pull or push 每次都要输入账号密码

git config credential.helper store
  • 这里没有 –global 意思是指只对这个仓库生效,建议以后都不要加 –global,让代码配置以仓库为单位存储就好,设置成全局不灵活
  • git push 到远程仓库,按提示输入用户名和密码,注意要输入正确的( GitHub 的用户名和密码)
  • 再次运行 git push 就不用输入用户名和密码了,因为在用户主目录文件夹多了一个文件 git-credentials,这个就是用来存储用户名和密码的
  • 若想把项目的用户名和密码删掉,输入下列命令
git credential-manager uninstall

这样每次 git push 时又需要输入用户名和密码了。

store 是明文存储

这一点必须先说清楚,因为它决定了这个方案适用于什么场景。credential.helper store 把凭据以纯文本写进 ~/.git-credentials,格式是完整的 URL:

https://username:ghp_xxxxxxxxxxxx@github.com

没有任何加密,任何能读到这个文件的进程都能拿到你的凭据。文件权限默认是 600(只有你能读),但这在多人共用的机器、或者装了不明来源工具的环境里保护有限。

所以 store 适合:个人开发机、临时的 CI 容器。不适合:共用服务器、公司发的受管设备、任何你不完全掌控的环境。

更安全的几个 helper

macOS 用系统钥匙串:

git config --global credential.helper osxkeychain

凭据存进 Keychain,加密的,可以用「钥匙串访问」App 查看和删除。macOS 上装的 git(Xcode CLT 和 Homebrew 版)都自带这个 helper。

Windows 用 Git Credential Manager:

git config --global credential.helper manager

Git for Windows 安装包默认就带 GCM 并配好了,一般不用手动设。它存进 Windows 凭据管理器,同样是加密的,而且支持 OAuth 浏览器登录流程,不需要手动创建 token。

Linux 用 libsecret:

# Ubuntu/Debian 先装
sudo apt install libsecret-1-0 libsecret-1-dev
cd /usr/share/doc/git/contrib/credential/libsecret && sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

只想临时缓存不落盘:

# 缓存在内存里,默认 15 分钟
git config --global credential.helper cache
# 自定义超时(秒),这里是 8 小时
git config --global credential.helper 'cache --timeout=28800'

cache 靠一个后台守护进程持有凭据,进程退出或超时就没了,不写磁盘。临时机器上比 store 合适。

关于 --global 的取舍

原文建议「以后都不要加 --global」,这个建议在多账号场景下是对的,但对大多数人来说反而更麻烦。

我的实际取法是:helper 类型设全局,凭据本身天然是按 host 存的。也就是说 git config --global credential.helper osxkeychain 之后,GitHub、GitLab、公司 GitLab 的凭据各自独立存储,互不干扰——因为 helper 的查找 key 是 protocol://host,不同站点自然分开。

真正需要仓库级配置的是「同一个 host 上要用不同账号」,比如公司账号和个人账号都在 github.com。这种情况用 credential.<url>.username 更精确:

# 全局默认用个人账号
git config --global credential.https://github.com.username personal-name

# 某个公司项目单独指定
cd company-project
git config credential.https://github.com.username work-name

或者更彻底地按目录自动切换配置:

# ~/.gitconfig
[includeIf "gitdir:~/work/"]
	path = ~/.gitconfig-work
[includeIf "gitdir:~/personal/"]
	path = ~/.gitconfig-personal
# ~/.gitconfig-work
[user]
	name = Work Name
	email = work@company.com

includeIf 是 Git 2.13+ 的功能,按仓库路径自动套用不同配置。它连 user.email 一起解决了,比手动记着在哪个仓库配什么可靠得多。注意 gitdir: 的路径必须以 / 结尾才会匹配整个目录树。

GitHub 已经不能用密码了

这是原文那句「输入 GitHub 的用户名和密码」现在会失败的原因:GitHub 从 2021 年 8 月 13 日起停止了 HTTPS 的密码认证。现在密码那一栏要填的是 Personal Access Token(PAT)。

创建路径:GitHub → Settings → Developer settings → Personal access tokens。两种类型:

  • Fine-grained token(推荐):可以精确到单个仓库、单项权限,有强制过期时间。
  • Classic token:按 scope 授权,repo scope 覆盖仓库读写。粒度粗但兼容性好,某些老工具只认它。

推送代码最少需要的权限是 fine-grained 的 Contents: Read and write,或者 classic 的 repo。

token 只在创建时显示一次,之后看不到。存到 helper 里之后基本不用再管,但要记住它有过期时间——某天突然开始报 Authentication failed,先想想是不是 token 过期了。

GitLab、Gitee 同理,都改成了 access token。

SSH 才是我实际用的方案

配好 SSH 之后完全不用管凭据的事,也不存在 token 过期:

# 1. 生成密钥(现在推荐 ed25519,比 RSA 短且更安全)
ssh-keygen -t ed25519 -C "your@email.com"

# 2. 把公钥加到 GitHub(Settings → SSH and GPG keys)
cat ~/.ssh/id_ed25519.pub

# 3. 测试连通
ssh -T git@github.com
# 出现 "Hi username! You've successfully authenticated" 即成功

# 4. 把已有仓库的远端从 HTTPS 换成 SSH
git remote set-url origin git@github.com:user/repo.git

生成密钥时会问要不要设 passphrase。设了更安全,但每次用都要输——这时候用 ssh-agent 把它缓存起来:

# macOS:加进 agent 并存到钥匙串,重启后仍有效
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# ~/.ssh/config,让 macOS 自动加载
Host github.com
  HostName github.com
  User git
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519

多账号场景下 SSH 也很好处理,给每个账号配一个 Host 别名:

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

之后远端地址写成 git@github-work:company/repo.git,用哪个密钥由 Host 别名决定,不会搞混。

公司网络封了 22 端口的话,GitHub 提供了 443 端口的 SSH 入口:

Host github.com
  HostName ssh.github.com
  Port 443
  User git

清除已存的凭据

原文提到的 git credential-manager uninstall 只适用于 Windows 的 GCM,而且新版 GCM 已经改成了 git-credential-manager unconfigure。按 helper 类型分别处理:

# store:直接删文件,或者只删其中一行
rm ~/.git-credentials

# cache:让守护进程退出
git credential-cache exit

# macOS 钥匙串:用交互式命令删
git credential-osxkeychain erase
# 然后输入两行,回车两次结束:
# protocol=https
# host=github.com

# 或者打开「钥匙串访问」App 搜 github.com 手动删

# 彻底取消 helper 配置
git config --global --unset credential.helper
git config --unset credential.helper       # 仓库级

换过 token 之后 push 还是报旧凭据失败,就是缓存里还留着旧的,按上面清一遍再重新输入。

验证当前用的是哪个 helper

# 看所有生效的 helper(可能有多个,按顺序尝试)
git config --get-all credential.helper

# 带来源,确认是全局还是仓库级
git config --show-origin --get-all credential.helper

# 看 git 实际的认证过程
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git push 2>&1 | head -40

credential.helper 可以配多个,git 会依次询问直到拿到凭据。这也意味着旧的配置不会被新的自动覆盖——想干净替换要先 --unset 掉旧的,或者用 --replace-all。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEGit pull push 免输入账号密码的配置方法加载中