服务器搭建私人Git

环境是CentOS 7.4 64位

主要参考:在服务器上搭建 Git

0. 预备

  • 安装git yum install git

1. 开发者-生成个人SSH公钥

p.s. 书中的4.3节是【生成个人的SSH公钥】,网站版本却是【服务器上的 Git - 生成 SSH 公钥】,因为是用户的公钥,所以还是书中名字较合适

在本地win10上测试,没有装Git则下载安装Git for windows

打开git Bash, ssh-keygen 回车几次就生成了(默认在/c/Users/用户名/.ssh/id_rsa)
(*nix用户直接使用ssh-keygen)

id_rsa.pub或者id_dsa.pub发给管理员,需放置到服务器上。

2. 服务端-服务器上的Git,设置服务器

$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

将开发者*.pub文件内容,追加进~/.ssh/authorized_keys中。

/opt/git下建立裸仓库,

  • 将现有仓库导出为一个新的裸仓库 git clone --bare https://github.com/onionc/Laravel-Messages.git messages.git

  • 或者git init --bare初始化一个目录

cd /opt/git
mkdir messages.git
cd messages.git
git init --bare

看一下目录,用现有仓库的话配置文件里面多了几行,有远程分支url

[root@x messages.git]# ll
total 36
drwxr-xr-x 2 root root 4096 Apr 22 15:26 branches
-rw-r--r-- 1 root root  138 Apr 22 15:26 config
-rw-r--r-- 1 root root   73 Apr 22 15:26 description
-rw-r--r-- 1 root root   23 Apr 22 15:27 HEAD
drwxr-xr-x 2 root root 4096 Apr 22 15:26 hooks
drwxr-xr-x 2 root root 4096 Apr 22 15:36 info
drwxr-xr-x 4 root root 4096 Apr 22 15:26 objects
-rw-r--r-- 1 root root   98 Apr 22 15:27 packed-refs
drwxr-xr-x 4 root root 4096 Apr 22 15:26 refs
[root@x my_project.git]# cat config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = true
[remote "origin"]
	url = https://github.com/onionc/Laravel-Messages.git

这样就创建了(舍去工作目录的)一个新的目录。

3. 将自己的代码推上去

由于我本地的已经有一个github远程库,所以用git remote add 添加一个远程仓库。可参考 2.5 Git 基础 - 远程仓库的使用

建远程仓库(需确保opt/git目录权限为git)

 git remote add tx-origin git@111.111.111.111:/opt/git/messages.git

推数据

git push tx-origin master

4. 克隆

换个目录克隆一下

$ git clone git@111.111.111.111:/opt/git/messages.git
Cloning into 'messages'...
git@111.111.111.111's password:
remote: Counting objects: 200, done.
remote: Compressing objects: 100% (155/155), done.
remote: Total 200 (delta 25), reused 196 (delta 24)
Receiving objects: 100% (200/200), 1.17 MiB | 122.00 KiB/s, done.
Resolving deltas: 100% (25/25), done.

成功。试着修改一个文件,提交成功


$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   README.md
no changes added to commit (use "git add" and/or "git commit -a")


$ git add README.md

$ git commit -m '2'
[master 10c25ba] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git push
git@111.111.111.111's password:
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 266 bytes | 266.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To 111.111.111.111:/opt/git/messages.git
   2fa76cf..10c25ba  master -> master

p.s. 服务器ip 111.111.111.111等隐私均为杜撰,也可用域名。

其他. 疑问:文件存到哪去了?

服务器的messages.git目录下均未找到项目文件

[git@x messages.git]$ ll
total 32
drwxrwxr-x 2 git git 4096 Apr 22 20:57 branches
-rw-rw-r-- 1 git git   66 Apr 22 20:57 config
-rw-rw-r-- 1 git git   73 Apr 22 20:57 description
-rw-rw-r-- 1 git git   23 Apr 22 20:57 HEAD
drwxrwxr-x 2 git git 4096 Apr 22 20:57 hooks
drwxrwxr-x 2 git git 4096 Apr 22 20:57 info
drwxrwxr-x 7 git git 4096 Apr 22 21:28 objects
drwxrwxr-x 4 git git 4096 Apr 22 20:57 refs

那么项目文件推送到后存储到哪里去了呢?

找到一个类似的问题:自己搭建git服务器,本地文件为什么push不到服务器上?的答案是:git服务器上那个目录project001.git 这只是一个仓库. 你需要找个目录克隆出来, 才会显示你push上去的内容的

可是,到底存到哪里了?( 鸽子为什么这么大?

所有服务端的工作都由hooks目录下的update(update.sample)脚本文件来完成 - 精通Git Second Edition, 8.4.1

用我这战五渣英语搜出来一个:
Git Push worked, but files are not on server

回答里说

The files are there, you just don't see them because they are embedded into the Git database. This is the difference between initializing a repository with --bare or without

文件在那里,你只是看不到它们,因为它们被嵌入到Git数据库中。这是初始化一个l裸存储库的不同之处。

这样啊,放到数据库中我就不深究了,我这菜逼八成也看不懂了,以后再研究。

回答里留了个参考 What is a bare git repository?

找几句重要的:

Repositories created with git init --bare are called bare repos. They are structured a bit differently from working directories. First off, they contain no working or checked out copy of your source files. And second, bare repos store git revision history of your repo in the root folder of your repository instead of in a .git subfolder.

A bare repository created with git init --bare is for… sharing.

Because git is a distributed version control system, no one will directly edit files in the shared centralized repository.

Because no one ever makes edits directly to files in the shared bare repo, a working tree is not needed. In fact the working tree would just get in way and cause conflicts as users push code to the repository. This is why bare repositories exist and have no working tree.

使用git init --bare创建的存储库称为裸存储库。它们的结构与工作目录稍有不同。首先,它们不包含任何工作或检查源文件的副本。其次,在存储库的根文件夹中,而不是在一个.git子文件夹中,仅使用repos存储您的repo的历史记录。

使用git init --bare创建的一个裸存储库用于…共享。

因为git是一个分布式版本控制系统,所以没有人会直接在共享的集中存储库中编辑文件。

因为没有人直接对共享的裸回文件进行编辑,所以不需要工作树。实际上,当用户将代码推到存储库中时,工作树会导致冲突。这就是为什么裸存储库存在且没有工作树的原因。

5. 限制 git用户 权限

首先你必须确保 git-shell 已存在于 /etc/shells 文件中:

$ cat /etc/shells   # 查看 git-shell 是否存在,不能存在则
$ which git-shell   # 确保安装了 git-shell, 返回了路径:/usr/bin/git-shell
$ sudo vim /etc/shells  # 将 git-shell 路径添加到最后

现在你可以使用 chsh 命令修改任一系统用户的 shell:

$ sudo chsh git # 然后输入git-shell的路径,通常是:/usr/bin/git-shell

这样,用户 git 就只能利用 SSH 连接对 Git 仓库进行推送和拉取操作,而不能登录机器并取得普通 shell。 如果试图登录,你会发现尝试被拒绝。

6. 安装 GitWeb 用于在线查看

进入项目路径下

$ yum install gitweb # 安装gitweb
$ git instaweb --httpd=webrick #简易查看 

打开浏览器查看:

6. 加入虚拟主机

6.1 生成gitweb.cgi

手动生成cgi

$ git clone git://git.kernel.org/pub/scm/git/git.git
$ cd git/
$ make GITWEB_PROJECTROOT="/opt/git" prefix=/usr gitweb
    SUBDIR gitweb
    SUBDIR ../
make[2]: `GIT-VERSION-FILE' is up to date.
    GEN gitweb.cgi
    GEN static/gitweb.js
$ sudo cp -Rf gitweb /var/www/

我直接使用yum安装的gitweb,所以和书中的配置不一样,手动更改:

$ vim /var/www/git/gitweb.git
80行左右 our $projectroot = "/var/lib/git";
改为我的git项目目录,our $projectroot = "/opt/git";

nginx配置,提醒错误

Access denied.
nginx错误日志
FastCGI sent in stderr: "Access to the script '/var/www/git/gitweb.cgi' has been denied

修正半天没好,应该是fastcgi_pass问题,127.0.0.1:9000是php-fpm的
但是PHP-fpm仅仅是个“PHP Fastcgi 进程管理器”, 它仍会调用PHP解释器本身来处理请求,PHP解释器(在Windows下)就是php-cgi.exe.

6.2 在nginx下运行,需要安装cgi支持

  • 首先安装perl fcgi, 下载生成,遇到错误
$ perl Makefile.PL
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.

  • 需要安装perl-ExtUtils-Embed yum install perl-ExtUtils-Embed -y (by linux安装软件报错...)
  • 再次生成,又遇到错误configure: error: C compiler cannot create executables, 需要gcc, 安装一个yum install gcc

…… 好麻烦,修正,使用apache运行8080端口,用nginx代理

6.3 使用apache吧

查看/etc/httpd/modules/下有mod_cgi.so mod_cgid.so, 添加到httpd.conf配置里:

LoadModule cgi_module modules/mod_cgi.so #之后httpd可以看到是內建模块cgi_module跳过了,可注释掉
LoadModule cgid_module modules/mod_cgid.so

虚拟主机配置用书中的,但改了端口,因为nginx用着80.
Options行注释掉是因为错误Either all Options must start with + or -, or no Option may索性注释掉,全局配置里也有AddHandler那句的,不过没关系。

<VirtualHost *:8080>
    ServerName gitserver
    DocumentRoot /var/www/git
    <Directory /var/www/git>
        #Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
        AllowOverride All
        order allow,deny
        Allow from all
        AddHandler cgi-script cgi
        DirectoryIndex gitweb.cgi
    </Directory>
</VirtualHost>

重启apacheservice httpd restart后生效。

之后在nginx添加反向代理:

location /git/ {
    proxy_pass http://127.0.0.1:8080;
}

重启nginxnginx -s reload后生效。
访问域名:

p.s. 修改项目目录下的description则为项目描述。

7. 同时推送多个库

.git/config里面加上远程仓库合集

[remote "origin"]
	url = https://github.com/onionc/Laravel-Messages.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[remote "tx-origin"]
	url = git@www.xxxxx.com:/opt/git/messages.git
	fetch = +refs/heads/*:refs/remotes/tx-origin/*
[remote "all"]
	url = git@www.xxxxx.com:/opt/git/messages.git
	url = https://github.com/onionc/Laravel-Messages.git

单独推送拉取可用origin(github) tx-origin(自建私有git) 远程仓库,同时推送可用all(远程仓库合集)

修改README.md测试同时推送

$ git add README.md

$ git commit -m '测试多个git库同时推送'
[master 0949ff9] 测试多个git库同时推送
 1 file changed, 3 insertions(+), 1 deletion(-)

$ git push all master
git@www.xxxxxx.com's password:
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 360 bytes | 360.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To www.xxxxxx.com:/opt/git/messages.git
   10c25ba..0949ff9  master -> master

Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 360 bytes | 360.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/onionc/Laravel-Messages.git
   10c25ba..0949ff9  master -> master
   

完美!不过推送完私有库之后卡了一阵才继续推的github。

其他参考

8. 追加,非智能HTTP协议

Git有两种不同的协议,智能HTTP协议和非智能HTTP协议(也叫哑HTTP协议)(可参考4.1 服务器上的 Git - 协议)。

上面建的就是智能的,那么非智能优势是啥:配置简单,只能拉取不能推(这也算不上优势了)。

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

设置一个特定的post-update钩子函数就可以了,但是我弄完之后,访问总是403,

Forbidden
You don't have permission to access /xxxxxx.git/ on this server.

然后克隆

$ git clone http://xxx.xxx.xxx.xxx/messages.git
Cloning into 'messages'...
fatal: repository 'http://xxx.xxx.xxx.xxx/messages.git/' not found

也是找不到这个repo, 最后搜到一个例子
A tutorial about Git. Setup remote Git repository on Mac OS X. Includes examples,发现他手动在版本库下执行了git --bare update-server-info ,我试了一下,果然好使。克隆成功。

比较一下两种克隆方式


$ git clone http://xxx.xxx.xxx.xxx:8088/messages.git
Cloning into 'messages'...


$ git clone git@xxx.xxx.xxx.xxx:/opt/git/messages.git
Cloning into 'messages'...
git@xxx.xxx.xxx.xxx's password:
remote: Counting objects: 298, done.
remote: Compressing objects: 100% (250/250), done.
remote: Total 298 (delta 90), reused 162 (delta 24)
Receiving objects: 100% (298/298), 1.22 MiB | 27.00 KiB/s, done.
Resolving deltas: 100% (90/90), done.

我还发现一个大问题,配置的SSH公钥一直没用到。学艺不精学艺不精。

posted @ 2018-04-22 22:37  姜小豆  阅读(2046)  评论(0编辑  收藏  举报