图解Git——服务器上的Git《Pro Git》
协议
1. Git 远程仓库及通信协议概述
1.1. 远程仓库的重要性
- 作用:提供协作平台,支持团队共享代码,即使主机离线,其他人仍可访问。
- 常见形式:裸仓库(不含工作目录,仅保存 Git 元数据)。
2. Git 支持的协议类型
1. 本地协议
- 适用场景:
-
- 在同一台主机或共享文件系统(如 NFS)上使用。
- 优点:
-
- 配置简单,速度快。
- 利用现有文件权限,方便与团队快速共享代码。
- 缺点:
-
- 依赖共享文件系统,不便于远程访问。
- 无法防止用户直接修改或破坏仓库文件。
2. ⭐HTTP/HTTPS 协议
- 智能 HTTP 协议:推荐方式,支持用户名/密码授权,传输数据加密,适合现代协作场景。
- 哑(Dumb)HTTP 协议:仅支持只读访问,简单易配置。
- 优点:
-
- 简单易用,广泛支持(企业防火墙通常允许)。
- 支持 HTTPS 提供安全传输,可灵活设置匿名和授权访问。
- 缺点:
-
- 需要维护证书,授权管理比 SSH 复杂。
3. SSH 协议
- 适用场景:企业内部协作和需要安全访问的场景。
- 优点:
-
- 配置简单,内置于大多数操作系统中。
- 提供加密传输和用户验证,速度高效。
- 缺点:
-
- 不支持匿名访问,需手动配置公钥,增加新用户的设置成本。
4. Git 协议
- 特点:基于特殊的 Git 守护进程,支持匿名访问,无需授权。
- 优点:
-
- 性能最高,适合高访问量或只读场景。
- 缺点:
-
- 无授权机制,无法提供推送权限管理。
- 需要开放非标准端口(9418),配置复杂。
3. 总结与选择
- 本地协议:适合团队在共享文件系统上使用,但局限于单一网络环境。
- HTTP/HTTPS 协议:推荐智能 HTTP,适合绝大多数团队协作场景。
- SSH 协议:适合企业内部使用,安全且高效。
- Git 协议:适合提供高效只读访问,但不适用于需要授权控制的场景。
选择协议时,可根据协作需求、访问场景、安全性和配置难度进行权衡。
服务器上搭建 Git
1. 创建裸仓库
- 使用
--bare
选项将现有的 Git 仓库导出为裸仓库,这样仓库不包含工作目录,适用于服务器上的协作:
$ git clone --bare my_project my_project.git
或者:
$ cp -Rf my_project/.git my_project.git
2. 上传裸仓库到服务器
- 假设服务器域名为
git.example.com
,将裸仓库上传到服务器的指定目录(如/srv/git
):
$ scp -r my_project.git user@git.example.com:/srv/git
3. 初始化共享仓库
- 登录到服务器,进入仓库目录,并使用
--bare
和--shared
初始化仓库,这样仓库对同组用户可写:
$ ssh user@git.example.com
$ cd /srv/git/my_project.git
$ git init --bare --shared
4. 团队成员克隆仓库
- 其他团队成员可以使用以下命令通过 SSH 克隆仓库:
$ git clone user@git.example.com:/srv/git/my_project.git
5. 用户权限管理
- 为每个用户创建服务器账户:通过在服务器上为每个开发者创建独立账户,使用操作系统的文件权限来控制访问。
- 使用共享账户管理 SSH 密钥:创建一个
git
用户,团队成员将各自的 SSH 公钥添加到该用户的~/.ssh/authorized_keys
文件中,所有用户通过git
账户访问仓库。 - 集中授权机制:可以使用 LDAP 或其他集中管理工具来控制访问。
6. 适用场景
- 这种简单的设置适合小型团队或初创项目,只需 SSH 连接和裸仓库即可实现团队协作。
- 如果需要更复杂的权限控制或功能扩展(如公共访问、网页界面),可以在此基础上进行改进。
总结:通过裸仓库和 SSH 配合,你可以轻松在服务器上搭建 Git 服务,满足基本的团队协作需求。对于更复杂的需求,可以进一步扩展和优化。
生成 SSH 公钥
1. 检查现有SSH密钥
- SSH密钥默认存储在
~/.ssh
目录下,可以通过以下命令检查是否已有密钥:
$ cd ~/.ssh
$ ls
你需要找到一对文件(例如 id_dsa
和 id_dsa.pub
或 id_rsa
和 id_rsa.pub
),.pub
文件是公钥。
2. 生成新的SSH密钥
- 如果没有现有的密钥,可以使用
ssh-keygen
生成一对新的公钥和私钥:
$ ssh-keygen -o
- 它会询问你密钥存储位置(默认是
~/.ssh/id_rsa
)和是否设置密钥密码。如果不想输入密码,可以留空。使用-o
选项来生成更安全的密钥格式。
3. 查看公钥内容
- 创建完成后,可以使用以下命令查看生成的公钥内容:
$ cat ~/.ssh/id_rsa.pub
该输出是公钥,你需要将它发送给 Git 服务器管理员,以便添加到服务器的 authorized_keys
文件中。
4. 发送公钥
- 将公钥(
.pub
文件中的内容)通过邮件或其他方式发送给 Git 服务器管理员,管理员将其添加到服务器上进行认证。
5. 避免频繁输入密码
- 如果设置了密钥密码,可以使用
ssh-agent
工具来避免每次连接时输入密码。
通过上述步骤,你可以轻松生成 SSH 公钥,并将其用于 Git 服务器的 SSH 验证。
配置服务器
1. 创建系统用户和配置 SSH
- 创建操作系统用户
git
,并为其建立.ssh
目录:
$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
- 将受信任的公钥添加到
authorized_keys
文件中:
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys
2. 创建 Git 仓库
- 使用
git init --bare
创建裸仓库:
$ cd /srv/git
$ mkdir project.git
$ cd project.git
$ git init --bare
3. 开发者推送到仓库
- 开发者通过 SSH 推送项目:
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/srv/git/project.git
$ git push origin master
4. 克隆和推送改动
- 其他开发者克隆仓库并提交改动:
$ git clone git@gitserver:/srv/git/project.git
$ cd project
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master
5. 限制 SSH 访问权限
- 使用
git-shell
作为限制 shell,防止开发者获取普通 shell 访问权限:
$ sudo chsh git -s $(which git-shell)
这样,开发者只能通过 SSH 执行 Git 操作,无法访问普通 shell。
6. 配置 SSH 限制选项
- 为了避免开发者使用 SSH 端口转发等功能,可以在
authorized_keys
文件中添加以下选项:
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...
7. 自定义 Git Shell
- 可为
git-shell
添加自定义配置来限制 Git 命令或显示自定义的登录信息。
Git 守护进程
1. Git 协议简介
- Git 协议适用于不需要授权的快速访问,适合只读项目,且一般无需配置 SSH 公钥。使用此协议时,内容会暴露给所有人,通常用于公开的只读项目或自动系统(如 CI/CD)。
2. 启动 Git 守护进程
- 启动 Git 守护进程:
$ git daemon --reuseaddr --base-path=/srv/git/ /srv/git/
-
--reuseaddr
:允许服务器重启时无需等待旧连接超时。--base-path
:指定仓库的基本路径,允许通过简短路径来访问仓库。
3. 防火墙配置
- 需要开放 9418 端口供 Git 守护进程通信。
4. 使用 systemd 启动 Git 守护进程
- 在
/etc/systemd/system/git-daemon.service
文件中添加服务配置:
[Unit]
Description=Start Git Daemon
[Service]
ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/
Restart=always
RestartSec=500ms
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=git-daemon
User=git
Group=git
[Install]
WantedBy=multi-user.target
- 使其在启动时自动运行并监控守护进程:
$ sudo systemctl enable git-daemon
$ sudo systemctl start git-daemon
$ sudo systemctl stop git-daemon
5. 创建 git-daemon-export-ok
文件
- 要允许仓库通过 Git 守护进程进行无授权访问,在仓库目录中创建
git-daemon-export-ok
文件:
$ cd /path/to/project.git
$ touch git-daemon-export-ok
这样,Git 守护进程就会为公开仓库提供无需授权的访问服务。
Smart HTTP
1. Smart HTTP 协议
- Smart HTTP 结合了 SSH 授权访问和 git:// 无授权访问,允许通过 HTTP 进行智能或哑模式的 Git 操作。
-
- 智能模式(Smart mode):适用于支持智能协议(Git 1.6.6 及以上版本的客户端),提供更高效的通信。
- 哑模式(Dumb mode):适用于老旧的 Git 客户端,不支持智能协议,回落到兼容模式。
2. 启用 Git HTTP 后端
- 在服务器上启用 Git 的
git-http-backend
CGI 脚本,该脚本处理通过 HTTP 协议发送的请求,并判断是否使用智能协议。
3. 安装 Apache 及必要模块
- 安装 Apache Web 服务器并启用必要的模块:
$ sudo apt-get install apache2 apache2-utils
$ a2enmod cgi alias env
- 启用
mod_cgi
,mod_alias
, 和mod_env
模块,使其支持 Git HTTP 请求。
4. 设置文件权限
- 将仓库的 Unix 用户组设置为
www-data
,让 Web 服务器可以访问 Git 仓库:
$ chgrp -R www-data /srv/git
5. 配置 Apache
- 在 Apache 配置文件中添加以下内容,处理 Git 请求:
SetEnv GIT_PROJECT_ROOT /srv/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
GIT_HTTP_EXPORT_ALL
:当启用时,Git 会对所有仓库提供 HTTP 访问(无授权),否则只提供带有git-daemon-export-ok
文件的仓库。
6. 设置授权访问
- 如果需要对写操作进行授权控制,可以在 Apache 配置中添加以下授权设置:
<Files "git-http-backend">
AuthType Basic
AuthName "Git Access"
AuthUserFile /srv/git/.htpasswd
Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#)
Require valid-user
</Files>
-
- 这会要求用户使用基本认证进行授权,除非是
git-receive-pack
请求。 - 使用
htpasswd
工具创建.htpasswd
文件并添加用户:
- 这会要求用户使用基本认证进行授权,除非是
$ htpasswd -c /srv/git/.htpasswd schacon
7. SSL 加密传输
- 可以通过启用 SSL 保障 HTTP 请求的加密传输,确保安全。
8. Web 服务器选择
- 虽然示例中使用 Apache,但只要能处理 CGI 脚本的 Web 服务器都可以用来实现 Smart HTTP。
9. 相关链接
- 若想深入了解 Apache 配置授权访问的信息,请参考 Apache 文档。
这样配置后,你就可以通过 Smart HTTP 协议为 Git 仓库提供高效且安全的访问。
GitWeb
GitWeb 是一个用于展示 Git 项目的网页界面,通常通过 CGI 脚本来运行。搭建和使用 GitWeb 的步骤如下:
1. 临时启动 GitWeb 服务器:
-
- 在项目目录中使用
git instaweb
命令来启动一个临时的网页服务器。如果使用 Mac 系统,可以加上--httpd=webrick
参数来使用webrick
服务器,默认监听端口为 1234。可以使用以下命令启动:
- 在项目目录中使用
$ git instaweb --httpd=webrick
-
- 若要关闭服务器,可以使用:
$ git instaweb --httpd=webrick --stop
2. 为持续访问设置 Web 服务器:
-
- 如果需要持续运行 GitWeb,需通过常规的 Web 服务器(如 Apache)来部署 GitWeb。
- 安装 GitWeb:
-
-
- 克隆 Git 源代码并编译:
-
$ git clone git://git.kernel.org/pub/scm/git/git.git
$ cd git/
$ make GITWEB_PROJECTROOT="/srv/git" prefix=/usr gitweb
-
-
- 将生成的 GitWeb 文件复制到 Web 服务器的根目录:
-
$ sudo cp -Rf gitweb /var/www/
-
- 配置 Apache 虚拟主机以支持 CGI 脚本:
<VirtualHost *:80>
ServerName gitserver
DocumentRoot /var/www/gitweb
<Directory /var/www/gitweb>
Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
AllowOverride All
Order allow,deny
Allow from all
AddHandler cgi-script cgi
DirectoryIndex gitweb.cgi
</Directory>
</VirtualHost>
3. 访问 GitWeb:
-
- 配置完成后,可以通过访问
http://gitserver/
来查看你的 Git 项目。
- 配置完成后,可以通过访问
通过这些步骤,你可以使用 GitWeb 为你的团队或开源项目提供一个网页查看界面。
GitLab
GitLab 是一个功能全面的 Git 服务器,提供了丰富的协作和项目管理功能。其安装和使用过程较为复杂,涉及到数据库支持,但提供了详细的文档和支持,下面是安装和管理 GitLab 的关键步骤:
安装 GitLab
- 快速启动:可以通过下载虚拟机镜像或使用 Bitnami 提供的一键安装包来快速启动。
-
- Bitnami GitLab:提供了登录界面,可以方便地获取 GitLab 的 IP 地址及默认的用户名和密码。
- GitLab 社区版:通过官方文档(GitLab 社区版 GitHub 仓库)进行安装,支持在 DigitalOcean 上运行虚拟机,或使用 RPM 和 DEB 包。
管理 GitLab
- 登录:通过浏览器访问安装好的 GitLab 主机,使用默认用户名
admin@local.host
和密码5iveL!fe
登录。 - 管理界面:登录后可以通过点击界面上的“Admin area”图标进入管理界面,进行各种管理操作。
用户和权限管理
- 用户账号:每个用户有一个命名空间,表示其项目的集合。用户可以通过该命名空间访问其拥有的项目。
- 移除用户:
-
- 屏蔽用户:阻止登录,但保留数据。
- 销毁用户:彻底删除用户及其数据。
- 组:多个项目的集合,组内用户有不同权限级别,从“访客”到“拥有者”,决定其访问项目的权限。
项目管理
- 项目:GitLab 中的项目等同于 Git 版本库,属于用户或组的命名空间。项目可以设置为私有、内部或公开,控制访问权限。
- 钩子:支持在项目和系统级别配置钩子,自动化连接其他开发工具(如 CI 服务器)。
协作与贡献
- 创建项目:通过点击“+”图标创建新项目,填写项目名称、命名空间及可视级别。
- 协作者:为项目添加协作者并指定访问级别(如“Developer”),允许其进行代码提交。
- 合并请求:允许协作者通过分支和合并请求向主项目贡献代码,支持代码审查。
其他功能
- Wiki:每个项目可以有一个 Wiki,用于文档和项目说明。
- 日常管理:GitLab 的大部分管理操作可以通过 Web 界面进行,无需频繁修改配置文件。
GitLab 提供了强大的版本控制、团队协作和项目管理功能,适合中到大型开发团队使用。
第三方托管的选择
第三方托管服务为 Git 项目提供了便捷的托管选项,避免了自己维护服务器的麻烦,并提供了一些额外的好处,特别是在开源社区的曝光度和协作方面。以下是选择第三方托管服务的一些要点:
第三方托管的优势:
- 快速开始:无需设立和维护自己的 Git 服务器,可以直接将项目托管到专业平台。
- 维护轻松:托管服务提供了基础设施和监控,不需要自己处理这些问题。
- 开源曝光:通过公共托管平台(如 GitHub)托管开源项目,可以让更多的人发现并参与项目,帮助项目更快成长。
托管平台选择:
- 市面上有许多 Git 托管平台,各平台提供不同的功能、界面和权限控制。
- 可以根据项目需求选择合适的平台。
- GitHub 是当前最大的 Git 托管平台,广泛用于开源项目,并且提供强大的协作工具,如 Pull Request 和 Issue 跟踪。
推荐:
- 如果你希望把开源代码托管给更多开发者发现和贡献,选择一个公共的托管平台(如 GitHub)是一个不错的选择。
- 即使你已经有自己的 Git 服务器,仍然可以将开源项目托管到这些第三方平台,从而提高项目的可见度和参与度。
可以查看 Git 维基的 GitHosting 页面 获取更多托管平台的信息。
总结
远程存取 Git 仓库提供了多种选择,方便与其他人合作或分享工作。选择托管服务器或自行运行服务器都有各自的优缺点,适合不同的需求和环境:
选择远程存取 Git 仓库的方式:
- 自行运行服务器:
-
- 优点:可以完全掌控权限和配置,仓库数据在自己的防火墙内,更有控制权。
- 缺点:需要投入大量时间和精力进行服务器设置、维护和监控。
- 使用第三方托管服务器:
-
- 优点:易于设置和维护,无需关注基础设施管理。适合快速启动和共享项目,尤其是开源项目。
- 缺点:依赖第三方服务,可能会遇到访问限制或安全担忧,某些组织可能不允许将代码存放在外部服务器。
决定因素:
- 如果安全性和完全控制对你很重要,且能投入足够的资源来维护服务器,可能会选择自己搭建 Git 服务器。
- 如果便捷性和快速启动是首要考虑,且可以接受将代码存储在外部服务器,那么使用托管服务(如 GitHub、GitLab)是更为便捷的选择。
在选择时,组织的安全策略和资源能力是关键决策因素。