今天还真写了不少东西!
以前一直在Ubuntu上操作gitolite托管git仓库,近日需要在Win8.1平台上写代码,众所周知git是linux世界的东西,即使MinGW和GitHub for Windows解决了大问题,但一些常用架构和服务框架还是没法在Windows平台上使用的,比如gitolite这个方便的git托管服务器维护工具!
关于gitolite一直想写篇文章介绍一下怎么实际安装和操作,一会儿再动笔,先打个标记在这里,等不及的可以先看官方文档(其实挺简单)
在Linux平台上使用gitolite托管版本库,我一直都是用分布式单用户流程,用密钥直接操作,现在启用Windows平台,就相当于添加了一个用户给gitolite,本文就顺便科普的详细带你走一边给gitolite添加新用户的流程吧。
准备好git
没git还玩儿什么呀?尚没准备好的,请猛戳我这篇文章:《Win8 64-bit上运行emacs 24.5 64-bit》
准备密钥
这里分两种方法,请详细看完并认真选择。
第一种情况:“一把钥匙走天下”(不推荐)
如果你喜欢用一对儿密钥登录所有地方,虽然不是很安全,但方便倒是真的,那就这么办:
进入Linux(或者你存放钥匙对儿的地方),把公钥私钥都拿回到Windows上来。
第二种情况:“我是一个认真的人”
如果你喜欢为每一个环境(场合)配一对儿钥匙,那就这么办,打开”Git Shell”(随GitHub for Windows一起安装的),在Win8.1平台上默认情况下应该是包装过的Windows Powershell. 在Git Shell里面,许多Linux的命令是可以直接使用的(比如ls/mv/cp),很方便。
1 | cd ~/.ssh/ |
上面的命令是进入Home主目录里面的.ssh目录中(这里存放着key相关的所有东西),使用ssh-keygen命令生成新的公钥私钥对儿,当问到下面这句话时,是让你输入密钥的名称,这里我们输入:test
1 | Enter file in which to save the key |
这句设置密钥的密码
1 | Enter passphrase (empty for no passphrase): |
直接两次回车,留空就好,本例子不需要。
回车之后,会显示出RSA 2048的散列图(也可以用其他加密算法,在这里不详细叙述),同时生成”test”(私钥)和”test.pub”(公钥)

上图中的”test”和”test.pub”就是我们要的密钥对儿,图上还能看出我有其他几个密钥,其中”william_laptop_ubuntu”和”william_laptop_win”是我这两个平台上的密钥,我的密钥管理的比较多,所以起的名字都比较复杂,建议走第二条路的童鞋也养成这样儿好习惯,省的将来一堆id_rsa头都大了。
好,两条路都可以,我们拿到自己的密钥对儿了,进入下一步。
获得权限
gitolite的权限分配和仓库维护,都是通过gitolite-admin.git这个特殊的git版本库来完成的(设计真的很奇妙),在本地修改相应配置后直接推送到服务器上,服务器就会根据修改做出相应的动作,所以我们首先要获得这个特殊的管理库。
那么问题来了,因为现在我们不具有访问gitolite托管库的权限,所以根本无法clone回来这个库,怎么办呢?有的童鞋可能会想,进Linux,把那儿的gitolite-admin.git考回来呗。那样做其实是无用的,因为还是不具有推送的权限。
所以首先要做的,就是获得管理员(或相应角色的)权限,这里分情况:
如果在上一步中你选了第一条路(一把钥匙走天下),而且是把Linux中的公钥私钥都给考回来了,那就请直接跳到下一步(4)。
如果是按照本文一步步生成密钥来到这里的,那么我们开始,这里我们要做一个大动作,就是带着你新生成的公钥(不是私钥,是带.pub的那个文件)回到Linux中,然后进入本地的gitolite-admin目录中(服务器上gitolite-admin.git的克隆),因为回到Linux之后,我们是有权限操作gitolite的,我们就从那里,把Windows中生成的公钥提供给gitolite,让他认了Windows这个干爹~
进入gitolite-admin目录,我们会看到”keydir”和”conf”两个目录,为了更直观一些,我们抛弃之前那个test名字,假定我们生成密钥那一步生成的是”william_laptop_win”这一对儿。
先进入keydir目录,将”william_laptop_win.pub”拷贝到这个目录里,因为原来Linux中的用户已经获得权限,所以等拷贝完成时,这个目录现在有两个文件william_laptop_ubuntu.pub和william_laptop_win.pub.
然后让我们回到conf目录中,用编辑器打开”gitolite.conf”
我的配置大致是这个样子:

第一行定义了一个用户组,原来只有”william_laptop_ubuntu”一个用户,现在要多一个了,因为都是我,所以组名叫做”william”,在ubuntu之后空一格,添加我们新的用户”william_laptop_win”,这里要注意,名字要和”keydir”中的公钥名称相同(”william_laptop_win”),这样才能形成对应关系。
下面的一堆repo是我的托管库中的一部分版本库,这里每一个repo都是在定义上面的用户在该版本库中具有什么样的权限,我这里偷懒了,注意看第一个repo段,@all表示全部版本库(或者全部用户),这段定义的意思是,@william这个用户组对@all(所有版本库)都有RW+(管理员)权限,随后的所有repo都只是个声明,用来操作gitolite新建对应版本库。
到这里,明白为什么“一把钥匙”的童鞋可以直接跳到下一步了吧?因为那样根本就是在用之前的用户,而不是新建用户,那样多没意思~
完成拷贝和修改动作之后,在当前目录(gitolite-admin目录中的任意位置)将更改提交给服务器:
1 | cd ~/path/to/gitolite-admin/ |
如果push成功,表示用户已经添加完毕了,让我们进入下一步,回到Windows…
配置ssh的config
终于又回到Windows下了,现在的状况是服务器已经知道他还有个干爹叫”william_laptop_win”,只是还没见面,没关系,咱这就认亲去!
还是打开Git Shell,”cd ~/“进入主目录,”cd .ssh”进入ssh目录,接下来我们要用到一个ssh封装别名组的小技巧来声明使用哪个私钥去访问哪个服务器:
1 | host gandie-win |
第一行是给封装取个别名,user那里是”git”,因为gitolite就是在服务器的git用户名下运行的(参考安装使用gitolite那篇文章),默认端口22
这里关键是最后一行,identityfile指定具体用哪个私钥去跟服务器上的公钥配对,这里我们用服务器上(刚才已经推送到服务器上了)的william_laptop_win.pub对应的这个私钥。
还有个小技巧,如果你之前把Linux的密钥对儿也拷过来了,这里可以紧接着定义一个新的别名段,让你可以随时以不同的身份与服务器通信(不推荐):
1 | host gandie-win |
为什么不推荐呢,因为这样在git log查看日志或者别的操作的时候,就分不清是哪个用户提交的推送了(明明是在Windows下推的,用的身份却是Ubuntu的)
认亲
假定你完成了第4步,这一步就简单了:git clone gandie-win:gitolite-admin.git,把gitolite-admin克隆到本地,看到”gandie-win”了吗?它就是我们上一步最后定义的别名组,当然如果也定义了”gandie-ubuntu”组,这里用也是可以的……
如果一切顺利,克隆完成,恭喜你,认亲成功!再有组员基友什么的想用你的服务器托管代码,就不用再切换回Linux操作了,从Windows中将他的公钥和用户名添加到gitolite-admin中推送,让他去clone只属于他自己的项目,就OK了。
最后一个gitolite的高频率使用功能之一:ssh gandie-win
这个ssh命令并不能真正登录到服务器中(因为git用户是锁死的),而是返回对应的用户所有拥有权限的代码库的名字列表,以及所具有的对应权限,并中断连接。

后记
记得我多年前第一次使用密钥对儿登录某服务器的时候,给我的感觉就是:“哇擦居然不要密码!这样安全吗?”其实这个问题这么些年从来没消失过,谈的多了就是网络安全,那话题就太沉重了,别问我为什么,我不想说T_T,总之培养良好的安全意识比什么铁腕儿手段都来的重要,看好你的私钥和闭口不谈密码是一样重要,也是一样安全(或不安全)的。
还是建议童鞋们,该给密钥加passphrase就一定要加,也千万别一把钥匙即开门锁又开保险柜!
最后,希望能对你有帮助。