227. 多个GIT账户共存并支持推送仓库

平时开发过程中可能遇到这样的问题,就是在进行公司的项目开发时要用公司的git账号,以及对应的git仓库,比如gitlab的;对于个人的开源项目,又会有自己的git账号,以及对应的git仓库,比如github或者码云(gitee)。
这时就会遇到多账户提交时的冲突问题,以及对应的多个ssh key的管理的问题。

先验知识

  • 查看所有配置及其来源: git config [--global] --list --show-origin
  • 检查配置: git config [--global] --get <credential.helper>

[!NOTE]
如果命令配置后无效, 请使用 git config [--global] --list --show-origin 查看所在文件, 直接修改文件也可以达到同样的目的. (万物皆文件)

实现

多个ssh key的管理

ssh key的创建

假如有两个git账户,分别是github@example.comgitee@example.com。为了提交git,我们需要设置对应的ssh key,ssh key具体其在对应平台的配置方法比较简单,本文不再详述,可参考对应的资料,这里只是ssh key的创建及管理。
在终端输入如下命令:

1
ssh-keygen -t rsa -C "github@example.com"

终端提示如下:

1
2
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/XXX/.ssh/id_rsa):

此时直接回车,就会在~/.ssh/路径下,创建一个名为id_rsa的公钥,这个并不是我们想要的,因为这里要设计多个ssh key的管理,这个命名没有任何特征。

在终端中输入如下命令:

1
/Users/XXX/.ssh/id_rsa_github

表示这个是github平台的key,之后根据终端提示,输入并确认密码,就可以生成了。

1
2
3
4
5
6
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:
Your identification has been saved in /Users/XXX/.ssh/id_rsa_github.
Your public key has been saved in /Users/XXX/.ssh/id_rsa_github.pub.
The key fingerprint is:
...

同理,另一个ssh key的创建流程如下:

1
2
3
4
5
6
7
8
9
10
ssh-keygen -t rsa -C "gitee@example.com"
# Generating public/private rsa key pair.
# Enter file in which to save the key (/Users/XXX/.ssh/id_rsa):
/Users/XXX/.ssh/id_rsa_gitee
# Enter passphrase (empty for no passphrase):
# Enter same passphrase again:
# Your identification has been saved in /Users/XXX/.ssh/id_rsa_gitee.
# Your public key has been saved in /Users/XXX/.ssh/id_rsa_gitee.pub.
# The key fingerprint is:
...

配置ssh代理

创建好了上面的多个ssh key就可以开始管理他们了。
在终端中输入如下命令,查询系统ssh key的代理:

1
ssh-add -l

如果系统已经设置了代理,需要删除:

1
2
ssh-add -D
# All identities removed.

如果提示:

1
# Could not open a connection to your authentication agent.

执行:

1
exec ssh-agent bash

接下来添加刚才创建的ssh key的私钥:

1
2
3
4
5
6
7
8
9
# 第一个
ssh-add ~/.ssh/id_rsa_github
# Enter passphrase for /Users/XXX/.ssh/id_rsa_github:
# Identity added: /Users/XXX/.ssh/id_rsa_github (/Users/XXX/.ssh/id_rsa_github)

# 第二个
ssh-add ~/.ssh/id_rsa_gitee
# Enter passphrase for /Users/XXX/.ssh/id_rsa_gitee:
# Identity added: /Users/XXX/.ssh/id_rsa_gitee (/Users/XXX/.ssh/id_rsa_gitee)

添加公钥

其实就是将对应的.pub中的内容,复制到对应平台的ssh key管理栏目中,不同的平台,位置不同,可以去对应的个人中心的设置中查看,很容易找到。

配置文件config

在/.ssh目录下创建config配置文件:

1
vim ~/.ssh/config

熟悉vim的可以直接在终端中编辑这个config文件,不熟悉的,打开指定目录下新创建的config文件,直接文本编辑即可:

1
2
3
4
5
6
7
8
9
10
11
# github配置
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github

# gitee配置
Host gitee.com
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa_gitee

编辑保存后,再次查看ssh key的代理:

1
ssh-add -l

如果看到如下,说明设置成功了:

1
2
2048 SHA256:............ /Users/XXX/.ssh/id_rsa_github (RSA)
2048 SHA256:............ /Users/XXX/.ssh/id_rsa_gitee (RSA)

验证ssh key

终端中输入如下验证命令,如果返回如下,说明配置成功了:

1
2
3
4
5
ssh -T git@github.com
# Hi XXXXXX! You've successfully authenticated, but GitHub does not provide shell access.

ssh -T git@gitee.com
# Hi XXXXXX! You've successfully authenticated, but Gitee.com does not provide shell access.

如果遇到:

1
permission denied (publickey)

就是之前的公钥设置的问题,需要去对应的平台检查下ssh key公钥是否设置成功。
至此,ssh key的配置管理就结束了。

多个git账户的提交问题

我们大多数人都会使用第三方工具进行git提交,比如source tree之类的,这些工具在提交时,如果不对对应的git仓库进行专门的配置,会默认走git的全局配置,也就是会用默认的全局配置的账户进行git提交。一不小心,就会用我们私人的账户,进行了公司项目的git提交,生成了对应的提交记录,也有可能因为权限问题,导致直接提交失败。
这时,我们需要对不同的仓库,进行对应的配置。

检查全局配置

在终端中,分别输入如下命令,可以检查目前电脑中的git的全局配置信息,如果没有返回,说明没有全局配置,如果有,就可以看到对应的默认的账户是那个了。

1
2
git config --global user.name
git config --global user.email

为了避免麻烦,我们可以取消全局配置:

1
2
git config --global --unset user.name
git config --global --unset user.email

全局配置和局部配置

此时已经取消了电脑中默认的git全局配置信息,此时进行git提交,会报对应的找不到账户信息的错误。
我们可以cd到对应的git仓库的根目录下,执行局部git配置命令。比如/Users/XXX/github/DemoProject是一个在github平台托管的本地git仓库的根目录,我们可以执行如下命令:

1
2
3
cd /Users/XXX/github/DemoProject
git config user.name
git config user.email

如果返回均为空,说明没有进行过局部配置,可以分别配置github的账户名和邮箱:

1
2
git config --local user.name "github账户名"
git config --local user.email "github@example.com"

同理,在不同的git仓库下,可以分别配置不同平台的git账户名和git邮箱。这虽然看起来麻烦,不过,只要设置完成,之后只要不再更改对应的git仓库的路径,就不需要再更换配置了。

而且,即便我们没有取消默认的全局git配置,在进行了局部配置后,后者的优先级会更高。 执行:

1
git config --list

可以查看查看当前仓库的具体配置信息,在当前仓库目录下查看的配置是全局配置+当前项目的局部配置,使用的时候会优先使用当前仓库的局部配置,如果没有,才会去读取全局配置。

hexo部署时的git提交问题

因为我们先前取消了电脑中的git全局配置,hexo在部署发布时,可能遇到如下问题:

1
2
3
4
5
6
7
8
9
*** Please tell me who you are.

Run

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

不知道是不是因为hexo必须要求读取全局配置,设置了几个文件夹的局部git配置,均无效,只好又恢复了全局配置,也就是对应的github的账户信息,因为之前提到过,局部配置的优先级大于全局配置,所以不用担心账户冲突的问题,只要设置好对应仓库的局部配置信息,就不用担心全局配置的存在。
当然,这只是折中的方案,如果有人知道如何配置hexo仓库的局部配置信息,欢迎指教。

global管理多个账户的私有仓库

  1. 添加 github 账户的 SSH keys

  2. 新建 github 账户的 token

  3. 设置一个账户用作全局账户

    1
    2
    3
    4
    5
    git config --global user.name <global_username>
    git config --global user.email <global_usermail>
    git config --global --unset credential.helper
    git config --global credential.helper store
    git config --global credential.username <global_username>
  4. 按照上面的教程配置多个账户的ssh key

  5. 使用命令: git clone git@<user_hostname>:<repository_owner>/<repository_name>.git 下载该仓库

  6. 使用命令设置 local 配置

    1
    2
    3
    4
    5
    6
    7
    8
    git config --local user.name <username>            # 设置用户名
    git config --local user.email <usermail> # 设置用户邮箱
    git config --local credential.helper store # 设置存储密钥
    git config --local --unset credential.helper # 删除当前仓库存储密钥
    git config --local credential.username <username> # 设置凭证对应的用户名
    git remote rm origin # 移除远程链接
    git remote add origin <remote_url> # 添加仓库的url
    git push --set-upstream origin <master> # 推送仓库
  7. 大功告成

[!NOTE]
建议使用 --lobal, 目前没有深入研究 git configgit config --local 的区别
目前 qwen 给出的回答是: 没有指定作用域,Git 会按照以下优先级查找配置: --local (本地) -> --global (全局) -> --system (系统)
但是: git config 会打印出来所有的包括本地、全局和系统.

QAs

  • 如果存在无法上传到仓库的问题

    运行命令:

    1
    2
    git config --global --unset user.name
    git config --global --unset user.email
  • Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate.

    你可以运行命令

    1
    2
    git config --local user.name "Your Name"
    git config --local user.email you@example.com

    但是该命令需要在每个仓库都要运行一遍. 如果想一劳永逸, 那么运行命令:

    1
    2
    git config --global user.name "Your Name"
    git config --global user.email you@example.com

Reference

  1. 一台电脑如何管理多个SSH KEY
  2. 同一台电脑关于多个SSH KEY管理
  3. Git管理多个SSH密钥,Git多帐号配置
  4. 如何配置多个ssh key
  5. Git配置多账号登录不同项目
  6. Git全局配置和单个仓库的用户名邮箱配置
  7. GIT 常用命令