卖兜搞IT

在多个git服务器和用户之间进行切换的终极解决方案

在多个git服务器和用户之间进行切换的终极解决方案

在网上看到有人往GitHub提交commit的时候不小心使用了公司的邮箱,结合网友的回复,想把这个问题梳理一下再。

Image

以上图片来自网络

为了演示这个问题,本文使用GitHub来模拟公司的git服务器,GitLab模拟私人的。往GitHub提交代码使用的公司的邮箱和用户名,往GitLab提交代码使用私人的邮箱和用户名

多个用户的验证问题

建议使用SSH Key加上 SSH config的方式。

首先使用 ssh-keygen 命令生成两对SSH key pair

$ ls .sshgithub  github.pub  gitlab  gitlab.pub

分别把public key上传到GitHub和GitLab

https://github.com/

https://gitlab.com/

准备ssh的config文件, 对于不同的目标服务器使用不同的SSH 私钥

$ more ~/.ssh/configHost github.comIdentityFile/home/penxiao/.ssh/githubUser xiaopeng163Host gitlab.comIdentityFile/home/penxiao/.ssh/gitlab

然后就可以不用密码进行git的clone和commit了

$ git clone git@gitlab.com:zhangsan163/gitlab-test.git$ git clone git@github.com:xiaopeng163/github-test.git$ lsgithub-test  gitlab-test

gitconfig

一般情况下我们会有一个全局的gitconfig, 假如下面是我的公司邮箱的话

more ~/.gitconfig[user]        email = pengxiao@company.com        name =PengXiao

但是这样的问题是,我们进行commit的时候,不管是往Github还是Gitlab都会使用这个username和email进行commit,这样很不好,假如你公司的电脑上,全局的gitconfig是公司的邮箱,而你去commit的一个项目却是一个私人项目,那你的个人信息就泄露了。

最笨的办法

修改每一个项目的git config来覆盖全局的config

比如我想在GitLab的项目里使用下面的邮箱, 而用户名使用global全局的。

➜  gitlab-test git:(main) more .git/config[core]        repositoryformatversion =0        filemode =true        bare =false        logallrefupdates =true[remote "origin"]        url = git@gitlab.com:zhangsan163/gitlab-test.git        fetch =+refs/heads/*:refs/remotes/origin/*[branch "main"]        remote = origin        merge = refs/heads/main[user]        email = pengxiao@private.com

你可以手动修改这个config文件,或者进入到这个项目的文件夹,然后使用命令

$ cd gitlab-test$ git config user.email "[email protected]"

这时候新的commit就会使用这个配置了

➜  gitlab-test git:(main) touch test.txt➜  gitlab-test git:(main)✗ git add test.txt➜  gitlab-test git:(main)✗ git commit -m 'first commit'[main 6737d50] first commit1 file changed,0 insertions(+),0 deletions(-) create mode 100644 test.txt➜  gitlab-test git:(main) git logcommit 6737d50f2cb533db2d42ca2030820088bc3cb960(HEAD -> main)Author:PengXiao<pengxiao@private.com>Date:FriJul212:05:002021+0200    first commitcommit b2abaefa1c786bc9f4427c382afa35cba2ca3a83 (origin/main, origin/HEAD)Author:PengXiao<pengxiao@private.com>Date:FriJul209:41:152021+0000Initial commit(END)

使用git alias或者Linux alias简化命令

http://git-scm.com/book/en/v2/Git-Basics-Git-Aliases

我们的目的是只要是私人的项目,我都想通过下面的命令,修改项目local的config

$ git config user.email "[email protected]"

两条命令,虽然不多,但是也有点麻烦,我们可以通过git alias的用法,把它给简化成一个简单的命令,这个非常像linux的alias, 你可以简化任何你认为复制的命令

git config --globalalias.private'config user.email "[email protected]m"'➜  gitlab-test git:(main) more ~/.gitconfig[user]        email = pengxiao@company.com        name =PengXiao[alias]private= config user.email \"pengxiao@private.com\"➜  gitlab-test git:(main)

这时候每次你只需要运行一次 git private 就ok了

➜  gitlab-test git:(main) more .git/config[core]        repositoryformatversion =0        filemode =true        bare =false        logallrefupdates =true[remote "origin"]        url = git@gitlab.com:zhangsan163/gitlab-test.git        fetch =+refs/heads/*:refs/remotes/origin/*[branch "main"]        remote = origin        merge = refs/heads/main➜  gitlab-test git:(main) git private➜  gitlab-test git:(main) more .git/config[core]        repositoryformatversion =0        filemode =true        bare =false        logallrefupdates =true[remote "origin"]        url = git@gitlab.com:zhangsan163/gitlab-test.git        fetch =+refs/heads/*:refs/remotes/origin/*[branch "main"]        remote = origin        merge = refs/heads/main[user]        email = pengxiao@private.com➜  gitlab-test git:(main)

终极解决方案

这个方案我也是刚从网上学到的。

以上两个方案不管是手动配置还是alias,都需要记住,万一忘了,还是有可能会把公司邮箱泄露出去的。有一个比较好的终极解决方案

•公司项目和私人项目放到不同的目录•在不同的目录使用不同的git config

我们可以使用 git version 2.13开始支持的conditional configuration includes. 文档见 https://git-scm.com/docs/git-config#_includes

首先把项目放到不同的目录:

•公司项目放到company目录•私人项目放到private目录

这样的灵活性就非常非常大了。

➜  tmp mkdir company➜  tmp mkdir private➜  tmp cd company➜  company git clone git@github.com:xiaopeng163/github-test.gitCloninginto'github-test'...remote:Enumerating objects:3,done.remote:Counting objects:100%(3/3),done.remote:Total3(delta 0), reused 0(delta 0), pack-reused 0Receiving objects:100%(3/3),done.➜  company cd ../private➜private git clone git@gitlab.com:zhangsan163/gitlab-test.gitCloninginto'gitlab-test'...remote:Enumerating objects:3,done.remote:Counting objects:100%(3/3),done.remote:Total3(delta 0), reused 0(delta 0), pack-reused 0Receiving objects:100%(3/3),done.➜private cd ..➜  tmp tree ..├── company│└── github-test│└── README.md└──private└── gitlab-test└── README.md4 directories,2 files➜  tmp

创建一个private的git config

➜~ more ~/.gitconfig-private[user]        email = pengxiao@private.com        name =PengXiao➜~

在global的gitconfig里设置当使用私人目录的时候,就加载私人的git config

➜~ more ~/.gitconfig[user]        email = pengxiao@company.com        name =PengXiao[includeIf "gitdir:~/tmp/private/"]  path =.gitconfig-private

我们验证一下,首先是提交公司的项目,可以看到邮箱是使用的公司邮箱

➜~ cd tmp/company/github-test➜  github-test git:(master) touch test.txt➜  github-test git:(master)✗ git add test.txt➜  github-test git:(master)✗ git commit -m 'first commit'[master a64b46f] first commit1 file changed,0 insertions(+),0 deletions(-) create mode 100644 test.txt➜  github-test git:(master) git logcommit a64b46f0cecac00c2791f169a722b805596eec71 (HEAD -> master)Author:PengXiao<pengxiao@company.com>Date:FriJul212:39:332021+0200    first commit

然后我们在测试一下私人项目, 提交的commit就是私人邮箱了。

➜~ cd tmp/private/gitlab-test➜  gitlab-test git:(main) more .git/config[core]        repositoryformatversion =0        filemode =true        bare =false        logallrefupdates =true[remote "origin"]        url = git@gitlab.com:zhangsan163/gitlab-test.git        fetch =+refs/heads/*:refs/remotes/origin/*[branch "main"]        remote = origin        merge = refs/heads/main➜  gitlab-test git:(main) touch test.txt➜  gitlab-test git:(main)✗ git add test.txt➜  gitlab-test git:(main)✗ git commit -m 'first commit'[main b91a660] first commit1 file changed,0 insertions(+),0 deletions(-) create mode 100644 test.txt➜  gitlab-test git:(main) git log➜  gitlab-test git:(main)commit b91a6607e20bb07b55e60ffa7478f25e3d621cd8 (HEAD -> main)Author:PengXiao<pengxiao@private.com>Date:FriJul212:41:592021+0200    first commit

你学会了么。