git账户切换bug(trouble shooting)
分享一个git的bug追踪过程
严格的说这算是git的一个不完善的地方,或者说是个bug
问题
在一台电脑上,有多个git用户,要进行切换时,总是提交不了,提示没有权限:
D:\git>git push remote: Permission to geektcp/packetsender.git denied to xxxx.
fatal: unable to access 'https://github.com/geektcp/packetsender.git': The requested URL returned error: 403
这个问题非常烦人。有强迫症或者代码洁癖的开发人员自然有体会。
首先绝对不是密码不对;
也不是git安装版本的问题;
而且git安装目录没有缓存文件;
跟git项目下隐藏目录.git也无关。
如果电脑上之前用过一个账户一段时间,并且使用下面这条命令保存过密码:
git config --global credential.helper store
当你要换另外一个用户clone代码,并且提交时,就会一直出现这个问题。
不管是用git push 这个命令,还是用idea的提交按钮,都会必现。
这个时候,如果用下面的命令不保存密码:
git config --global --unset credential.helper
这时每次提交都需要输入账户和密码,可以正常提交,权限是正常的,但是每次都要输入账号密码。
Trouble Shooting
这个问题非常容易让开发人员误以为是账号缓存没有清理干净,于是使用下面命令进行设置:
git config --global user.name xxxx git config --global user.email xxxx@xxx.com
实践表明,这是徒劳的!
搜索网上的一些解决方案,说是windows的凭据问题,删除凭据即可,我不确信win8即以上系统是否可以通过这个方法解决;
但我确定,win7系统肯定不行!
事实上,问题的关键在于:
git config --global credential.helper store
这条命令做了什么?
这条命令其实是把git账号/密码/github.com,缓存到磁盘上。
格式如下:
https://userA:passwordA@github.com
https://userB:passwordB@github.com
仔细看,这个缓存压根没有具体的git项目的详细路径。
实际上,git是如何命中缓存的呢?
git是根据密码来命中缓存的。
比如说:
git config --global user.name userA git config --global user.email userA@xxx.com
git config这个命令只能缓存账号和邮箱,不能对密码进行指定缓存。
根本原因
关键在于,当你push的时候,git会根据你输入的密码,去找到缓存的磁盘文件中找到对应的账号。
比如输入密码为passwordA时,会找到userA,因为有下面的记录。
https://userA:passwordA@github.com
当你的多个用户,且密码是同样的时候,就会出现下面的缓存:
https://userA:passwordA@github.com
https://userB:passwordA@github.com
这个时候,如果你想用userB登录,但是由于userA所在这条缓存记录在前面,密码一样的情况下,先命中磁盘文件缓存的userA,
于是git用userA和passwordA进行登录,接下来就是网络认证的事情,当然是没有权限的,因为那个项目可能只有userB有权限。
在win7系统上,这个缓存用的是绝对路径,比如Administrator用户的路径是:
C:\Users\Administrator\.git-credentials
解决方案就是:把这个文件删除,或者编辑这个文本文件,删除里面你要清理的那条缓存并保存文件,问题就解决了。
by the way,都2020年了,赫赫有名的git,它缓存文件里的密码竟然是明文的!
现在这个坑货问题已经彻底解决。
技术不在于多么高超先进巧妙,而在于要有现实价值!!!