安得万里风,飘飖吹我裳。
唐 杜甫 《夏夜叹》
摘要
目前使用 git 作为文件版本控制工具的开发者越来越多,同时一个开发者可以拥有多个不同 git 服务器的帐号或者同一个 git 服务器的不同帐号。
例如,小明在公司有个公司搭建的 git 服务器帐号用于工作开发,同时在目前流行的 github 和 bitbucket 上也有帐号,在业余时间 fork 一些项目,然后做一些 contributes. 这时小明就会遇到一个问题,账户这么多,如果每次使用 git 软件在终端进行 add, commit 后,需要 push 到本地仓库对应的远程服务器时,如果没有事先配置好 ssh 免密码登录或是其他密钥管理方法, 每次都需要输入对应的服务器账户密码来进行安全认证。
有没有什么方法可以一劳永逸地解决这个多 git 账户自动匹配免密码登录问题呢?
本文描述了在 Terminal 环境下使用 ssh 协议的多个不同 git 服务器帐号的 git 仓库如何自动匹配免密码登录的方法。
快速预览
主要解决两个问题,免密码登录 和 多账户自动匹配,前者可以使用 ssh 公私钥对解决,后者通过编辑 ssh 配置文件解决。
场景模拟
小明目前有 3 个 git 服务器账户,账户信息分别如下:
- 第 1 个是公司购买的 bitbucket 付费账户,用于日常工作开发, 其账户名为
xiaoming, 关联邮箱为xiaoming@test.com,
目前工作项目的仓库地址为git@bitbucket.org:xiaoming/testFly.git. - 第 2 个是自己私人申请的免费 bitbucket 账户, 用于管理和保存私人的配置文件等或者 fork 一些项目研究做些贡献,其账户名为
superming,关联邮箱为
superming@gmail.com, 目前关注的项目仓库地址是git@bitbucket.org:superming/superman.git. - 第 3 个账户也是自己私人申请的免费 github 账户,这里是开源的天堂,小明经常在此 star, watch, fork 项目等,其账户名为
mingh, 关联邮箱为
mingh@gmail.com.
为了实现这 3 个账户自动匹配免密码登录,小明首先依次生成了三对密钥文件:
# 生成第 1 个名为 xiaoming 账户的密钥对
$ssh-keygen -t rsa -f ~/.ssh/id_rsa_xiaoming -C "xiaoming@test.com"
# 生成第 2 个名为 superming 账户的密钥对
$ssh-keygen -t rsa -f ~/.ssh/id_rsa_superming -C "superming@gmail.com"
# 生成第 3 个名为 mingh 账户的密钥对
$ssh-keygen -t rsa -f ~/.ssh/id_rsa_mingh -C "mingh@gmail.com"
接着手动添加了这 3 对密钥对的私钥文件到 ssh-agent 会话用于自动认证 ssh 会话连接:
$ssh-add ~/.ssh/id_rsa_xiaoming
$ssh-add ~/.ssh/id_rsa_superming
$ssh-add ~/.ssh/id_rsa_mingh
由于 ssh-agent 会话是一个临时的会话,在终端退出后也随之结束,为了每次启动终端时都能自动添加私钥文件:
$echo "ssh-add ~/.ssh/id_rsa_xiaoming >/dev/null 2&1" >> ~/.bashrc
$echo "ssh-add ~/.ssh/id_rsa_superming >/dev/null 2&1" >> ~/.bashrc
$echo "ssh-add ~/.ssh/id_rsa_mingh >/dev/null 2&1" >> ~/.bashrc
由于小明用的是 zshell, 需要把 ~/.bashrc 改成 ~/.zshrc.
接下来就要配置 ~/.ssh/config 配置文件实现账户自动匹配:
# 第 1 个 xiaoming bitbucket 工作账户
host xiaoming_work
hostname bitbucket.org
Port 22
User git
IdentityFile "~/.ssh/id_rsa_xiaoming"
# 第 2 个 superming bitbucket 私人账户
host bitbucket.org
hostname bitbucket.org
Port 22
User git
IdentityFile "~/.ssh/id_rsa_superming"
# 第 3 个 mingh github 私人账户
host github.com
hostname github.com
Port 22
User git
IdentityFile "~/.ssh/id_rsa_mingh"
由于工作账户新项目创建不频繁,所以使用了 xiaoming_work 作为 host, 但同时需要到当前工作的项目的根目录修改远程服务器地址:
# 原远程服务器 origin 地址为 git@bitbucket:xiaoming/testFly.git
$git remote remove origin
$git remote add origin xiaoming_work:xiaoming/testFly.git
而 host 与 hostname 一致的两个常用账户则不需要修改远程服务器地址了。
为了保证对应账户下的 git 仓库使用对应的账户名和邮箱进行 commit, push 等,
还需要进行每个 git 仓库设置对应的 user.name 和 user.email:
$cd <testFly 仓库根目录>
$git config --local user.name "xiaoming"
$git config --local user.email "xiaoming@test.com"
...
## 其他仓库类似配置
方法详解
-
为指定 git 账户生成 ssh 密钥文件实现免密码登录
ssh-keygen -t rsa -f ~/.ssh/id_rsa_work -C "work@163.com"`-
-t rsa指定生成密钥类型(type)为 rsa 非对称加密; -
-f ~/.ssh/id_rsa_work指定生成密钥存放文件(file)为~/.ssh/id_rsa_work, 该文件名可以由用户自己命名,
建议该文件统一放在~/.ssh/目录下以便于管理; -
-C "work@163.com"给该密钥添加注释(comment),一般使用关联该 git 账户的 email.
执行此命令后需要你输入要生成的密钥文件的口令(密码)和重复输入口令,连按回车键即可设置密钥文件口令为空从而实现免密码登录。
然后你就会在~/.ssh目录下找到新生成的密钥文件分别为id_rsa_work和id_rsa_work.pub, 前者为私钥文件,本地私人使用,后者为公钥文件,
可以公开使用。
-
-
添加上述私钥文件到当前 ssh-agent 会话用于认证 ssh 会话
ssh-add ~/.ssh/id_rsa_work -
查看当前会话已添加的 ssh 私钥
ssh-add -L -
每次启动终端时都自动添加指定私钥到当前 ssh-agent 会话中
echo "ssh-add ~/.ssh/id_rsa_work >/dev/null 2>&1" >> ~/.bashrc如果使用 zshell
echo "ssh-add ~/.ssh/id_rsa_work >/dev/null 2>&1" >> ~/.zshrc -
配置
~/.ssh/config文件实现多 git 账户自动匹配认证登录
编辑~/.ssh/configssh 配置文件(如果没有该文件就手动新建,touch ~/.ssh/config),
以 bitbucket 帐户为例,例如账户work下的一个 git 仓库地址为:git@bitbucket.org:work/test.git, 从仓库地址可以看出此仓库的
用户名(User)为git, 主机名(hostname)为bitbucket.org, 通信端口号(Port)一般为22.所以其配置为:# 此处演示 bitbucket 下注册的账户名为 work 的账户的 ssh 配置 host git@bitbucket.org # 主机别名,用户自定义,具有唯一性 hostname bitbucket.org # git 远程服务器主机名 Port 22 # git 服务器端口号,一般默认为 22 User git # git 仓库地址中 @ 符号前的用户名,常见为 git, 注意与你在该服务器上申请的账户名区分 IdentityFile "~/.ssh/id_rsa_work" # 刚开始生成的密钥文件存放位置其中
hostname,User,Port对应于 git 仓库地址里的信息,而host可以认为是一个别名,表示了这一主机的别名,
可随意命名,用于区分具有同一个hostname的不同账户的仓库。IdentityFile为私钥认证文件,即上文生成的id_rsa_work文件. -
部署公钥到 git 服务器
例如在 bitbucket 服务器网页上菜单bitbucket Settings > SSH keys > Add key,
把公钥文件里的公钥字符串拷贝粘贴到此处设置处.# 拷贝公钥字符串到系统剪贴板,此处是 macOS 的系统剪贴板 cat ~/.ssh/id_rsa_work.pub | pbcopy -
测试 ssh 能否免密码直连
ssh -vT git@bitbucket.org或者使用
git clone一个当前账户下的私人项目到本地看是否成功。 修改本地 git 仓库的远程服务器地址
- 如果你在 github 或者 bitbucket 服务器上都只注册了一个账户,在配置
~/.ssh/config时建议host与hostname保持一致,
如此不用修改配置。 - 如果你在同一个 git 服务器上有两个账户,例如在 bitbucket 上有常用的
work账户和不太常用的life账户,~/.ssh/config可以配置如下:# personal git account "work" in bitbucket host git@bitbucket.org hostname bitbucket.org Port 22 User git IdentityFile "~/.ssh/id_rsa_work" # personal git account "life" in bitbucket host lifebucket hostname bitbucket.org Port 22 User git IdentityFile "~/.ssh/id_rsa_life"- 使用上述配置,对于要新
clone的work账户下的仓库或是本地已存在的仓库,不需要修改任何配置,因为host与hostname一样。 - 对于
life账户下的仓库:- 新 clone 的仓库需要修改仓库地址url,例如
git clone git@bitbucket.org:life/tutorial.git改为git clone lifebucket:life/tutorial.git - 已经存在的仓库,切换到该仓库根目录,执行
git remote remove origin && git remote add origin lifebucket:life/tutorial.git.
- 新 clone 的仓库需要修改仓库地址url,例如
- 使用上述配置,对于要新
- git 设置
由于有多个不同的 git 账户,一般不能随意设置 git 全局设置了,尤其是user.name和user.email,需要单独给每个仓库设置。
首先移除全局设置:
git config --global --unset user.name && git config --global --unset user.email,
然后到对应的仓库根目录下执行类似于下面的命令:git config --local user.name "life" git config --local user.email "life@163.com"