问题
今天遇到一个在一台电脑上使用两个github账号的问题,A账号提交到A账号下的仓库,B 账号提交到B账号下的仓库.中间一直报错:
remote: Permission to Nacy-QI/Nacy-QI.github.io.git denied to SYJshang.
fatal: unable to access 'https://github.com/Nacy-QI/Nacy- QI.github.io.git/': The requested URL returned error: 403
原因
在之前此电脑一直使用的A账号,并没有遇到这种情况. 经过一番的探索终于知道原因,原因是在B账号下并没有此电脑的公钥,也就是权限不通过,验证不过去,所以在提交时候电脑默认会找到A默认的私钥去匹配.
解决办法
-
为工作账号生成SSH Key
$ ssh-keygen -t rsa -C "your-email-address" #存储key的时候,不要覆盖现有的id_rsa,在生成两个Key时,不要随便输入enter键就就不会覆盖掉老的两个key ,使用一个新的名字,比如 id_rsa_B
-
把id_rsa_B.pub加到你的B账号上
-
把该key加到ssh agent上。由于不是使用默认的.ssh/id_rsa,所以你需要显示告诉ssh agent你的新key的位置
$ ssh-add ~/.ssh/id_rsa_work # ssh-add -K ~/.ssh/id_rsa # 使用-K可以将私钥添加到钥匙串,不用每次开机后还要再次输入这条命令 # 可以通过ssh-add -l来确认结果
-
配置.ssh/config
$ vi .ssh/config # 加上以下内容 #default github Host github.com HostName github.com IdentityFile ~/.ssh/id_rsa Host github_work HostName github.com IdentityFile ~/.ssh/id_rsa_B
-
取消取消git全局设置
$ git config --global --unset user.name $ git config --global --unset user.email
-
简单分析下原因,我们可以发现 ssh 客户端是通过类似:git@github.com:A/A.github.com.git这样的 git 地址中的 User 和 Host 来识别使用哪个本地私钥的。很明显,如果 User 和 Host 始终为 git 和 github.com,那么就只能使用一个私钥。所以需要上面的方式配置,每个账号使用了自己的 Host,每个 Host 的域名做 CNAME 解析到 github.com,这样 ssh 在连接时就可以区别不同的账号了。
$ ssh -T git@github.com # 测试one ssh连接#Hi ***! You've successfully authenticated,but GitHub does not provide shell access. $ ssh -T git@two.github.com # 测试two ssh连接 #Hi ***! You've successfully authenticated, but GitHub does not provide shell access.
-
在需要提交账号的仓库下关联设置
$ git config user.A "__name__" # __name__ 例如 A $ git config user.email "__email__" # __email__ 例如A@126.com
-
由于A使用的是默认的Host,所以不需要修改,但是B使用的是B.github.com,则需要进行修改
$ git remote rm origin $ git remote add origin git@two.github.com:B/B.github.com.git
-
最后提交代码
$ git add -A $ git commit -m "your comments" $ git push
-
如果遇到warning
warning: push.default is unset; its implicit value is changing in Git 2.0 from ‘matching’ to ‘simple’. To squelch this messageand maintain the current behavior after the default changes, use… //使用下边命令 $ git config --global push.default simple