4種git支持的協議中,ssh配置簡單,權限管理也比較全面,無需密碼,且linux內置,當然會有偏向平臺的。git協議是運行最快的,基本上和操作系統關系不大,就是git-daemon啟動,然后git-clone。對那些人來說,快是很重要的。
至于smarthttp很慢,并且,配置真的(相對)復雜,需要了解cgi的概念,環境變量概念,特定的webserver的配置方法,以及特定操作系統的配置方法。我看到的progit中的smarthttp配置,就是缺少一些步驟的。
我剛剛寫了文章,對比了下,ssh,git配置大概半頁,http3頁而且只能適應于osx,apache的組合。可以欣賞下:
==========正文
##更多協議
想要和他人協作,我必須有遠程倉庫,這樣我才可以推送和拉取代碼的變更。在上一節,我們已經通過一個共享倉庫作為中介,以本地協議的通訊方式,達成兩人(多人)的代碼協作了。
git支持4種協議,包括本地協議、HTTP協議、Git協議、SSH協議。我們繼續看看Git協議。
##Git協議
通過Git協議來托管倉庫是內置于git-daemon命令之內。因此使用它來做測試和驗證倉庫的托管是非常方便的。執行git-daemon,會啟動一個監守程序,等待采用git協議來連接的客戶端,這些連接過來的客戶端可以訪問指定目錄下的倉庫。
假設我們在~/git目錄內已經存在一個共享倉庫,那么
cd~/git
gitdaemon--verbose--export-all--base-path=.--enable=receive-pack
這里的新命令git-daemon需要做些解釋。參數說明:
--base-path=.指定基礎目錄,客戶端連接指定的目錄都相對于此目錄來定位目錄。當前命令行內的基礎目錄就是~/git
--enable=receive-
--export-all公開全部倉庫
啟動了git監守程序,就可以在客戶端運行git-clone來拉取倉庫了:
gitclonegit://localhost/repo.git
我們使用的主機地址為localhost,就是意味著拉取的倉庫位于本機;你可以使用IP地址,就可以訪問其他主機的托管倉庫了。
##SSH協議
以OSX為例,首先激活sshd:
sudosystemsetup-setremoteloginon
隨后遠程登錄到主機(為了演示和測試的方便,遠程主機使用localhost來做模擬),并輸入密碼:
sshlocalhhost
然后創建一個共享倉庫:
mkdirgitshared.git
cdgitshared.git
gitinit--bare--shared
exit
這時我們已經準備好了一個空倉庫,可以在另外一個主機(也是本機)做克隆了。
gitclonessh://localhost/Users/lcjun/gitshared.git
使用git-remote來查詢遠程倉庫:
$gitremote-v
originssh://localhost/Users/lcjun/gitshared(fetch)
originssh://localhost/Users/lcjun/gitshared(push)
即可驗證命令確實有效的被執行了,ssh遠程倉庫也已經和本地關聯起來了。
##HTTP
HTTP協議下的git托管是相對最復雜的,因為它涉及到了WebServer的配置,CGI知識,特定的OS。WebServer和操作系統的版本差異也會對應有不同的配置方法。我的操作系統是OSXEICaptain,Git版本為2.6,Apache版本為2.4。我以本機為服務器,本機地址為192.168.3.11。在這樣的環境下,我希望可以使用
gitclonehttp://git.example.com/repo.git
的形式,以http協議方法訪問主機上的repo.git倉庫。留意URL的第一部分是http,而不是ssh,或者git。
假設倉庫以/var/www/git存放。我在此目錄內創建一個名為repo.git的倉庫:
mkdir-p/var/www/git/repo.git
cd/var/www/git/repo.git
gitinit--bare--shared
在本機內,找到hosts文件,并加入如下一行,以便支持通過主機名(http://git.example.com)訪問主機
192.168.3.11http://git.example.com
我采用apache作為Web服務器,首先保證apache是啟動和可以訪問的:
$sudoapachectlstart
$curllocalhost
<html><body><h3>Itworks!</h3></body></html>
¥curlhttp://git.example.com
<html><body><h3>Itworks!</h3></body></html>
git-http-backend需要引用模塊cgi,env,alias。必須它們是被加載了的。具體的做法是查看http.conf,確保一下模樣的行是沒有被標注的。如果被標注(行首有一個#),那么通過去掉“#”來解除標注。我的主機上,http.conf的位置在/etc/apache2/httpd.conf。
LoadModulecgi_modulelibexec/apache2/mod_cgi.so
LoadModuleenv_modulelibexec/apache2/mod_env.so
LoadModulealias_modulelibexec/apache2/mod_alias.so
找到http.conf,加入如下配置在文件末尾,它添加了一個名為http://git.example.com的虛擬主機,它的文檔目錄為/var/www/git:
<VirtualHost192.168.3.11:80>
DocumentRoot/var/www/git
ServerNamehttp://git.example.com
<Directory"/var/www/git">
Options+Indexes
Requireallgranted
</Directory>
<Directory"/usr/local/Cellar/git/2.4.1/libexec/git-core/">
OptionsExecCGIIndexes
Orderallow,deny
Allowfromall
Requireallgranted
</Directory>
SetEnvGIT_HTTP_EXPORT_ALL
SetEnvGIT_PROJECT_ROOT/var/www/git
ScriptAlias/git//usr/local/Cellar/git/2.4.1/libexec/git-core/git-http-backend/
</VirtualHost>
同時,這段配置內還添加了一個腳本別名,別名指向git-http-backend的CGI程序。git-http-backend在不同的系統上可能位置不同,可以使用這個命令查找到它:
$find/-namegit-http-backend2>/dev/null
為了讓此CGI可以運行,也必須配套的把CGI所在目錄設置為允許執行CGI(OptionsExecCGI)。
GIT_PROJECT_ROOT必須設置,這個值是git-http-backend需要的,有了它,git-http-backend就知道如何定位基礎目錄了。環境變量GIT_HTTP_EXPORT_ALL看起來有點熟悉,是因為我們在上一節git協議內在git守護進程的命令行中看到過它。設置了此環境變量,就意味著在基礎目錄內的所有倉庫都是可以對外共享的。
進入需要克隆的git倉庫所在的目錄并執行gitupdate-server-info:
cd/var/www/git/repo.git
sudogitupdate-server-info
重啟apache
sudoapachectlrestart
隨后,我就可以真的去克隆一個在apache服務后的git倉庫了:
gitclonehttp://git.example.com/repo.git
Cloninginto'repo'...
warning:Youappeartohaveclonedanemptyrepository.
Checkingconnectivity...done.
這個配置過程相對復雜,難免配置是出現不期望的錯誤,那么常備些命令是可以幫助調試的。比如查看Apache運行錯誤
sudotail/private/var/log/apache2/error_log
我需要多次修改http.conf,記得使用:
apachectlconfigtest
驗證下配置是正確的。我發現這個命令對我是有用的。
#找到apache用戶的方法
$psaux|egrep'(apache|httpd)'.
#找到apache用戶組的方法:
$iduser-name
user-name換成apache用戶名
在我的主機上,我在升級git的時候,曾經出過這樣的報錯:
$brewupgradegit
#Gitpackagebrokenin10.11ElCapitan
brewreinstallgit
...
==>makeprefix=/usr/local/Cellar/git/2.4.3sysconfdir=/usr/local/etcCC=clangC
./git-compat-util.h:219:10:fatalerror:'openssl/ssl.h'filenotfound
#include<openssl/ssl.h>
^
我嘗試了改變下命令行參數的方式:
brewreinstallgit--with-brewed-openssl
結果是可以升級到最新的git版本的(git2.6.4)