[TOCM]
[TOC]
前言
相信不少人学习 git 知识时都是了解了如何使用 git ,如何管理版本,分支等,却不知道如何处理多账号/身份的环境,导致在公司仓库提交代码时却显示着个人的身份信息(个人邮箱而不是公司邮箱),亦或推送代码时登陆着个人的 (github) git 账户而没有公司内网 git 仓库的访问权限,还得在全局退出个人账户,切换至公司账户,十分麻烦。
本文将简单介绍 git 中的身份与账户是什么,如何体现,如何设置多个身份与账户的环境及如何使用。本文内容主要为个人理解,如有缪误,欢迎指正。本文所实验的环境为 mac 系统, windows 与 linux 系统类似,应该只是各配置文件的路径不同。
在 git 中,身份信息主要用于标识进行 git 操作的用户的身份与验证,主要在 git commit 等相关的操作时进行身份标识。可以在 commit 时对其进行用户名,邮箱进行标识,甚至可以对 commit 进行 gpg 签名。
而账户信息则主要涉及对代码进行远端推送 (push / pull) 时,与平台进行身份验证,是否许可推送与拉取代码等。
多 git 身份
本部分将展示如何使用 git 别名来为支持 gpg 签名的项目托管平台在项目级别设置标识。(备注:gpg 作用在进行 commit 时进行签名)
首先,删除所有现有的全局标识
git config --global --unset user.name
git config --global --unset user.email
git config --global --unset user.signingkey
git config --global --list # 检查现有的全局标识
设置要求配置存在才能进行提交操作
默认在没有全局用户名和用户电子邮件的情况下 git 将使用系统的主机名和用户名进行提交。通过此设置让您为每个新项目指定一个标识否则 commit 时 git 会抛出错误。
git config --global user.useConfigOnly true
(附)如何生成 GPG 密钥
进入生成GPG公钥/私钥对交互对话:
gpg --full-gen-key
如后图:选择(1)RSA 和 RSA (默认)密钥类型。选择 4096 位的密钥大小。将密钥设置为不过期(0),除非您想定期重复此步骤。最后,设置您的姓名和电子邮件地址。评论(备注)可以留空。

一旦密钥对生成,我们需要导出公钥。
(附)导出公钥
对于每个身份,导出公钥:
gpg --list-secret-keys --keyid-format LONG user@example.com
其中 user@example.com
是您刚刚创建的身份的电子邮件地址。
这将以 sec
格式输出 ID rsa4096/[serial]
。复制序列号,然后运行以下命令以输出公钥:
gpg --armor --export [serial]
示例图片:

复制公钥块并将其添加到您的 Github 或 Gitlab 设置中。使用公钥, Github 和 Gitlab 可以加密验证您的提交,在每个提交旁边放置一个“已验证”标签。
设置全局 git 配置标识
现在我们需要在 git 的全局配置中创建身份。例如:
git config --global user.gitlab.name "Your Name"
git config --global user.gitlab.email "gitlab@example.com"
git config --global user.gitlab.signingkey 543166183AE7043A
git config --global user.github.com.name "Your Name"
git config --global user.github.com.email "github@example.com"
git config --global user.github.com.signingkey BCF8B7A8C138D16B
git config --global user.identity3.name "Your Name"
git config --global user.identity3.email "identity3@example.com"
git config --global user.identity3.signingkey 4F3FFC37B1A027BD
git config --global user.identity4.name "Your Name"
git config --global user.identity4.email "identity4@example.com"
git config --global user.identity4.signingkey D921F8BA473CF1FC
当然,如果你在 github 只有一个账户的话,我建议你就设置为 user.github.com
;而如果你有多个 github 账户的话,建议设置一个常用的为 user.github.com
,而其他的就可以设置成 user.github_u1
、 user.github_u2
、 user.github_u3
等(你随意)。
创建 git 别名
设置 git 别名将给我们一个新的 git 命令,用于在项目级别设置标识。这实际上只是一个为本地配置设置特定全局标识的脚本,可以帮助你快速设置你在仓库的身份信息。
git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; git config user.signingkey "$(git config user.$1.signingkey)"; :'
指定 git 标识
对于每个项目,指定要使用的 git 标识:
$ cd /path/to/git/repo
$ git config user.email # should be no response
$ git config user.github.email
github@example.com
$ git identity github # 一键设置当前项目使用 user.github 的信息(name, email, signingkey)
$ git config user.email
github@example.com
$ git config --list --local # 亦可直接使用此命令查看当前仓库的配置信息
就这样!现在,无论何时您开始一个新项目或处理现有项目,您都可以确信正在使用正确的名称、电子邮件地址和 GPG 签名密钥。
git commit -S -m "hello world" # -S 参数表示对其签名,也可以自行查找如何设置默认签名,就不用加 -S 参数了
多 git 账户
(可选)准备工作-清除 push 缓存中的账号密码
清除配置中纪录的用户名和密码,下次提交代码时会让重新输入账号密码:
git config --system --unset credential.helper
清除git缓存中的用户名的密码
git credential-manager uninstall
创建 ssh 密钥对
ssh-keygen -t rsa -C "snow08@gmail.com" -f '/Users/snow08/.ssh/id_rsa' # 邮箱与存储位置/存储文件名请自行修改
[...]
ssh-keygen -t rsa -C "snow08@outlook.com" -f '/Users/snow08/.ssh/id_rsa_pro'
将密钥对连接到你的 git 托管平台账号(以 github 为例)
- 手动复制公钥
cat ~/.ssh/id_rsa.pub
(也可使用 pbcopy 命令自动复制到剪贴板)
- 登陆到你的 github 账号
- 在 github 设置 ssh 界面粘贴你的 ssh 公钥
- 复制其他公钥
cat ~/.ssh/id_rsa_pro.pub
- 重复 2 至 4 步,分别设置其他账号
注:图文教程可参考 Adding a new SSH key to your GitHub account
自动选择 ssh 密钥
我们可以配置 ssh
来使用特定加密密钥的主机(取决于 host
)。 令人高兴的是,您可以为同一主机名(hostname)使用多个别名(host)。
下面是一个 ~/.ssh/config
文件的示例:
# 默认 GitHub 账号使用的 ssh 配置
Host github.com # host 决定使用哪个配置
HostName github.com # 实际的 git 托管平台服务器地址
User git # 无需改变
IdentityFile ~/.ssh/id_rsa # 实际使用的 ssh 密钥
# 其他 github 账号配置
Host github_pro
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_pro
git 远程设置
你可以通过修改 git 远程配置中的 git@github.com
为 git@github_pro
来应用上面配置的别名(host)
您可以更改现有的项目远程(使用诸如 git remote set-url origin git@github_pro:foo/bar.git
),也可以在克隆它们时直接对其进行修改。
git clone git@github.com:snow08/snow08.git # clone 时的原链接
# 使用别名后则变为
git clone git@github_pro:snow08/snow08.git
设置 git 用户信息
Git配置设置可以是全局的,也可以是每个项目的。我们更推荐对每个项目单独设置。要实现它很容易:
git config user.email 'snow08@outlook.com' # 在您的 git 项目下执行就可以设置项目的用户 email
这虽然很简单,但是又有点繁琐(需要设置 name, email 和 signingkey(可选)),需要输入三次命令,所以我推荐按照上文[多 Git 身份](#多 Git 身份)进行一键设置 git 项目的用户信息。
一键设置 git 账号
在_已有的项目_下,我们可以通过一个命令实现修改远程仓库的地址信息。(前提是你的远程地址是 ssh 格式的,你可以通过在项目下输入 git remote -v
命令查看到类似于 git@HOST:user_name/repository_name.git
的结果。注:如果看到的输出是 url 类型的(含 origin https://github.com),则可以参照附录中方法修改为 ssh 类型的)
编辑 ~/.gitconfig
文件,在 alias
节下添加以下内容:
[alias]
changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
此后,你可以通过输入 git changeremotehost [default host] [host you want change to]
:
$ git remote -v # 查看修改前的远程仓库地址。 注:如果看到的输出是 url 类型的(含 origin https://github.com),则可以参照附录中方法修改为 ssh 类型的
origin git@github.com:snow08/snow08.github.io.git (fetch)
origin git@github.com:snow08/snow08.github.io.git (push)
$ git changeremotehost github.com github_pro
$ git remote -v # 查看修改后的远程仓库地址
origin git@github_pro:snow08/snow08.github.io.git (fetch)
origin git@github_pro:snow08/snow08.github.io.git (push)
如果是需要 pull 一个新的(本地没有的)私有仓库(公有仓库可以不设置账号来 pull),亦可直接在项目托管平台上选择 ssh ,然后将 @github.com (以 github 为例),改为你所配置的账号的 host (参照上文 [git 远程设置](#git 远程设置) )。

一键设置账号和身份信息
如果我们在 ~/.ssh/config
中的 Host
与 git config --global --list
中 user.$1.name
(参见 [设置全局 git 配置标识](设置全局 git 配置标识) ) 的 $1
相同,则可以通过添加以下别名,一键设置已有仓库的账号信息和身份信息。
git config --global alias.setgit '! git identity $2; git changeremotehost $1 $2'
然后,我们就可以通过 git setgit [default host] [host/user you want change to]
来一键设置 git 。
附录: url 类型转 ssh 类型
首先看一下两种类型的样子:
$ git remote -v # 下方输出 url 类型的
origin https://github.com/ArnaudRinquin/arnaudrinquin.github.io.git (fetch)
origin https://github.com/ArnaudRinquin/arnaudrinquin.github.io.git (push)
$ git remote -v # 下方输出 ssh 类型的
origin git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (fetch)
origin git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (push)
我们可以通过手动修改当前项目下的 .git/config
文件,将 [remote "origin"]
节下的 url 改成 git@host
格式的,然后保存即可。
也可以通过命令 git remote set-url origin git@[gitserver]:[user_name]/[repository_name].git
来修改(对应替换相应位置,如上例则为 git remote set-url origin git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git
)
添加别名,一键修改
git config --global alias.url2ssh "! git remote -v | grep fetch | sed s/..fetch.// | sed s/https.../git@/ | sed 's/\//\:/1' | xargs git remote set-url"
以后,则只需在 url 类型的项目下运行 git url2ssh
即可一键将 url 类型的远程链接转换为 ssh 类型的