Git, 一個分布式的版本管理工具,我認為其革命性的點:在於改變了用戶協作的方式,使得協作更簡單。
下面講述 使用一個開源軟件 Gitolite搭建一個Git Sever, 並給了一個推薦的團隊協助方式。
Install Gitolite
創建 git 用戶
創建一個名為 git 用戶
[root@server ~]# useradd git
設置密碼
[root@server ~]# passwd git
## Download Gitolite
```shell
# 切換為 git 用戶
# su git
[git@server ~]$ cd ~
[git@server ~]$ git clone git://github.com/sitaramc/gitolite
Install Gitolite
# 創建 ~/bin 目錄
[git@server ~]$ mkdir bin
# 把 /home/git/bin 添加到環境變量里, 通過修改git 家下面的.bashrc
[git@server ~]$ vim .bashrc
# 在文件最后添加
export PATH=/home/git/bin:$PATH
# Install gitolite into $HOME/git/bin
[git@server ~]$ gitolite/install -ln
[git@server ~]$
上傳客戶端管理員的SSH 公鑰 {#ssh_key}
客戶端如果生成ssh key, 參考: Github - Generating SSH Keys
[ahnniu@client ~] cd ~/.ssh
[ahnniu@client .ssh] ls -al
# 如果不存在 id_rsa, id_rsa.pub 則運行下面的命令創建
[ahnniu@client .ssh] ssh-keygen -t rsa -C "your_email@example.com"
# 復制一份id_rsa.pub並重命名為 ahnniu.pub, 注 ahnniu為 gitolite管理員的用戶名
[ahnniu@client .ssh] cp id_rsa.pub ahnniu.pub
# 通過ssh上傳到服務器上(/home/git/),特別注意文件的owern應該為git
[ahnniu@client .ssh] scp ~/.ssh/ahnniu.pub git@192.168.2.223:/home/git/
Setup Gitolite
Refrence: 官方 - setting up gitolite
[git@server ~]$ cd ~
# 基於提供的ahnniu.pub 創建 gitolite-admin 管理倉庫
[git@server ~]$ gitolite setup -pk $HOME/ahnniu.pub
Initialized empty Git repository in /home/git/repositories/gitolite-admin.git/
Initialized empty Git repository in /home/git/repositories/testing.git/
WARNING: /home/git/.ssh missing; creating a new one
(this is normal on a brand new install)
WARNING: /home/git/.ssh/authorized_keys missing; creating a new one
(this is normal on a brand new install)
至此,SSH方式的Git服務已經搭建好了
客戶端SSH方式clone, push
# 首先需確保,上傳的管理員key ahnniu.pub是在這台電腦上生成的,否則是沒有權限的
[ahnniu@client ~] git clone git@192.168.2.223:gitolite-admin.git
Cloning into 'gitolite-admin'...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (6/6), done.
Checking connectivity... done.
gitolite使用
將在最后一節詳細介紹。
Gitolite支持HTTP
Install Apache
[root@server ~]# yum install httpd
編輯http.conf,使得apache正常工作
Apache幾個重要的路徑:
- /etc/httpd/conf/httpd.conf # apache的主配置
- /etc/httpd/conf.d/* # 擴展配置
- /usr/sbin/apachectl # 可執行文件,用於啟動,關閉apache服務
- /var/www/ # apache文檔的根目錄
- /var/www/html/ # 網頁根目錄
- /var/log/httpd/ # httpd log
[root@server ~]# /etc/httpd/conf/httpd.conf
# 修改下面2個變量
Listen 192.168.2.223:80
ServerName 192.168.2.223:80
添加一個index.html, 看是否可訪問
[root@server ~]# cd /var/www/html/
[root@server html]# vim index.html
# 添加以下內容.
Hello World!
# 需把index.html的所有權轉為apache用戶
[root@server html]# chown apache:apache index.html
# 開啟 httpd
# 這里可能會有端口被占用的一些問題,使用命令netstat 查看是哪個命令
[root@server html]# /usr/sbin/apachectl -k start
從客戶端訪問 http://192.168.2.223/index.html, 如果可能,說明apache安裝成功
修改~/.gitolite.rc
[git@server ~]$ cd
# 編輯 ~/.gitolite.rc, 設置PATH變量:(添加gitolite 所在的bin到$PATH)
[git@server ~]$ vim .gitolite.rc
# 添加下面一句道文件最__前面__
$ENV{PATH} .= ":/home/git/bin";
check which document root your Apache's suexec accepts
[root@server ~]# suexec -V
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=100
-D AP_HTTPD_USER="apache"
-D AP_LOG_EXEC="/var/log/httpd/suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=500
-D AP_USERDIR_SUFFIX="public_html"
在AP_DOC_ROOT 目錄下創建一個bin, 供git用戶執行
[root@server ~]# install -d -m 0755 -o git -g git /var/www/bin
在AP_DOC_ROOT 目錄下創建一個git 目錄 , 供 apache 用戶 做 別名映射
[root@server ~]# install -d -m 0755 -o apache -g apache /var/www/git
在 /var/www/bin 中 添加一個 shell 腳本, 供 git用戶調用 gitolite功能 : gitolite-suexec-wrapper.sh
[root@server ~]# cd /var/www/bin
[root@server bin]# vim gitolite-suexec-wrapper.sh
# 內容為
#!/bin/bash
#
# Suexec wrapper for gitolite-shell
#
export GIT_PROJECT_ROOT="/home/git/repositories"
export GITOLITE_HTTP_HOME="/home/git"
# 為gitolite 下載目錄 git clone git://github.com/sitaramc/gitolite
exec ${GITOLITE_HTTP_HOME}/gitolite/src/gitolite-shell
# git為owner
[root@server bin]# chown git:git gitolite-suexec-wrapper.sh
# 修改執行權限
[root@server bin]# chmod 0700 gitolite-suexec-wrapper.sh
# 查看權限有無修改正確
[root@server bin]# ls -al
NOTE: gitolite-suexec-wrapper.sh 文件中不能出現中文,包括空格,否則會出現format錯誤。
如果遇到問題,可以參考:http://stackoverflow.com/questions/14860166/solved-gitolite-and-http-error-500-permission-issue-in-setup
配置 Apache 使其可與 gitolite 工作
[root@server ~]# cd /etc/httpd/conf.d
# 在 conf.d 添加 gitolite的配置
[root@server conf.d] vim gitolite.conf
# 內容為
<Directory /var/www/git>
Options None
AllowOverride none
Order allow,deny
Allow from all
</Directory>
SuexecUserGroup git git
ScriptAlias /git/ /var/www/bin/gitolite-suexec-wrapper.sh/
ScriptAlias /gitmob/ /var/www/bin/gitolite-suexec-wrapper.sh/
<Location /git>
AuthType Basic
AuthName "Git Access"
Require valid-user
AuthUserFile /etc/httpd/git.passwd
</Location>
創建Git Access 認證用戶信息
我們在上面的配置:AuthUserFile /etc/httpd/git.passwd
[ahnniu@server ~] cd /etc/httpd/
# 創建git.passwd, 並創建 ahnniu的用戶
[ahnniu@server ~] htpasswd -c git.passwd ahnniu
#接下來輸入密碼
Finally
- add an R = daemon access rule to all repositories you want to make available via http.
重啟apache , 測試
gitolite log文件:/home/git/.gitolite/logs
[root@server ~]# /usr/sbin/apachectl -k stop
[root@server ~]# /usr/sbin/apachectl -k start
[ahnniu@client ~] git clone http://192.168.2.223/git/testing.git
團隊開發過程中建議的Gitolite使用方式
Gitolite的管理方式
我認為Gitolite是典型的吃自己的狗糧,他的管理完全是操作Git來完成, 他可以允許多個管理員同時管理,因為是基於一個git倉庫,那么通過merge可以解決沖突的問題
Gitolite有一個gitolite-admin.git的倉庫, 通過操作:
- /keydir/ 來管理SSH用戶
- /conf/gitolite.conf 來管理repo(增刪,權限)
下面我們探討如果通過gitolite打造Github那樣的Git Server.
Git倉庫的幾種權限
Public / Private
Public: 倉庫可以給任何人Clone,pull
Private: 倉庫只能給指定的人Clone,pull
幾種權限組
- 權限組: Owner
倉庫的擁有者,可以對倉庫做任何想做的事情,比如push, 修改其它人訪問這個倉庫的權限,甚至刪除,至少需要有一個人
- 權限組: RW
可讀寫組, clone, push, pull
- 權限組: R
可讀組, clone, pull
其中 Owner包含 RW, RW權限 包含 R
准備工作
克隆gitolite管理倉庫
NOTE: 需使用安裝Gitolite指定的SSH Key對應的電腦(或者Copy 對應的 id_rsa到你使用的電腦~/.ssh), HTTP方式好像不能操作gitolite-admin.git倉庫。
[ahnniu@client ~] $ git clone git@192.168.2.223:gitlite-admin.git gitolite-admin
[ahnniu@client ~] tree
├── conf
│ └── gitolite.conf
└── keydir
└── ahnniu.pub
2 directories, 2 files
Gitolite的用戶管理
Refernce: Gitolite官方 - adding and removing users
用戶名
建議的用戶名:盡可以由 字母,數字, - , _ 來組成,最少3個字符,不能包括#,$,@等特殊符號
舉例: paul
用戶名的用途:
- gitolite用於分配 repo的權限
- HTTP可用此用戶名登錄,當然不僅限於(比如還可以使用郵箱登錄)
- 用戶生成個人主頁:比如 http://github.com/ahnniu
- 用於標示倉庫的所有者:比如 git@github.com:ahnniu/testing.git https://github.com/git/ahnniu/testing.git
SSH用戶管理
SSH協議很安全,另外,配置好之后也無需輸入密碼什么的,也很方便。
假定新增 用戶名: paul
Step1: paul 在他本機電腦上:生成SSH Key
參考 文章的上部
Step2: paul 把生成的 paul.pub 發給管理員,由管理員添加
Step3: 管理員在Client端 gitolite-admin倉庫,復制 paul.pub 到 ./keydir中
Step4: 管理員commit倉庫,並push, gitolite配置生效
[ahnniu@client gitolite-admin] git commit -m "add user: paul"
[ahnniu@client gitolite-admin] git push origin
Step5: 管理員可以 使用 paul 這個用戶名 配件權限了
多個SSH Key
一個人經常會有幾個辦公的場所/電腦,比如公司,家,筆記本,那么如果需要在這些電腦上操作Git的話,都需要配置SSH Key, 並把這些Key發給管理員添加
建議的SSH Public Key的命名為:
- paul@home.pub # 家里電腦
- paul@work.pub # 公司電腦
HTTP 用戶管理
需管理員登錄到服務器操作:
[ahnniu@server ~] cd /etc/httpd/
# 基於git.passwd文件, 並創建 paul的用戶
[ahnniu@server ~] htpasswd git.passwd paul
#接下來輸入密碼
刪除用戶
假定刪除 paul 用戶,gitolite-admin倉庫中
- /conf/gitolite.conf 刪除所有跟 paul
- /keydir/ 刪除 paul.pub, paul@*.pub
- 服務器 /etc/httpd/git.passwd 中刪除 paul 用戶 (htpasswd -D /etc/httpd/git.passwd paul)
Gitolite的團隊管理
一個Team表示一些具備同類屬性的人,如果就Git倉庫來說,他們操作的是同一些Git倉庫。
一個Team也是一個實體,他可以擁有Git倉庫。Team的成員可以按照Owern, RW, R三個不同的權限分成3組。
Github的做法:首先是一個Orignization, Orignization下再分多個Team, 每個Team對應一個權限組,或者Owern, 或者RW, 或者R, 那么這個Github下面的Team的共性在於:操作同一些Git倉庫,而且具有相同的權限操作。這對大公司而言,比較合適,比如一個公司研發團隊很大,又分為了研發一部,研發二部等等。
詳細可參考:
- Github - What's the difference between user and organization accounts?
- Github - Permission levels for an organization repository
對於小公司而言,直接按照我上面提到的應該更合適一些。
在Gitolite中,推薦的團隊呈現方式:
# coocox team owner組
@coocox_owner = paul
# coocox team 讀寫組
@coocox_rw = tom jim
# coocox team 只讀組
@coocox_r = alice sky
# 三個小組合並起來,就是coocox這個team
@coocox = @coocox_owner @coocox_rw @coocox_r
Gitolite 倉庫管理
新增一個倉庫
NOTE: 新建倉庫 無需 在Server端 repositories 中 運行
git init --bare
, 直接在gitolite.conf中添加下面配置語句,gitolite會幫我們做到
# cox 是要創建的倉庫名稱, 對應url: git@192.168.2.223: cox.git
repo cox
RW+ = ahnniu
R = @all
我們看到github上的倉庫命名:git@github.com:coocox/cox.git, 很清晰,一樣可以看到倉庫的owner, gitolite是否支持這樣的? 答案是支持的。
# cox 是要創建的倉庫名稱, 對應url: git@192.168.2.223: cox.git
# ahnniu是用戶名,用戶名是不可能更改的
repo ahnniu/cox
RW+ = ahnniu
R = @all
Refrence: Gitolite官方 - adding and removing repos
刪除一個倉庫
- gitolite.conf 中找到對應的 repo , 移除
- 登錄到服務器,從 repositories中刪除對應的倉庫
重命名一個倉庫
- 登錄到服務器,在repositories下手動重命名
- gitolite.conf 重命名
管理一個Team的倉庫
# 用於歸納
@coocox_repo = coocox/cox coocox/coide
repo coocox/cox
RW+ = @coocox_owner @coocox_rw
R = @coocox_r
repo coocox/coide
RW+ = @coocox_owner @coocox_rw
# 除coocox team的人可Read外,paul這個個人也是可以讀的
R = @coocox_r paul
# 不推薦下面 大鍋飯的管理方式:
# 這樣不允許特例的出現,比如Team下的倉庫還希望可以被某個個人訪問
repo @coocox_repo
RW+ = @coocox_owner @coocox_rw
R = @coocox_r
#
Gitolite的權限管理
我們用到gitolite倉庫的權限主要有兩個:
- RW+,僅需在對應的行 添加一個 team (@coocox_rw) 或者 個人 (paul)
- R, 同上
- owner, 不在gitolite倉庫權限本身體現,他是gitolite權限之外的,具備管理員的某些特性,比如要刪除一個操作,
更改Public / Private
repo ahnniu/cox
RW+ = ahnniu
# R組, 添加@all 就是 Public
# R組, 移除 @all 就是 Private
R = @all