一般我们在自己的个人电脑上使用git时都会通过SSH的方式来连接代码管理站点如Github等。但有时候我们也会遇到多重SSH的问题。
需求
最常见的情况就是一般的公司都会有自己的私有git仓库,比如用gitlab来搭建的git仓库站点。而公司里也会为每位员工设置一个个人专属的公司域名邮箱,这样的情况下就遇到问题了:我们在自己的电脑上已经配置了自己的邮箱账号作为主力的git账户,而在开发公司的项目时,用来提交git操作的时候就要切换为公司分配的邮箱账号了。虽然我们可以在项目目录内使用 git config user.name
和 git config user.email
来为该项目指定单独的git提交账户,但在 git pull
和 git push
时,每次都需要使用 http
的方式输入密码才行,非常的麻烦。
准备
那么现在问题就来了,个人使用的git账户和公司分配的git账户应该如何在一台电脑上同时存在并保证都能分别使用SSH的方式来提交代码呢?
首先,我们指定下面示例使用的git账户:
我的个人git账户: leafney
leafney@gmail.com
git仓库:github.com
我的公司git账户: wuyazi
wuyazi@company.com
git仓库:111.206.223.205:8080
(公司配置的gitlab对应ip地址)
我使用的Bash : iTerm2+zsh
我的需求是,因为我使用的是个人电脑,所以我希望的是在默认情况下,仍然使用我自己的git账户 leafney@gmail.com
作为全局账户来提交项目。对于公司的项目,则使用公司的git账户 wuyazi@company.com
作为局部账户来仅提交公司的项目。
之前在我的mac下已经设置了默认的git账号 leafney@gmail.com
对应的ssh密钥 。如果你还没有设置过SSH,可以参考我之前的文章:Linux下使用SSH密钥连接Github
新增SSH key
现在要新增一个工作的账号,以 wuyazi
wuyazi@company.com
为示例账户来添加。
查看已添加SSH密钥
查看mac下已经添加的我的个人git账号信息:
1 | ~/.ssh |
查看 id_rsa.pub
内容:
1 | ➜ vim id_rsa.pub |
新增SSH密钥
创建新的 ssh key:
1 | // 切换到 .ssh 目录下 |
需要注意的一点是,当提示 Enter file in which to save the key (/Users/leafney/.ssh/id_rsa):
时,我们不使用默认的名称 id_rsa
,因为该名称我们之前在设置个人git账户时已经使用过了,所以这里新设置一个针对于公司git账户的名称 id_rsa_work
。
操作记录:
1 | ~/.ssh |
将密钥添加到ssh agent管理
通过ssh agent对密钥的管理我们可以实现免密码提交。使用 ssh-add
命令来将新增的密钥添加到 ssh-agent
的高速缓存中:
1 | ~/.ssh |
可以通过命令 ssh-add -l
来查看存在于 ssh-agent
密钥管理器中所有的密钥列表:
1 | ~/.ssh |
这里如果发现之前的 id_rsa
的密钥不存在,可以重新添加一下。
如果要删除所有已添加的密钥,可以使用命令:ssh-add -D
。
配置ssh config
编辑config
SSH
程序可以从以下途径获取配置参数:
用户配置文件:~/.ssh/config
系统配置文件:/etc/ssh/ssh_config
配置文件可分为多个配置区段,每个配置区段使用 Host
来区分。我们可以在命令行中输入不同的Host来加载不同的配置段。
在 ~/.ssh
目录下打开配置文件 config
(没有则新增该文件),如下是我的配置示例:
新增:
1 | ➜ cd ~/.ssh/ |
config
内容:
1 | Host work |
配置项说明
常用的SSH配置项:
Host
别名 :Host myhost
表示自定义的host简称,以后连接远程服务器就可以使用命令ssh myhost
(注意下面有缩进)HostName
主机名 : 主机名可以是ip也可以是域名(如:github.com或者bitbucket.org);如果主机名中包含%h
,则实际使用时会被命令行中的主机名替换。Port
端口 : 表示服务器open-ssh端口,默认22,默认时一般不写此行User
用户名 :User git
表示登录ssh的用户名,如git
IdentityFile
: 表示证书文件路径(如~/.ssh/id_rsa_*
)
其他SSH配置项:
IdentitiesOnly
只接受 SSH Key 登录 可选yes
orno
PreferredAuthentications
强制使用Public Key验证
测试
如上,我用别名 work
指代了公司gitlab的ip地址 111.206.223.205:8080
,使用 ssh -T
命令来验证一下:
1 | ➜ ssh -T git@work |
第一版示例
项目clone
如上的步骤配置完成后,我们就可以通过ssh别名的方式来区分使用不同的SSH Key了。
在 clone
项目到本地之前,我们需要进行一个小小的改动。
之前的clone命令:
1 | ➜ git clone git@111.206.223.205:8080:how_to_use_multiple_git_ssh/you_can_by_this_way.git |
更改后的clone命令:
1 | ➜ git clone git@work:how_to_use_multiple_git_ssh/you_can_by_this_way.git |
即我们将原来ssh地址中的域名用我们在配置文件中的别名来代替了,而相应的别名又对应着ssh密钥文件。
当然,我们还可以更精简一下,因为我们在config
文件中已经指定了用户为 git
,所以可将路径中的用户名也省略掉:
1 | ➜ git clone work:how_to_use_multiple_git_ssh/you_can_by_this_way.git |
这样,看起来是不是非常的舒服呢?
而如果我要clone自己的个人项目,则仍然按照之前的操作即可:
1 | ➜ git clone git@github.com:Leafney/docker-alpine-mysql.git |
设置项目提交账户
在将项目 clone
到本地之后,还要为该项目单独设置commit提交时使用的git账户。
因为我们在之前已经按照 Linux下使用SSH密钥连接Github
操作中的方法将我的个人账户 leafney
leafney@gmail.com
设置为了全局的git账户,在提交项目时如果没有设置项目单独的git账户,就会使用全局的,那这样就不对了。
不加 --global
参数,为刚刚clone下来的公司项目设置公司分配的git账户:
1 | ➜ git config user.name "wuyazi" # 双引号是为了防止name中含有空格而导致错误 |
这样就配置完成了。
还能再快一点吗
总结上面的操作步骤,无非是设置了如下两项:
- 指定git项目使用的SSH Key
- 指定git项目提交时使用的git账户
那么第一步我们已经在ssh的 config
中做了指定,貌似已经是最快的操作了。那就看看第二项如何优化呢?
我们是在git项目clone到本地之后,再去为该项目添加了使用的git账户,那是否能将这两步合并为一步呢?
答案当然是可以的。
设置Base/Zsh方便clone操作
为了以后方便使用不同git账户 git clone
项目,我们在 bash
的 ~/.bashrc
或者 zsh
的 ~/.zshrc
内加入:
1 | alias work-git-clone='git clone --config user.name="wuyazi" --config user.email="wuyazi@company.com" $@' |
以后就只要输入 work-git-clone REPO-SSH-URL
,效果就相当于执行了如下的命令:
1 | git clone REPO-SSH-URL |
然后,更新 Bash/Zsh
的设置:
1 | # 更新Bash设置 |
第二版示例
经过上面的操作,我们在 git clone
公司的git项目时,只需要执行如下简单的两步即可:
第一步:更改SSH地址
1 | # 将项目SSH地址: |
第二步:执行 work-git-clone
1 | ➜ work-git-clone work:how_to_use_multiple_git_ssh/you_can_by_this_way.git |
而操作个人的git项目,命令只需要一步:
1 | ➜ git clone git@github.com:Leafney/docker-alpine-mysql.git |
新的复杂需求
上面的需求可能是相对来说比较常见而且普通的一种情况了,那么下面的需求算是一种稍微复杂的情况了。
因为在Github上发布私有的项目,是需要付费的,所以一般针对于个人的私有项目,我们一般会选择自己购买服务器来搭建属于自己的私有个人仓库,比如我自己的 gogit.itfanr.cc
就是我用开源项目 Gogs
来搭建的。有兴趣可查看我的开源项目:Docker Ubuntu-Gogs 用更简单的方式部署、升级或迁移Gogs服务。 。
那么,现在就出现了下面的四种情况:
- 对于我个人想要开源的代码项目,我会选择使用个人账户发布到
github.com
站点下; - 对于我个人的私有代码项目,我会选择使用个人账户发布到我自己搭建的
gogit.itfanr.cc
仓库站点下; - 对于公司的私有项目,我要选择使用公司分配的git账户发布到公司搭建的私有仓库
111.206.223.205:8080
站点下; - 对于我在工作中的一些积累或私人的项目,我想使用公司分配的git账户发布到我个人的
gogit.itfanr.cc
仓库站点下;
修改ssh config
经过上面的步骤,我们很容易的就知道想要实现上面的需求,只需要通过修改SSH的配置文件 config
中的配置即可实现。
对于公司的项目,针对于上面第3个情况,我们仍然如之前的配置即可:
config
:
1 | # company repo account |
那么在clone项目时的操作如下:
更改项目SSH地址中的域名部分;
执行命令:
1 | ➜ work-git-clone work:how_to_use_multiple_git_ssh/you_can_by_this_way.git |
对于工作中的私人项目,我们要使用公司的git账户来发布到我的个人仓库站点 gogit.itfanr.cc
。配置时我们还需要指定使用密钥 id_rsa_work
:
config
:
1 | # wuyazi private repo account |
那么在clone项目时的操作如下:
- 更改项目SSH地址中的域名部分;
1 | # 如将: |
- 执行命令:
1 | work-git-clone ssh://git@wuyazigogit:9527/wuyazi/repo_for_myself.git |
2019-02-11-更新
在上面的 配置项说明 中也有指出,如果你的ssh链接中不是默认的端口 22
如 ssh://git@gogit.itfanr.cc:9527/wuyazi/repo_for_myself.git
,那么可以通过参数 Port
来指定:
1 | # wuyazi private repo account |
则,后面执行的命令就是:
1 | work-git-clone ssh://git@wuyazigogit/wuyazi/repo_for_myself.git |
这样,看起来更简洁一些了。
因为我的个人账户是作为全局账户来使用的,就是说在 config
文件中如果上面的 Host
部分没有匹配上,那么要保证最后一个 Host
匹配到我的个人git账户。再次回顾 config
配置项中的常用参数,我们发现 HostName
除了可以设置域名或ip地址之外,还可以设置为 %h
,表示实际使用时会被命令行中的主机名替换。
所以,为了实现上面的第1种和第2种情况,以及实现对未特殊说明的项目的默认匹配,我用如下的方式来配置:
1 | # leafney default account for github.com or gogit.itfanr.cc |
如上,针对于不同主机地址使用同一私钥进行登录的情况,可以在 Host
中指定多个别名来匹配,而 HostName
中的 %h
会自动匹配用户输入的ssh地址中的域名部分,来匹配到对应的密钥。
那么在clone项目时的操作如下:
1 | git clone git@github.com:Leafney/ubuntu-gogs.git |
综上,我的 config
配置内容如下:
1 | # company repo account |
新增项目配置
上面的操作中说到的方法一般适用的场景比如你去到一家新公司,然后会给你分配公司的邮箱及git账号,以及公司项目的私有git站点,直接从站点上面 clone
项目到你的开发电脑上,这些项目一般都是公司已有的项目了。
某些情况下,可能需要你新增一个公司的项目,那对于新增公司的项目时,我们要如何使用指定的SSH账户来操作呢?
一般的步骤如下:
初始化项目
在你的开发电脑上,新增一个git管理的项目。在项目目录下使用 git init
来初始化。
设置项目git账户
注意,这里就是最关键的一步了。我们要为该新增的项目创建针对于该项目的git账户。在上面的流程中也提到过,要使用不加 --global
的命令来设置:
1 | git config user.name "wuyazi" |
创建远端项目
然后就是在公司的私有git站点上创建一个空项目。一般在创建完成后都会有类似于下面的一个提示页面:
1 | 从命令行创建一个新的仓库 |
提交到远端仓库
对于只有一个SSH密钥的情况下,我们要将本地项目提交到远端,只要执行页面中后面这两句就可以了。而现在我们要将本地新增的公司项目使用我的公司git账户提交到公司的私有git站点上,首先呢还是需要更改一下提交的项目地址:
1 | # 将项目SSH地址: |
然后我们就可以执行上面两条命令了:
1 | git remote add origin ssh://work:how_to_use_multiple_git_ssh/new.git |
有没有简洁命令
可能有的朋友会想了,在之前 clone
已有项目时,我们使用了一条简洁的命令: work-git-clone work:how_to_use_multiple_git_ssh/you_can_by_this_way.git
来直接省略了单独设置git操作账户的步骤,那在新增时,是不是也可以有类似的操作呢?
答案是否定的。
因为 git clone
命令是可以接收 --config
参数的,以便在clone的同时指定配置;而 git push
命令却是没有该项的。具体的可以通过命令 git clone help
和 git push help
来详细了解。
至此,后面的操作就是常用的 pull
和 push
等操作了。