问题背景与目标
问题背景
很多单位,包括不仅限于国防相关的保密单位和各种企业的研发部门,大约都有严格的保密要求,总有一些代码是不想放到GitHub上开源,甚至不希望通过网络进行传输的。这时如果还想享受到git方便有效的版本管理功能,在项目协作中提升效率,就非常有必要建立一个在单位/部门局域环境下的git服务器。
有时候,条件甚至会更加苛刻。程序的运行可能依赖于复杂的系统设置,而课题组只有一台高性能的服务器符合要求,多名同学/员工使用不同的账户在同一个服务器上工作,为保证系统安全,他们也不能都被授予root权限。
而且现有的条件(自然包括经费)不希望取一个单独的内网服务器用作git服务器——对于大多数小型项目,这都是毫无必要的,这意味着现存网络上容易搜到的git服务器搭建教程不起作用。
实现目标
因此我们希望在同一台服务器上,实现git远程仓库的功能并建立多个账户分别独立的git仓库,如同使用多台独立设备一样运行于同一个系统环境中,并可以通过git协作,进行版本管理和多分支协同开发。
实现方式
git基本原理回顾
可以参考网上的相关资料,例如这篇。大体上说,git是一个分布式的代码管理工具,从原理上讲,远端仓库不需要是GitHub或者Gitee等,在git官方的文档里也写道:
词语“远程”未必表示仓库在网络或互联网上的其它位置,而只是表示它在别处。
在这样的远程仓库上工作,仍然需要和其它远程仓库上一样的标准推送、拉取和抓取操作。
并明确的指出了
你完全可以在一个“远程”仓库上工作,而实际上它在你本地的主机上。\
这说明我们的目标是完全可行的,只是这样的实践较少而已。
建立一个git服务器
参考官方教程,需要在服务器合适的位置建立一个裸仓库作为“远程仓库”。例如根目录下的/gitlib/中创建一个目录code.git,并初始化,代码为:
cd /
mkdir gitlib
mkdir gitlib/code.git
cd gitlib/code.git
git init --bare --shared
这样就创建好了一个空白的仓库,按照教程中所说创建好再传输/复制也是可以的。
这的确是架设一个几个人拥有连接权的 Git 服务的全部
克隆仓库
然后需要创建一个本地仓库(虽然“远程仓库”也在本地吧)
一般来说,克隆的语法是这样的例如
git clone user@git.example.com:/srv/git/my_project.git
但其实clone后面只要是个可访问的url就行,因此在本机上,我们只需要输入
git clone /gitlib/code.git
就可以了。此时在你用于克隆的那个个人本地仓库的目录下访问
git remote -v
同样会看到origin正常显示为刚才输入的文件路径。clone和pull操作仅需要读取权限,因此同样不麻烦。
push操作
身份管理
通常情况下,我们默认一台计算机由一个用户操作,我们需要通过下面的命令:
git config --global user.name "username"
git config --global user.email useremail@qq.com
这里的–global针对整台计算机上的姓名和email进行了设置,为了让一台机器上的不同用户使用不同的名称提交,我们采用不带–global的版本,即:
git config user.name "username"
git config user.email useremail@qq.com
这里配置是面向每一个“本地仓库”的了。
权限管理
为了实现push,需要让用户拥有写权限。我们需要为这个仓库创建一个Linux用户组,例如叫grp:
groupadd grp
将需要协作的成员加入这个组grp中,随后,利用root权限将这个组设为“远程仓库”的拥有者:
chown :grp /gitlib/code.git
可以使用代码查看文件夹权限:
ls -l /gitlib
此后,在grp组中的各用户都可以正常push了。不在组中的用户,可以clone仓库和拉取代码更新,但不能推送,这和GitHub上协作者与非协作者的表现类似。
git用户方案
在教程还提供了一种方案,即使用git用户在其目录下创建git远程仓库并访问。通过ssh访问本机ip并使用git用户的账户连接,理论上是可能的,但听起来有些怪,如果有需要并有兴趣的朋友可以尝试一下,由于我们在“本地仓库”配置了身份信息,使用git用户登录并不会影响git log中显示的提交者用户身份,同样可以满足我们的需求。