
1. 先搞懂 Git 在 Mac 上到底把密码存在哪很多人在 Mac 上用 Git 拉代码、推代码遇到要输账号密码的提示就老老实实敲一遍。敲完没过多久又被要求再输一次烦得一比。还有些人明明换了新密码终端里却还是用旧密码在走怎么改都不生效。这些问题其实都指向同一件事你压根没搞清楚 Git 在 macOS 上是怎么管理账号和密码的。先给结论Git 本身不保存任何账号密码它只是按规则去调用系统的凭据管理器。在 Mac 上这个凭据管理器就是钥匙串访问Keychain Access。当你第一次通过 HTTPS 方式操作远程仓库Git 会提示输入用户名和密码同时会顺手把这对凭据写进钥匙串。之后每次再操作Git 直接找钥匙串要凭据不再烦你。如果你没配置过任何凭据存储方式Git 默认的行为是“每次都问”。但 macOS 上很多安装方式会默认启用osxkeychain这个 helper所以大多数人实际体验是“输一次就记住了”。这个“记住”的底层就是钥匙串里多了一条Internet Passwords类型的记录。理解了这个机制后面所有设置和清除的操作就都有了根。你不是在“改 Git 的配置”而是在“管钥匙串里的凭据 决定 Git 用什么策略去读写这个凭据”。另一个容易忽略的点是Git 的配置分为系统级--system、全局级--global、仓库级--local三个层级。如果你在某个仓库里设置了特殊的用户信息或者在全局配置里写死了某个账号它和钥匙串里的凭据会叠加生效。很多时候你以为自己在“清密码”其实只清了钥匙串但配置文件里还有残留的账号指向照样会出问题。所以后面实操部分我会把配置文件和钥匙串一起处理这才是真正干净的“清除”。2. 设置 Git 账号密码的几种方式和适用场景2.1 最推荐的官方姿势配置 osxkeychain 凭据助手macOS 自带的 Git或者说通过 Xcode Command Line Tools 安装的 Git默认就集成了 osxkeychain。你只需要让 Git 显式使用它以后第一次输过账号密码就永久存在钥匙串里了。git config --global credential.helper osxkeychain这一句配置完成后你随便找一个 HTTPS 地址的仓库操作一次比如git pull或者git push终端会弹出输入框提示你输用户名和密码。输完之后凭据就被写入钥匙串。此后这个域名下的所有操作都不需要再输入。这里有个细节credential.helper 是针对域名生效的不是针对具体仓库。也就是说你在github.com下任何一个仓库输过一次凭据其他所有 GitHub 仓库都会直接用这份凭据。如果你在 GitHub 上同时有个人账号和工作账号这就会造成串号——后面我会专门讲多账号怎么处理。为什么推荐用 osxkeychain 而不是 Git 自带的内存缓存因为 osxkeychain 是持久化的重启电脑后依然有效。内存缓存只能在指定时间内省去输入重启或者过了 timeout 就失效适合临时用一下不适合长期使用。2.2 配置用户名和邮箱很多人和密码搞混的一步不少教程会把下面两条命令也归到“设置账号密码”里git config --global user.name 你的名字 git config --global user.email 你的邮箱严格来说这两条设置的是提交信息里的作者身份不是登录远程仓库的凭据。但这两个东西确实会影响你操作 Git 的体验如果你没设置 user.name 和 user.emailGit 在 commit 的时候会直接报错退出。如果你设错了邮箱你的提交会挂到错误的账号名下在 GitHub 的 Contributions 图上也会显示得乱七八糟。所以建议在设置凭据的同时把这两个基础配置一起检查一遍。查看当前全局配置git config --global --list实际工作中我遇到过很多次“明明密码对了但 push 还是 403”的情况最后查来查去发现是配置文件里写了一个旧邮箱导致所有提交都算在公司账号名下权限校验自然就过不去。所以在排查凭据问题的时候不要只盯着密码user.name 和 user.email 也要一起看。2.3 把账号密码写进远程地址应急方案不建议长期用还有一种土办法直接把账号密码拼在远程仓库地址里git remote set-url origin https://用户名:密码github.com/用户名/仓库名.git这种方式最直观git pull和git push的时候 Git 会直接从 URL 里提取用户名密码完全不用走凭据助手。但问题也很明显URL 里的密码是明文的任何能看到你终端历史、.git/config文件的人都能拿到你的密码。GitHub 现在已经不支持用账号密码直接走 HTTPS 操作了需要换成 Personal Access Token个人访问令牌你等于是把令牌写死在仓库配置里。如果哪天密码改了、令牌过期了你必须手动更新 URL非常麻烦。所以我只建议在两种情况下用这种方式一是临时调试比如你只想测一下某个令牌能不能用改完马上改回来二是在某些 CI/CD 环境里没有交互式输入凭据的条件只能硬编码。其余场景一律不要用。2.4 用 Personal Access Token 替代密码这里多说一句现在 GitHub 已经在 2021 年后全面推行 Personal Access Token个人访问令牌代替账号密码进行 HTTPS 操作用户认证。也就是说即使你走 osxkeychain在第一次弹出的登录框里输入密码这个密码也应该是你的 Token而不是 GitHub 的登录密码。Token 怎么生成GitHub 页面上Settings - Developer settings - Personal access tokens - Tokens (classic)然后 Generate new token。记得勾选repo、workflow等需要的作用域。生成的 Token 要立刻复制保存因为关掉页面后就再也看不到了。实际使用中Token 的格式类似ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx在钥匙串输入密码的位置粘贴这个 TokenGit 就会把它当成密码来用。Token 的好处是可以随时在 GitHub 后台撤销、重新签发不需要去改账号密码安全性高得多。如果你用的是 GitLab对应的概念叫 Personal Access Token 或者 Deploy Token逻辑类似。提示如果你之前用旧密码写过钥匙串后来 GitHub 密码改过或者强制启用了 2FA旧凭据就会失效。这种时候你在终端里怎么输账号密码都没用因为本地钥匙串里的凭据已经被 Git 拿走了。解决方式就是手动删除钥匙串里对应条目再触发一次重新输入。这个操作下面会专门讲。3. 清除 Git 账号密码核心操作和完整命令3.1 最直接的方式从钥匙串访问里删除凭据这是最推荐、最不会出错的方式。按以下步骤操作打开“钥匙串访问”Spotlight 搜索 Keychain Access或者 应用程序 - 实用工具 - 钥匙串访问.app。在左上角搜索框里输入github.com。找到类型为Internet Passwords、账号是你用户名的条目。右键点击这个条目选择“删除”。删除之后Git 不会再从钥匙串里找到凭据下一次操作远程仓库时就会重新弹出输入框。这就是“清除密码”的完整含义。有个细节值得注意钥匙串里可能有多条相似条目。比如你之前用过 Git 客户端工具它可能单独存了一条又比如你既配过 HTTPS 的凭据又在 Safari 里登录过 GitHub也可能多出条目。建议都删掉不要只删一条。否则另一个残留条目仍然可能被 Git 读取到造成“怎么删了还有旧密码”的错觉。3.2 用终端命令直接重置凭据如果你更习惯在终端里操作可以用git credential-osxkeychain命令来搞定。先执行清除命令git credential-osxkeychain erase hostgithub.com protocolhttps输完上面三行也就是先运行 erase然后输入hostgithub.com和protocolhttps最后再按一个回车表示输入结束。执行之后钥匙串里对应的凭据就会被清除。这个方法不需要打开图形界面适合在 SSH 远程场景或者纯粹是懒得开 App 的时候用。但它有个前提这台机器上必须安装了 osxkeychain helper。如果用的是自编译 Git 或者某些包管理器装的 Git可能没有这个命令执行的时候会提示command not found。这种情况下还是老老实实用钥匙串访问 App 删除。另外还有一个更暴力的操作逻辑直接删除 Git 凭据缓存目录。不同 Git 版本和不同安装方式缓存路径不一样最常见的是停在~/Library/Preferences/com.git.CredentialManager或~/.git-credentials。rm ~/.git-credentials.git-credentials文件是 git 的store模式产生的明文凭据文件每行一个 URL里面直接写着账号密码。如果你之前设置过git config --global credential.helper store那么删除这个文件就是最彻底的清除方式。不过 macOS 上默认基本不会走 store 模式看到这个文件大概率是装了某个 GUI 工具后自动生成的。3.3 把凭据助手的配置也一起重置删除钥匙串里的条目只是清除了“当前已存的密码”但 Git 的credential.helper osxkeychain配置还在。这意味着下次操作时 Git 依然会优先去找钥匙串找不到就会弹输入框。这本身没毛病很正常。但如果你希望 Git不再试图保存任何新的凭据而是每次都问那就需要把 helper 配置也清掉git config --global --unset credential.helper或者直接把整个全局配置编辑一遍git config --global --edit把里面credential.helper相关行删掉。这样 Git 就恢复成了“每次都要输账号密码”的原始状态。这里要说明一下很多人在网上看到“彻底清除密码”的教程只教删钥匙串条目没有提配置层的事。如果你只是想换一个账号删条目就够用了。如果你是想让这台机器以后不再自动保存凭据那必须连 helper 配置一起去掉否则下一次输入新账号密码时又被写进钥匙串就像从来没清过一样。3.4 一键重置一个组合命令搞定懒得一步步来可以一次性把配置和钥匙串两方面的清理都做了。下面是我常用的组合命令# 取消凭据助手配置 git config --global --unset-all credential.helper # 删除可能的明文凭据文件 rm -f ~/.git-credentials # 删除钥匙串里的 GitHub 凭据通过 osxkeychain erase 方式 printf protocolhttps\nhostgithub.com\n\n | git credential-osxkeychain erase # 验证是否删除 printf protocolhttps\nhostgithub.com\n\n | git credential-osxkeychain get最后一条get命令如果返回空说明钥匙串里已经没有对应凭据了如果弹出一个界面或者直接返回账号说明没删干净检查一下 host 是不是写错了。注意git credential-osxkeychain get在某些系统上会弹出 GUI 密码输入框如果弹出界面说明找到了凭据。如果没有弹窗也没输出说明确实没了。4. 多账号切换和凭据过期的实战细节4.1 同一平台多账号怎么处理我在公司同时维护着三四个 GitHub 账号个人号、工作号、以及给某个开源项目单独开的号。用一套钥匙串凭据根本没法处理因为 Git 只认域名。后来我摸索出一套可落地的方案第一种做法不同域名隔离。比如个人项目用github.com公司项目走github.company.comGitHub Enterprise钥匙串会自动按域名区分互不干扰。这是最省心的方案也是我强烈建议的。如果你的公司有自建 GitLab域名和 GitHub 不一样天然就是隔离的不会串号。第二种做法同一个域名下多账号利用 URL 里的用户名区分。GitHub 支持在远程地址里显式写用户名比如git remote set-url origin https://personal-usergithub.com/个人账号/仓库.git执行完这个再触发一次 pushGit 会弹窗要求输入密码Token这个 Token 会绑定在personal-user这个用户名下存进钥匙串。你切到另一个仓库时如果它也是personal-user那么复用同一个凭据如果它写的是work-userGit 就会重新弹窗要一份新的凭据。这样就在同一个域名下实现了多账号共存。第三种做法为不同目录单独配 Git 配置和凭据。这算是进阶操作用includeIf指令按目录加载不同配置。比如git config --global includeIf.gitdir:~/personal/.gitconfig git config --global includeIf.gitdir:~/work/.gitconfig然后在~/.config/git/personal里写[user] name 个人昵称 email 个人邮箱 [credential] helper osxkeychain在公司目录里写 employee 版本。这样你在不同目录下操作的时候用的用户名、邮箱、甚至凭据策略都是分开的。这种方式适合对目录划分很严格的人整理好之后体验非常顺滑。不过初次配置成本稍高而且一旦目录放错位置就会出现用公司账号提交个人项目的情况提交记录会挂错人改起来很麻烦。我建议新手先从方案二入手简单直接。4.2 过期的 Token 卡在钥匙串里怎么办这是工作中最高频的问题之一。GitHub 的 Token 有效期到了之后Git 依旧会先去钥匙串找凭据找到了旧 Token然后因为它已经失效服务器返回 401/403 错误。典型症状就是你明明已经在浏览器里改好了新密码、生成了新 Token终端一操作却还是报错 remote: Support for password authentication was removed. 或者 fatal: Authentication failed for https://github.com/...。这时候很多人会觉得是自己代码出问题了实际上就是钥匙串里存了条旧的失效凭据。在 Git 弹出输入框之前它就已经把旧凭据提交上去了。输入框都没出现你的新 Token 根本没机会生效。排查步骤很简单先执行git credential-osxkeychain get看钥匙串里存的是哪个用户名。去钥匙串访问里删掉该域名下对应条目。重新 push 或 pullGit 会重新要求输入账号密码。输入新 Token问题解决。这个场景下的关键心得是遇到认证相关的报错先想本地的钥匙串和配置不要一开始就去怀疑服务器、怀疑网络、怀疑代码。我排查过很多团队的 Git 问题90% 都是本地凭据缓存出了问题服务器端反而很稳定。4.3 清除配置后 Git 开始疯狂询问账号密码有人清完凭据之后发现每次命令都要输入账号密码而且输入完下次还要输。这其实是正常现象因为credential.helper被清除后Git 回到默认的“不保存凭据”模式。每次操作都是一次全新连接自然要重新认证。如果你想恢复到“输入一次以后免密”重新设置一下 helper 就行git config --global credential.helper osxkeychain这里要注意一个顺序先设 helper再触发一次需要认证的操作Git 会弹出输入框输完并验证通过后写入钥匙串。如果你先触发了操作、输入了密码、然后才设置 helper那么刚才那次输入不会触发保存下一次还是会让你重新输。还有个小坑某些情况下 Git 的凭据输入并不是终端明文输入提示而是弹出系统的图形化输入框。很多 Mac 新手第一次看到git push弹出一个 macOS 原生对话框会以为系统被劫持了。实际上那是 Git 调用 Keychain 弹出的正常界面在里面输入账号密码就行还可以勾选“始终允许”来让这次认证结果被保存。5. 配置文件和调试命令速查5.1 最常用的 Git 凭据相关命令整理实际操作中我不可能每次去翻文档所以平时只记下面这组命令。这里整理成一个速查表方便你直接抄操作命令查看全局配置git config --global --list查看当前仓库配置git config --list设置使用钥匙串git config --global credential.helper osxkeychain取消凭据助手git config --global --unset credential.helper删除钥匙串里的凭据printf protocolhttps\nhostgithub.com\n\n | git credential-osxkeychain erase查看钥匙串里的凭据printf protocolhttps\nhostgithub.com\n\n | git credential-osxkeychain get删除明文凭据文件rm -f ~/.git-credentials查看远程地址里有没有写死账号git remote -v修改远程地址不带账号git remote set-url origin https://github.com/用户名/仓库.git这里面最容易被忽略的是git remote -v。很多时候你以为自己清掉了所有凭据但实际上某个仓库的 remote URL 里仍然带着用户名:Token前缀Git 看到这种 URL 根本不会走钥匙串逻辑而是直接从 URL 里取账号密码。所以每次排查问题时我建议先跑一下git remote -v确认 URL 干净。5.2 不同安装方式导致的 Git 差异Mac 上 Git 的安装方式五花八门Xcode Command Line Tools 自带的、Homebrew 装的、官网 pkg 包安装的、甚至还有通过 Conda 或者其他环境管理器带的。不同安装方式带来的 Git 在凭据管理器上的行为可能不一样。Homebrew 安装的 Git 通常会自动启用 osxkeychain helper因为它在安装时会配套装一个git-credential-osxkeychain工具。Xcode 自带的 Git 也默认支持 osxkeychain。但如果你是从源码编译安装的 Git没有配置过任何 helper那么默认就是“每次都要输密码”。遇到这种情况验证方法是执行git config --show-origin --get-all credential.helper这条命令会告诉你当前生效的 helper 是什么、配置来自哪个文件全局、系统、仓库。如果输出为空说明没配 helperGit 每次都会问账号密码。如果输出是osxkeychain说明走的是钥匙串。还有种特殊情况如果你之前装过 GitHub Desktop、SourceTree、VS Code 的某些 Git 插件它们可能会劫持或者修改系统级别的 Git 配置。典型表现就是你明明没有配过任何东西但 Git 莫名其妙地能够自动记住密码。这种情况不用太慌张因为底层多半还是 osxkeychain。你只需要检查一下系统级的配置git config --system --list确认有没有credential.helper的设置。如果有那个 GUI 工具安装时自动写入的删不删你自己权衡——反正不影响安全但如果你自己配了一条同名的 helper可能会出现重复提示那种情况反而是配置冲突。5.3 用环境变量临时绕过凭据有一种场景很容易被忽略你在 Mac 上临时要跑一条命令比如拉取一个公共仓库但不想因为这个操作把凭据写进钥匙串也不想清掉已有的配置。这种时候可以用环境变量来做临时覆盖GIT_TERMINAL_PROMPT0 git pull这个设置会让 Git 在需要认证时直接停止并报错而不是等待用户输入。如果你看到这个报错说明当前 URL 确实需要认证。对于公共仓库来说这个命令基本可以避免无意义的交互。更常用的一个场景是 CI 环境或初始化脚本中通过环境变量传入 Tokenexport GIT_ASKPASS/path/to/askpass.shaskpass.sh可以是一个简单的脚本输出你要给的密码#!/bin/bash echo $GIT_TOKEN这样 Git 会调用这个脚本获取密码输入同时不会影响钥匙串里的内容。这是比较讨巧的做法适合临时测试某个 Token 是否有效测完即弃。我不太建议日常长期这么用因为很容易让 Token 暴露在你的 Shell 历史、环境变量文件里。但作为一个应急技巧它在排查问题的时候非常实用。6. 安全习惯和踩坑复盘6.1 明文存储 vs 钥匙串安全等级完全不同很多人对 Git 凭据的安全性没有具体概念。简单说osxkeychain 模式把凭据放在 macOS 钥匙串系统里这玩意是系统级的加密容器有独立的访问控制。即使有人拿到你电脑的硬盘文件也无法直接读出钥匙串里的明文密码他得先通过你的系统登录和钥匙串解锁。这也是为什么打开钥匙串访问工具时偶尔会弹出让你输入开机密码的窗口——那是在解锁钥匙串。而store模式说白了就是往~/.git-credentials里写一行明文 URL。任何能读取你 home 目录的程序或用户都有机会拿到明文密码。我亲眼见过有人把~/.git-credentials当成普通文件提交到了 GitHub 仓库里几秒之内整个账号就被盗刷了。这种事不是危言耸听在 GitHub 安全团队的漏洞报告里凭据泄漏一直是热门类型。所以在 Mac 上首选永远是 osxkeychain。如果你用的 Git 客户端自带其他凭据机制务必确认它是用系统钥匙串而不是自定义的明文文件。比如某些老版本 SourceTree 会在用户目录下建一个~/.stgitconfig或者类似名字的文件记录账号密码这种就非常危险。6.2 个人踩过的三个坑权限、中文字符、镜像源第一个坑和权限有关。有段时间我用了一个第三方的 Git 配置管理工具它把 helper 配到了/Library/Developer/CommandLineTools/usr/bin/git-credential-osxkeychain这个路径上。后来我卸载了 Xcode 命令行工具这个路径就失效了。结果 Git 操作远程仓库时直接报错提示找不到 helper。排查了半天才发现是配置里写了一个不存在的绝对路径。如果你也遇到类似的诡异报错检查一下 helper 的完整路径是否还存在。第二个坑是用户名里的中文字符。Git 的用户名、地址本身支持 UTF-8但是某些老版本的工具尤其是通过 WINE 包装出来的 GUI 工具、或者 Windows 上开发的代码传到 Mac 上跑的仓库在处理中文字符串时会乱掉。表现是钥匙串里存的用户名是一串乱码你删掉旧凭据后新输入的也还是乱码。这种情况我建议在全局配置里把 user.name 改成拼音或者英文昵称稳定优先。好看不好看不重要能顺利 push 才是重点。第三个坑是换源导致凭据串号。国内很多开发者在 Mac 上会配置几个不同的 Git 服务商镜像比如把某些仓库的远程地址指向快的镜像站。镜像站和我本意访问的官方站域名不同各自有各自的钥匙串条目这没毛病。但如果你在某个仓库里直接git remote set-url origin https://mirror.example/...然后这个镜像站本身也支持 Git 认证那么钥匙串里就会多一条mirror.example的凭据。等你之后又从镜像站切回官方源github.com的凭据是旧的于是认证失败。排查这种问题思路还是不变git remote -v看远程 URLgit credential-osxkeychain get看钥匙串状态定位是哪个域名出了问题单独处理它。6.3 把“清除密码”当一次安全的例行检查我个人的习惯是每个月做一次本地凭据体检。不是等 Git 报错了才去处理而是定期主动清理。做法很简单打开钥匙串访问搜一下git、github、gitlab、相关域名关键词。看一看有没有不认识的条目、很久没用的旧条目。有过期嫌疑的旧 Token 坚决删除。顺手检查git config --global --list确保 user.name、user.email、credential.helper 都还是自己设定的状态。这套检查做下来也就几分钟但能避免绝大多数“突然 push 不上去”的尴尬。尤其是 Token 这种东西没有过期提醒只能靠主动排查。等你真的在开会演示、或者赶上线前最后一刻遇到认证失败再去临时处理那体验相当酸爽。回过头来看Mac 终端里设置或清除 Git 账号密码这件事并不是什么高深技术但它牵扯到操作系统钥匙串、Git 配置层级、凭据助手的交互、以及不同 Git 安装方式的差异。把这些机制理解了你在任何一台不同的 Mac 上都能快速定位问题而不是靠瞎试和重启去碰运气。希望这篇笔记里提到的命令和思路能帮你少踩几个我当年踩过的坑。