《精通git第二版》读书笔记·ch04 服务器端的git
与他人合作的最佳方式是建立一个共用的仓库。
远程仓库通常是一个裸仓库(没有当前工作目录的仓库),类似于只有.git
目录。
传输协议
git支持Local、HTTP、SSH、git四种协议来传输数据。具体如下:
- Local(本地协议)。远程版本库为硬盘内的一个目录,通过
git clone "/xxx/xxx.git"
访问,使用硬连接或者直接复制文件。file:///xxx/xxx.git
形式触发网络传输进程,获得没有外部参考的干净版本库。优点在于简单,直接使用现有的文件权限和网络访问权限,缺点在于共享文件系统比较难配置,速度不一定快,不便于从多个位置访问,不能保护仓库避免意外损坏。 - 智能HTTP协议。新版本为智能HTTP协议,运行在HTTPS端口上,支持各种HTTP验证机制,使用一个URL即可实现匿名服务和授权加密,而且HTTPS协议使用广泛。但是配置智能HTTPS协议相对复杂。
- 哑HTTP协议。旧版本为哑HTTP协议,只把裸仓库当作普通文件,提供文件服务。git自带的
post-update
钩子,可以设置从HTTP访问版本库。设置见下文。 - SSH协议。使用ssh协议传输,架设简单,访问安全(数据传输经过授权和加密),高效(传输前压缩)。缺点在于不能实现匿名访问。访问形式为
ssh://xxx
或者user@server:xxx.git
。 - git协议。git自带一个特殊的守护进程,监听在9418端口,访问无需授权。git协议传输速度最快,但是缺乏授权机制。
1
2
3
4
5
6
# 设置git的post-update钩子
cd /var/www/hosts # web服务器地址
git clone --bare /xxx xxx.git
cd xxx.git
mv hooks/post-update.sample hooks/post-update
chmod a+x hooks/post-update
搭建ssh协议仓库
首先将仓库导出为裸仓库。
1
git clone --bare "xxx" "xxx.git"
假设已经建立好git.example.com
的服务器,可以通过ssh连接,在/opt/git
目录下放置git仓库。将裸仓库放到仓库目录下后,有ssh访问权限的用户就可以访问了。
1
2
cd /opt/git/xxx.git
git init --bare --shared # 自动修改目录的组权限为可写
架设git服务复杂的地方在于用户管理,特别是对不同的用户设置不同的权限。如果团队的每个人都需要对仓库有写权限,有几种解决方式:
- 给每个人设置ssh账号。
- 建立一个git账户,将每个人的ssh公钥写入git账户的认证文件。可以将登录shell设置为
git-shell
限制活动。 - 让ssh服务器通过LDAP服务或者其他集中授权机制进行认证。
默认情况下密钥存储在~/.ssh
下,以id_dsa
或id_rsa
命名,.pub
后缀为公钥,另一个是私钥。在linux/mac下可以用ssh-keygen
生成,win下位于MSysGit
软件包。更多参考:https://docs.github.com/cn/github/authenticating-to-github/connecting-to-github-with-ssh。
搭建git协议仓库
使用git协议建立仓库,可以实现快速的、无需授权的访问。建议只对只读项目应用,并且强烈建议使用一个对仓库具有只读权限的用户来运行任务。
1
2
3
4
git daemon --reuseraddr --base-path=/opt/git/ /opt/git/ # 启动守护进程
cd "xxx.git"
touch git-daemon-export-ok # 开启访问
搭建智能HTTP协议仓库
在web服务器上启用git-http-backend
的CGI脚本即可,例如使用apache作为web服务器。
1
2
3
4
5
6
apt-get install apache2 apache2-utils
a2enmod cgi alias env # 启动模
SetEnv GIT_PROJECT_ROOT /opt/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
留空GIT_HTTP_EXPORT_ALL
,则对于未授权客户端只提供git-daemon-export-ok
的仓库。
配置apache,接受路径请求。
1
2
3
4
5
6
<Directory "/usr/lib/git-core*">
Options ExecCGI Indexes
Order allow,deny
Allow from all
Require all granted
</Directory>
实现写操作授权。
1
2
3
4
5
6
<LocationMatch "^/git/.*/git-receive-pack$">
AuthType Basic
AuthName "Git Access"
AuthUserFile /opt/git/.htpasswd
Require valid-user
</LocationMatch>
然后通过以下命令添加授权用户。
1
htdigest -c /opt/git/.htpasswd "Git Access" "xxx"
GitWeb
git提供了gitweb的CGI脚本,用来以简单网页的形式展示仓库。
Linux一般安装了lighttpd
服务器,mac可以用webrick
,这两个是轻量级web服务器。
1
2
git instaweb --httpd=webrick # 启动web服务,在1234端口
git instaweb --httpd=webrick --stop # 关闭web服务
如果要长久运行,一些linux发行版提供了gitweb包,也可以手动编译。然后配置web服务器。
GitLab
GitLab是git服务器的一个开源解决方案,一个数据库支持的web应用。基本概念如下:
- 使用者。GitLab上的用户,即协作者账号。每个账号一个命名空间,即项目的逻辑集合。屏蔽会阻止用户登录GitLab,但是保留所有数据。销毁则彻底删除用户的数据。
- 组。一些项目的集合,附加多少用户可以访问这些项目。每个组一个命名空间,有许多用户与之关联,且每个用户对于组中的项目、组本身具有不同的权限。
- 项目。相当于git的版本库。每个项目属于一个用户或者一个组的单个命名空间。每个项目有一个可视层级,控制着项目的可见性。
- 钩子。在项目和系统级别,支持钩子程序。
优点在于配置服务器并运行后,绝大多数的日常管理和使用都可以在浏览器中完成。
使用GitLab进行协作有两种方式:直接赋予协作者push权限和使用合并请求。对于可以直接访问的协作者,可以创建分支,在分支上提交,然后合并到其他分支。对于没有推送权限的协作者,fork版本库(创建自己的副本),向副本提交,从副本开启到主项目的合并请求。对每一个合并请求,可以进行轻量级代码审查,或者对话题进行讨论。
github
对GitHub的详细讲解查看github章节。
第三方托管服务
参考Git维基:https://git.wiki.kernel.org/index.php/GitHosting。
参考
《精通git第二版》