搭建本身的 Git 服务器

根据 RhodeCode 在 2016 年作过的一项分析报告 Version Control Systems Popularity in 2016,在现在的 VCS(版本控制系统)领域,Git 几乎已经一统江山,在选择本身的 VCS 时,有 87% 的人会选择使用 Git,排在第二名的 SVN 只占 6%,不管是从 Google Trends,仍是在 Stack Overflow 上的提问,均可以看到 Git 的爆发式增加。另外,根据 Eclipse 的社区调查 (Eclipse Community Survey),在 2010 年先后,SVN 的使用率都远超其余几款 VCS,从 2010 年开始,SVN 的使用率开始快速下滑,相应的,Git 的使用率快速上升,并在 2014 年超过了 SVN。php

vcs-popularity-eclipse-community.jpg

如今,Git 已经成为了程序员的必备技能,愈来愈多的企业开始采用 Git。在开源的世界里,Github 是程序员汇集的狂欢之地,但这并不适合企业的私有项目,虽然 Github 也支持建立私有项目,可是搭建一个本身的 Git 服务器在不少时候多是更好的选择,这篇博客将介绍并学习几种搭建 Git 服务器的方法。html

Git 支持四种不一样的传输协议:本地协议(Local)、HTTP(S) 协议、SSH(Secure Shell)协议以及 Git 协议,这四种协议在不一样的场合有不一样的用途,而且各有利弊,能够根据实际状况来选择。java

1、本地协议

本地协议是 Git 最基本的协议,当咱们想在本地作一些 Git 实验时,这将很是有用。咱们首先创建两个目录:/git/repo~/working,前者做为远程版本库,后者做为本地工做目录。nginx

aneasystone@little-stone:~$ sudo mkdir -p /git/repo
aneasystone@little-stone:~$ sudo git init --bare /git/repo/test.git
已初始化空的 Git 仓库于 /git/repo/test.git/
复制代码

咱们在 /git/repo 目录经过 git init --bare 命令建立一个裸仓库(bare repository,即一个不包含当前工做目录的仓库),只要这一步,咱们就能够开始使用了。接着咱们在工做目录 clone 这个版本库:git

aneasystone@little-stone:~$ cd ~/working/
aneasystone@little-stone:~/working$ git clone /git/repo/test.git
正克隆到 'test'...
warning: 您彷佛克隆了一个空仓库。
完成。
复制代码

而后咱们可使用 pullpush 就像操做其余的版本库同样。程序员

aneasystone@little-stone:~/working$ cd test/
aneasystone@little-stone:~/working/test$ touch 1
aneasystone@little-stone:~/working/test$ touch 2
aneasystone@little-stone:~/working/test$ git add .
aneasystone@little-stone:~/working/test$ git commit -m 'first commit'
[master (根提交) 4983f84] first commit
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1
 create mode 100644 2
aneasystone@little-stone:~/working/test$ sudo git push
[sudo] aneasystone 的密码: 
对象计数中: 3, 完成.
Delta compression using up to 8 threads.
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 205 bytes | 205.00 KiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To /git/repo/test.git
 * [new branch]      master -> master
复制代码

本地协议不只在作 Git 实验时颇有用,若是你的团队有一个共享文件系统,能够在这个共享文件系统上建立一个远程版本库,团队成员把这个共享文件系统挂在本地,就能够直接使用本地协议进行协做开发,彻底不须要搭建一台专门的 Git 服务器。github

2、SSH 协议

本地协议虽然简单,可是通常来讲并不适用,由于你没法控制用户对共享文件系统的操做,用户拥有 push 权限也就意味着用户对远程目录拥有完整的 Shell 权限,他们有可能会无心甚至有意的修改或删除 Git 内部文件,损坏 Git 仓库。算法

更安全的作法是使用专门的 Git 服务器,若是你有一台可使用 SSH 链接的服务器,搭建 Git 服务将会很是简单。首先咱们要确保服务器上运行着 SSH 服务(sshd),大多数 Linux 服务器版本都默认包含了该服务,若是没有,能够先安装 openssh-server。而后在服务器上建立 Git 远程版本库:shell

root@myserver:~# mkdir -p /git/repo
root@myserver:~# git init --bare /git/repo/test.git
已初始化空的 Git 仓库于 /git/repo/test.git/
复制代码

而后在本地 clone 这个版本库:apache

aneasystone@little-stone:~/working$ git clone ssh://root@myserver/git/repo/test.git
正克隆到 'test'...
root@myserver's password: warning: 您彷佛克隆了一个空仓库。 复制代码

能够看到和使用本地协议几乎同样,不一样的地方在于,在 clone 的时候须要在 URL 前面加上 ssh://root@myserver,你也可使用 scp 式的写法:

$ git clone root@myserver:/git/repo/test.git
复制代码

另一点不一样的地方是,每次 pullpush 的时候都须要输入远程服务器的 root 密码。很显然,让每一个 Git 用户都使用 root 来访问服务器是一种很不安全的作法,有几种方法能够解决这个问题:

  • 最显而易见的方法是为每一个 Git 用户建立一个独立的帐号,并分别为他们分配对仓库的读写权限,这种方法行的通,可是对帐号的管理很是麻烦,在团队人员不是不少的时候能够尝试,可是并不推荐;
  • 另外一种方法是配置 SSH 服务器使用某个已有的认证系统来管理用户,好比 LDAP,这在不少企业中是很常见的,这样能够省去用 adduser 手工管理服务器帐号的麻烦;
  • 还有一种方法是只建立一个帐号,好比叫作 git,他对仓库具备读写权限,你们都使用这个帐号来访问仓库。这种方法的好处是用户管理起来比较简单,并且可使用后面介绍的 authorized_keys 文件对用户的公钥进行管理;

下面咱们尝试下第三种方法。首先在服务器上建立一个名叫 git 的帐号:

root@myserver:~# adduser git
Adding user `git' ... Adding new group `git' (1000) ...
Adding new user `git' (1000) with group `git' ...
Creating home directory `/home/git' ... Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for git
Enter the new value, or press ENTER for the default
	Full Name []: git
	Room Number []:   
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] Y
复制代码

再设置一下 git 仓库的权限(默认状况下,git 仓库的权限为 rwxr-xr-x,只有建立者 root 有写的权限,也就意味着使用 git 帐号只能 clone pull,不能 push):

# chmod a+w -R /git/repo/test.git
复制代码

咱们这里很是粗暴的使用 chmod a+w 将 git 仓库设置为对全部人可写,这里能够想想,若是咱们但愿设置某些用户对仓库具备只读的权限,该怎么作呢?

而后就能够在本地愉快的进行 git 操做了:

$ git clone git@myserver:/git/repo/test.git
复制代码

到这里彷佛一切都很正常,可是几回实操以后你就会发现,每次 git 操做都要输入一次密码,这也太麻烦了,能不能“免密提交代码”呢?首先咱们要知道,只要能经过 SSH 登录到服务器,咱们就能操做 git,因此若是 SSH 能支持免密登录,咱们就能够“免密提交代码”。还好,SSH 支持公钥认证,这种认证方式无需密码登录。在 Linux 操做系统中,每一个用户均可以拥有本身的一个或多个密钥对(公钥和私钥成对出现),这些密钥通常状况会保存在 ~/.ssh 目录下,在开始以前,咱们先确认下本身是否已经生成过公钥了,能够看下这个目录下是否有 id_dsa.pubid_rsa.pub 这样的文件,若是没有,咱们经过 ssh-keygen 来生成:

aneasystone@little-stone:~/.ssh$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/aneasystone/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/aneasystone/.ssh/id_rsa.
Your public key has been saved in /home/aneasystone/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:4Ulpufuhs/AgDMb0VXnqMUTw6bD/HrAOI2z9c1cod9I aneasystone@little-stone
The key's randomart image is: +---[RSA 2048]----+ | .oo. | | oo+. | | . o.Oo | | o . . B++ | | + . ..So o | | . + . ..+. + E | | * * + oo + | | . o Oo+.o. | | **+. | +----[SHA256]-----+ 复制代码

这样咱们在 ~/.ssh 目录生成了两个文件,id_rsa 是你的私钥,id_rsa.pub 是你的公钥。关于私钥和公钥的原理以及 RSA 加密算法等内容能够参考我以前写过的一篇介绍 HTTPS 和证书 的文章。

咱们假设你的 Git 服务器是由专门的服务器管理员负责维护和管理,当你生成你的公钥以后,就能够给服务器管理员发送一封申请 Git 服务的邮件,并附上你的公钥。服务器管理员在收到你的申请以后,若是赞成了,就能够进行下面的操做:

首先将公钥文件拷贝到服务器上:

# scp id_rsa.pub root@myserver:/home/git
复制代码

将公钥文件的内容追加到 git 帐户的 authorized_keys 文件中(要注意的是,若是是第一次操做,/home/git 目录下是没有 .ssh 目录的,须要手工建立 .ssh 目录和 authorized_keys 文件):

root@myserver:/home/git# cat id_rsa.pub >> /home/git/.ssh/authorized_keys
复制代码

后续若是有其余的用户申请 Git 服务,均可以按照这个步骤操做。一旦完成这个操做,服务器管理员将会回复你的邮件,通知你 Git 服务已经开通,这个时候你再进行 git 操做就能够不用输入密码了。关于 SSH 的使用,更详细的步骤能够参考 Github 上的这篇指南:Connecting to GitHub with SSH

做为服务器管理员,关于 SSH 还有一点须要考虑,那就是 SSH 的安全问题。在上面介绍本地协议时,咱们说这种方式没法控制用户对 Git 仓库的操做,没法防止用户有意或无心的损坏 Git 仓库,使用 SSH 协议同样存在这样的问题,用户能经过 SSH 拉取和提交代码,也就意味着用户能够经过 SSH 链接到服务器,对 Git 仓库进行任何操做,这是一件很让人担忧的事情。

所以,咱们还须要对 git 帐号作一些限制。默认状况下,咱们新建帐号的登录 shell 是 /bin/bash,这个配置在 /etc/passwd 文件中:

git:x:1000:1000:git,,,:/home/git:/bin/bash
复制代码

可使用 chsh 命令修改用户的登录 shell,让他不能经过 SSH 访问服务器,怎么修改呢?咱们能够看一下 /etc/shells 文件,这里定义了全部可使用的登录 shell,你能够将 /bin/bash 改为这里的任何一个:

root@myserver:~# cat /etc/shells 
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
复制代码

很显然,这些 shell 并非咱们想要的,有没有一个 shell 只容许用户进行 git 操做,而不容许其余操做呢?还好,Git 的软件包提供了一个名叫 git-shell 的登录 shell,咱们能够把他加进去,通常状况下位于 /usr/bin/git-shell。咱们使用 chsh 修改 git 的登录 shell:

root@myserver:~# chsh git
Changing the login shell for git
Enter the new value, or press ENTER for the default
	Login Shell [/bin/bash]: /usr/bin/git-shell
复制代码

这样当用户 git 经过 SSH 链接服务器时,就会直接被拒绝了。

3、Git 协议

SSH 协议解决了用户直接操做 Git 仓库的权限问题,可是若是咱们但愿对除仓库维护者以外的全部人都开放 Git 仓库的只读权限,这在开源项目中和企业内部每每是很常见的,任何人均可以去查看仓库的代码,这时管理员须要给每个用户配置 SSH 密钥是很是麻烦的。虽然也可使用变通的方法来达到这个效果,可是很繁琐,下面是具体的步骤:

  • 使用 g+w 设置 Git 仓库的权限,让仓库建立者所在的用户组具备写权限,而不是全部人都有写权限(这一步一般也能够在 git init 的时候加上 --shared 参数);
  • 而后将 git 帐号加到仓库建立者的用户组;
  • 再建立一个 git_ro 帐户,这个帐户对仓库只有只读权限;
  • 最后为 git_ro 帐户建立一个密钥对,把 git_ro 的私钥公开出来供全部人使用。

能够看到使用 SSH 协议最终都逃不过受权这一步,并且公开私钥的作法也不是很优雅。实际上,Git 提供了另外一种方式来让这个操做更简单,那就是 Git 协议。使用 Git 协议必需要在服务器上运行 Git 守护进程,git 命令自带了一个 daemon 参数:

root@myserver:~# git daemon --reuseaddr --base-path=/git/repo/ /git/repo/
复制代码

上面的各个参数能够 参考 git-daemon 的文档。git-daemon 会监听 9418 端口,若是你的服务器有防火墙,须要将该端口添加到白名单,若是你使用的是阿里云服务器,须要像下面这样添加一个安全组规则:

security-group.jpg

为了让全部的用户均可以访问咱们的仓库,还须要在仓库目录下建立一个名为 git-daemon-export-ok 的文件:

root@myserver:~# cd /git/repo/test.git/
root@myserver:/git/repo/test.git/# touch git-daemon-export-ok
复制代码

至此,全部人均可以经过 Git 协议来克隆或拉取项目源码了(注意上面指定了 base-path 参数为 /git/repo/,因此 URL 能够直接写 git://myserver/test.git):

aneasystone@little-stone:~/working$ git clone git://myserver/test.git
复制代码

通常状况下,服务器管理员还会作一些其余的配置,譬如在服务器重启时让 Git 守护进程自动启动,这有不少种方式能够实现,能够参考《Pro Git》 Git 守护进程 这一节的内容。

4、HTTP(S) 协议

咱们通常经过 Git 协议进行无受权访问,经过 SSH 协议进行受权访问,若是你的项目是内部项目,只针对部分受权用户,那使用 SSH 协议就足够了,可是若是既须要受权访问也须要无受权访问,可能须要 SSH 协议和 Git 协议搭配使用,这在维护上成本很高。这时就到了咱们的压轴戏 —— HTTP 协议出场的时候了,它同时支持上面两种访问方式。

经过 HTTP 协议访问 Git 服务是目前使用最普遍的方式,它支持两种模式:旧版本的 Dumb HTTP 和 新版本的 Smart HTTP,Dumb HTTP 通常不多使用,下面除非特殊说明,所说的 HTTP 协议都是 Smart HTTP。使用 HTTP 协议的好处是可使用各类 HTTP 认证机制,好比用户名/密码,这比配置 SSH 密钥要简单的多,对普通用户来讲也更能接受。若是担忧数据传输安全,也能够配置 HTTPS 协议,这和普通的 Web 服务是同样的。

下面咱们就来尝试搭建一个基于 HTTP 协议的 Git 服务器。《Pro Git》上提供了一个基于 Apache 的配置示例,若是你是使用 Apache 做为 Web 服务器,能够参考之,咱们这里使用 Nginx 来做为 Web 服务器,其原理本质上是同样的,都是经过 Web 服务器接受 HTTP 请求,并将请求转发到 Git 自带的一个名为 git-http-backend 的 CGI 脚本

首先咱们安装所需的软件:

# apt-get install -y git-core nginx fcgiwrap apache2-utils
复制代码

其中,Nginx 做为 Web 服务器,自己是不能执行外部 CGI 脚本的,须要经过 fcgiwrap 来中转,就像使用 php-fpm 来执行 PHP 脚本同样。apache2-utils 是 Apache 提供的一个 Web 服务器的工具集,包含了一些有用的小工具,譬以下面咱们会用到的 htpasswd 能够生成 Basic 认证文件。

启动 nginx 和 fcgiwrap,并访问 http://myserver 测试 Web 服务器是否能正常访问:

# service nginx start
# service fcgiwrap start
复制代码

而后咱们打开并编辑 Nginx 的配置文件(/etc/nginx/sites-available/default):

location / {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT /git/repo;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
复制代码

这里经过 fastcgi_param 设置了一堆的 FastCGI 参数,以下:

  • SCRIPT_FILENAME:指定 CGI 脚本 git-http-backend 的位置,表示每次 HTTP 请求会被转发到该 CGI 脚本;
  • GIT_HTTP_EXPORT_ALL:git-http-backend 默认只能访问目录下有 git-daemon-export-ok 文件的 Git 仓库,和上面介绍的 Git 协议是同样的,若是指定了 GIT_HTTP_EXPORT_ALL,表示容许访问全部仓库;
  • GIT_PROJECT_ROOT:Git 仓库的根目录;
  • REMOTE_USER:若是有认证,将认证的用户信息传到 CGI 脚本;

改完以后咱们重启 Nginx,并经过 HTTP 协议 clone 仓库:

aneasystone@little-stone:~/working$ git clone http://myserver/test.git
复制代码

4.1 开启身份认证

到这里一切 OK,可是当咱们 push 代码的时候,却会报下面的 403 错误:

aneasystone@little-stone:~/working/test$ git push origin master
fatal: unable to access 'http://myserver/test.git/': The requested URL returned error: 403
复制代码

为了解决这个错误,咱们能够在 git-http-backend 的官网文档 上找到这样的一段描述:

By default, only the upload-pack service is enabled, which serves git fetch-pack and git ls-remote clients, which are invoked from git fetch, git pull, and git clone. If the client is authenticated, the receive-pack service is enabled, which serves git send-pack clients, which is invoked from git push.

第一次读这段话可能会有些不知所云,这是由于咱们对这里提到的 upload-packfetch-packreceive-packsend-pack 这几个概念尚未什么认识。可是咱们大抵能够猜出来,默认状况下,只有认证的用户才能够 push 代码,若是某个 Git 仓库但愿全部用户都有权限 push 代码,能够为相应的仓库设置 http.receivepack

root@myserver:/# cd /git/repo/test.git/
root@myserver:/git/repo/test.git# git config http.receivepack true
复制代码

固然最好的作法仍是对 push 操做开启认证,官网文档上有一个 lighttpd 的配置 咱们能够借鉴:

$HTTP["querystring"] =~ "service=git-receive-pack" {
	include "git-auth.conf"
}
$HTTP["url"] =~ "^/git/.*/git-receive-pack$" {
	include "git-auth.conf"
}
复制代码

这个配置看上去很是简单,可是想要理解为何这样配置,就必须去了解下 Git 的内部原理。正如上面 git-http-backend 文档上的那段描述,当 Git 客户端执行 git fetch, git pull, and git clone 时,会调用 upload-pack 服务,当执行 git push 时,会调用 receive-pack 服务,为了更清楚的说明这一点,咱们来看看 Nginx 的访问日志。

执行 git clone

[27/Nov/2018:22:18:00] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1"
[27/Nov/2018:22:18:00] "POST /test.git/git-upload-pack HTTP/1.1" 200 306 "-" "git/1.9.1"
复制代码

执行 git pull

[27/Nov/2018:22:20:25] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1"
[27/Nov/2018:22:20:25] "POST /test.git/git-upload-pack HTTP/1.1" 200 551 "-" "git/1.9.1"
复制代码

执行 git push

[27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 401 204 "-" "git/1.9.1"
admin [27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 200 193 "-" "git/1.9.1"
admin [27/Nov/2018:22:19:33] "POST /test.git/git-receive-pack HTTP/1.1" 200 63 "-" "git/1.9.1"
复制代码

能够看到执行 clone 和 pull 请求的接口是同样的,先请求 /info/refs?service=git-upload-pack,而后再请求 /git-upload-pack;而 push 是先请求 /info/refs?service=git-receive-pack,而后再请求 /git-receive-pack,因此在上面的 lighttpd 的配置中咱们看到了两条记录,若是要对 push 作访问控制,那么对这两个请求都要限制。关于 Git 传输的原理能够参考 《Pro Git》的 Git 内部原理 - 传输协议 这一节。

咱们依葫芦画瓢,Nginx 配置文件以下:

location @auth {
        auth_basic "Git Server";
        auth_basic_user_file /etc/nginx/passwd;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT /git/repo;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
}

location / {
        error_page 418 = @auth;
        if ( $query_string = "service=git-receive-pack" ) {  return 418; }
        if ( $uri ~ "git-receive-pack$" ) { return 418; }

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT /git/repo;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
复制代码

其中相同的配置咱们也能够用 include 指令放在一个共用的配置文件里,这样咱们就实现了在 push 的时候须要填写用户名和密码了。咱们经过 Nginx 的 auth_basic_user_file 指令来作身份认证,用户名和密码保存在 /etc/nginx/passwd 文件中,这个文件可使用上面提到的 apache2-utils 包里的 htpasswd 来生成:

root@myserver:/# htpasswd -cb /etc/nginx/passwd admin 123456
复制代码

另外,在 push 的时候,有时候可能会遇到 unpack failed: unable to create temporary object directory 这样的提示错误:

aneasystone@little-stone:~/working/test$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 193 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
error: unpack failed: unable to create temporary object directory
To http://myserver/test.git
 ! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'http://myserver/test.git'
复制代码

这通常状况下都是因为 Git 仓库目录的权限问题致使的,在这里 Git 仓库的根目录 /git/repo 是 root 建立的,而运行 nginx 和 fcgiwrap 的用户都是 www-data,咱们能够把 Git 仓库目录设置成对全部人可读可写,也能够像下面这样将它的拥有者设置成 www-data 用户:

root@myserver:/# chown -R www-data:www-data /git/repo
复制代码

4.2 凭证管理

上面咱们站在管理员的角度解决了用户身份认证的问题,可是站在用户的角度,每次提交代码都要输入用户名和密码是一件很痛苦的事情。在上面介绍 SSH 协议时,咱们可使用 SSH 协议自带的公钥认证机制来省去输入密码的麻烦,那么在 HTTP 协议中是否存在相似的方法呢?答案是确定的,那就是 Git 的凭证存储工具:credential.helper

譬如像下面这样,将用户名和密码信息保存在缓存中:

$ git config --global credential.helper cache
复制代码

这种方式默认只保留 15 分钟,若是要改变保留的时间,能够经过 --timeout 参数设置,或者像下面这样,将密码保存在文件中:

$ git config --global credential.helper store
复制代码

这种方式虽然能够保证密码不过时,可是要记住的是,这种方式密码是以明文的方式保存在你的 home 目录下的。能够借鉴操做系统自带的凭证管理工具来解决这个问题, 好比 OSX Keychain 或者 Git Credential Manager for Windows。更多的内容能够参考《Pro Git》凭证存储 这一节。

除此以外,还有一种更简单粗暴的方式:

aneasystone@little-stone:~/working$ git clone http://admin:123456@myserver/test.git
复制代码

5、综合对比

这一节对 Git 的四大协议作一个综合对比。

  • 本地协议
    • 优势:架设简单,不依赖外部服务,直接使用现有文件和网络权限,经常使用于共享文件系统
    • 缺点:共享文件系统的配置和使用不方便,且没法保护仓库被意外损坏,传输性能较低
  • SSH 协议
    • 优势:架设简单,全部数据通过受权加密,数据传输很安全,传输性能很高
    • 缺点:不支持匿名访问,配置 SSH 的密钥对小白用户有必定的门槛
  • Git 协议
    • 优势:对开放的项目很适用,无需受权,传输性能最高
    • 缺点:缺少受权机制,架设较麻烦,企业通常不会默认开放 9418 端口须要另行添加
  • HTTP/S 协议
    • 优势:同时支持受权访问和无受权访问,传输性能较高,配合 HTTPS 也能够实现数据安全
    • 缺点:架设 HTTP 服务较麻烦,认证凭证很差管理

6、更高级的工具

上面介绍的是搭建 Git 服务器最基本的方法,若是你只是但愿能找一个版本控制系统来替代现有的 SVN,这也许就足够了。但若是你但愿你的版本控制系统能拥有一个更友好的 UI 界面,能更好的管理你的用户和权限,能支持更现代的 Pull Request 功能以及能和 CI/CD 系统更紧密的联系起来,你就须要一个更高级的工具,你能够试试 GitWebGitoliteGitlabGogsGitea,固然,若是你愿意,你也能够把代码放在那些流行的代码托管平台上,好比 GithubBitbucket 等等。

参考

  1. Version Control Systems Popularity in 2016
  2. Pro Git 第二版
  3. git-http-backend 的官网文档
  4. Connecting to GitHub with SSH
  5. nginx fastcgi 配置
  6. Git远程推送时记住用户名和密码
  7. 搭建Git服务器 - 廖雪峰的官方网站
  8. 在 Ubuntu 系统上配置 Nginx Git 服务器- 张志敏的技术专栏
  9. Git 服务器基于nginx配置http(s)协议 | Yvanの平行时空
相关文章
相关标签/搜索