服務器搭建私人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公鑰一直沒用到。學藝不精學藝不精。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM