git学习——服务器上的 Git
服務(wù)器上的 Git
到目前為止,你應(yīng)該已經(jīng)學(xué)會了使用 Git 來完成日常的工作。然而,如果想與他人合作,還需要一個遠程的 Git 倉庫。盡管技術(shù)上可以從個人的倉庫里推送和拉取改變,但是我們不鼓勵這樣做,因為一不留心就很容易弄混其他人的進度。另外,你也一定希望合作者們即使在自己不開機的時候也能從倉庫獲取數(shù)據(jù)——擁有一個更穩(wěn)定的公共倉庫十分有用。因此,更好的合作方式是建立一個大家都可以訪問的共享倉庫,從那里推送和拉取數(shù)據(jù)。我們將把這個倉庫稱為 "Git 服務(wù)器";代理一個 Git 倉庫只需要花費很少的資源,幾乎從不需要整個服務(wù)器來支持它的運行。
架設(shè)一個 Git 服務(wù)器不難。第一步是選擇與服務(wù)器通訊的協(xié)議。本章的第一節(jié)將介紹可用的協(xié)議以及他們各自的優(yōu)缺點。下面一節(jié)將介紹一些針對各個協(xié)議典型的設(shè)置以及如何在服務(wù)器上運行它們。最后,如果你不介意在其他人的服務(wù)器上保存你的代碼,又不想經(jīng)歷自己架設(shè)和維護服務(wù)器的麻煩,我們將介紹幾個網(wǎng)絡(luò)上的倉庫托管服務(wù)。
如果你對架設(shè)自己的服務(wù)器沒興趣,可以跳到本章最后一節(jié)去看看如何創(chuàng)建一個代碼托管賬戶然后繼續(xù)下一章,我們會在那里討論一個分布式源碼控制環(huán)境的林林總總。
遠程倉庫通常只是一個 純倉庫(barerepository) ——一個沒有當(dāng)前工作目錄的倉庫。因為該倉庫只是一個合作媒介,所以不需要從一個處于已從硬盤上檢出狀態(tài)的快照;倉庫里僅僅是 Git 的數(shù)據(jù)。簡單的說,純倉庫是你項目里 .git 目錄的內(nèi)容,別無他物。
協(xié)議
Git 可以使用四種主要的協(xié)議來傳輸數(shù)據(jù):本地傳輸,SSH 協(xié)議,Git 協(xié)議和 HTTP 協(xié)議。下面分別介紹一下他們以及你應(yīng)該(或不應(yīng)該)在怎樣的情形下使用他們。
值得注意的是除了HTTP 協(xié)議之外,其他所有協(xié)議都要求在服務(wù)器端安裝并運行 Git 。
本地協(xié)議
最基礎(chǔ)的就是 本地協(xié)議(Localprotocol) 了,遠程倉庫在該協(xié)議中就是硬盤上的另一個目錄。這常見于團隊每一個成員都對一個共享的文件系統(tǒng)(例如 NFS )擁有訪問權(quán),抑或比較少見的多人共用同一臺電腦的時候。后者不是很理想,因為你所有的代碼倉庫實例都儲存在同一臺電腦里,增加了災(zāi)難性數(shù)據(jù)損失的可能性。
如果你使用一個共享的文件系統(tǒng),就可以在一個本地倉庫里克隆,推送和獲取。要從這樣的倉庫里克隆或者將其作為遠程倉庫添加現(xiàn)有工程里,可以用指向該倉庫的路徑作為URL。比如,克隆一個本地倉庫,可以用如下命令完成:
$ git clone /opt/git/project.git
或者這樣:
$ git clone file:///opt/git/project.git
如果你在URL的開頭明確的使用file:// ,那么 Git 會以一種略微不同的方式運行。如果你只給出路徑,Git 會嘗試使用硬鏈接或者直接復(fù)制它需要的文件。如果使用了 file:// ,Git會調(diào)用它平時通過網(wǎng)絡(luò)來傳輸數(shù)據(jù)的工序,而這種方式的效率相對很低。使用 file:// 前綴的主要原因是當(dāng)你需要一個不包含無關(guān)引用或?qū)ο蟮母蓛魝}庫副本的時候——一般是從其他版本控制系統(tǒng)的導(dǎo)入之后或者類似的情形(參見第9章的維護任務(wù))。我們這里使用普通路徑,因為通常這樣總是更快。
要添加一個本地倉庫到現(xiàn)有 Git 工程,運行如下命令:
$ git remote add local_proj /opt/git/project.git
然后就可以像在網(wǎng)絡(luò)上一樣向這個遠程倉庫推送和獲取數(shù)據(jù)了。
優(yōu)點
基于文件倉庫的優(yōu)點在于它的簡單,同時保留了現(xiàn)存文件的權(quán)限和網(wǎng)絡(luò)訪問權(quán)限。如果你的團隊已經(jīng)有一個全體共享的文件系統(tǒng),建立倉庫就十分容易了。你只需把一份純倉庫的副本放在大家能訪問的地方,然后像對其他共享目錄一樣設(shè)置讀寫權(quán)限就可以了。我們將在下一節(jié)“在服務(wù)器上部署 Git ”中討論如何為此導(dǎo)出一個純倉庫的副本。
這也是個從別人工作目錄里獲取他工作成果的快捷方法。假如你和你的同事在一個項目中合作,他們想讓你檢出一些東西的時候,運行類似git pull/home/john/project 通常會比他們推送到服務(wù)器,而你又從服務(wù)器獲取簡單得多。
缺點
這種方法的缺點是,與基本的網(wǎng)絡(luò)連接訪問相比,能從不同的位置訪問的共享權(quán)限難以架設(shè)。如果你想從家里的筆記本電腦上推送,就要先掛載遠程硬盤,這和基于網(wǎng)絡(luò)連接的訪問相比更加困難和緩慢。
另一個很重要的問題是該方法不一定就是最快的,尤其是對于共享掛載的文件系統(tǒng)。本地倉庫只有在你對數(shù)據(jù)訪問速度快的時候才快。在同一個服務(wù)器上,如果二者同時允許 Git 訪問本地硬盤,通過 NFS 訪問倉庫通常會比 SSH 慢。
SSH 協(xié)議
Git 使用的傳輸協(xié)議中最常見的可能就是 SSH 了。這是因為大多數(shù)環(huán)境已經(jīng)支持通過 SSH 對服務(wù)器的訪問——即使還沒有,也很容易架設(shè)。SSH 也是唯一一個同時便于讀和寫操作的網(wǎng)絡(luò)協(xié)議。另外兩個網(wǎng)絡(luò)協(xié)議(HTTP 和 Git)通常都是只讀的,所以雖然二者對大多數(shù)人都可用,但執(zhí)行寫操作時還是需要 SSH。SSH 同時也是一個驗證授權(quán)的網(wǎng)絡(luò)協(xié)議;而因為其普遍性,通常也很容易架設(shè)和使用。
通過 SSH 克隆一個 Git 倉庫,你可以像下面這樣給出 ssh:// 的 URL:
$ git clone ssh://user@server:project.git
或者不指明某個協(xié)議——這時 Git 會默認使用 SSH :
$ git clone user@server:project.git
也可以不指明用戶,Git會默認使用你當(dāng)前登錄的用戶。
優(yōu)點
使用 SSH 的好處有很多。首先,如果你想擁有對網(wǎng)絡(luò)倉庫的寫權(quán)限,基本上不可能不使用 SSH。其次,SSH 架設(shè)相對比較簡單——SSH 守護進程很常見,很多網(wǎng)絡(luò)管理員都有一些使用經(jīng)驗,而且很多操作系統(tǒng)都自帶了它或者相關(guān)的管理工具。再次,通過 SSH 進行訪問是安全的——所有數(shù)據(jù)傳輸都是加密和授權(quán)的。最后,類似 Git 和 本地協(xié)議,SSH 很高效,會在傳輸之前盡可能的壓縮數(shù)據(jù)。
缺點
SSH 的限制在于你不能通過它實現(xiàn)倉庫的匿名訪問。即使僅為讀取數(shù)據(jù),人們也必須在能通過 SSH 訪問主機的前提下才能訪問倉庫,這使得 SSH 不利于開源的項目。如果你僅僅在公司網(wǎng)絡(luò)里使用,SSH 可能是你唯一需要使用的協(xié)議。如果想允許對項目的匿名只讀訪問,那么除了為自己推送而架設(shè) SSH 協(xié)議之外,還需要其他協(xié)議來讓別人獲取數(shù)據(jù)。
Git 協(xié)議
接下來是 Git 協(xié)議。這是一個包含在 Git 軟件包中的特殊守護進程; 它會監(jiān)聽一個提供類似于 SSH 服務(wù)的特定端口(9418),而無需任何授權(quán)。用 Git 協(xié)議運營倉庫,你需要創(chuàng)建 git-export-daemon-ok 文件——它是協(xié)議進程提供倉庫服務(wù)的必要條件——但除此之外該服務(wù)沒有什么安全措施。要么所有人都能克隆 Git 倉庫,要么誰也不能。這也意味著該協(xié)議通常不能用來進行推送。你可以允許推送操作;然而由于沒有授權(quán)機制,一旦允許該操作,網(wǎng)絡(luò)上任何一個知道項目 URL 的人將都有推送權(quán)限。不用說,這是十分罕見的情況。
優(yōu)點
Git 協(xié)議是現(xiàn)存最快的傳輸協(xié)議。如果你在提供一個有很大訪問量的公共項目,或者一個不需要對讀操作進行授權(quán)的龐大項目,架設(shè)一個 Git 守護進程來供應(yīng)倉庫是個不錯的選擇。它使用與 SSH 協(xié)議相同的數(shù)據(jù)傳輸機制,但省去了加密和授權(quán)的開銷。
缺點
Git 協(xié)議消極的一面是缺少授權(quán)機制。用 Git 協(xié)議作為訪問項目的唯一方法通常是不可取的。一般做法是,同時提供 SSH 接口,讓幾個開發(fā)者擁有推送(寫)權(quán)限,其他人通過git:// 擁有只讀權(quán)限。 Git 協(xié)議可能也是最難架設(shè)的協(xié)議。它要求有單獨的守護進程,需要定制——我們將在本章的 “Gitosis” 一節(jié)詳細介紹它的架設(shè)——需要設(shè)定 xinetd 或類似的程序,而這些就沒那么平易近人了。該協(xié)議還要求防火墻開放 9418 端口,而企業(yè)級防火墻一般不允許對這個非標(biāo)準(zhǔn)端口的訪問。大型企業(yè)級防火墻通常會封鎖這個少見的端口。
HTTP/S 協(xié)議
最后還有 HTTP 協(xié)議。HTTP 或 HTTPS 協(xié)議的優(yōu)美之處在于架設(shè)的簡便性。基本上,只需要把 Git 的純倉庫文件放在 HTTP 的文件根目錄下,配置一個特定的 post-update 掛鉤(hook),就搞定了(Git 掛鉤的細節(jié)見第七章)。從此,每個能訪問 Git 倉庫所在服務(wù)器上的 web 服務(wù)的人都可以進行克隆操作。下面的操作可以允許通過 HTTP 對倉庫進行讀取:
$ 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
這樣就可以了。Git 附帶的post-update 掛鉤會默認運行合適的命令(gitupdate-server-info)來確保通過 HTTP 的獲取和克隆正常工作。這條命令在你用 SSH 向倉庫推送內(nèi)容時運行;之后,其他人就可以用下面的命令來克隆倉庫:
$ git clone http://example.com/gitproject.git
在本例中,我們使用了Apache 設(shè)定中常用的 /var/www/htdocs 路徑,不過你可以使用任何靜態(tài) web 服務(wù)——把純倉庫放在它的目錄里就行了。 Git 的數(shù)據(jù)是以最基本的靜態(tài)文件的形式提供的(關(guān)于如何提供文件的詳情見第9章)。
通過HTTP進行推送操作也是可能的,不過這種做法不太常見并且牽扯到復(fù)雜的 WebDAV 設(shè)定。由于很少用到,本書將略過對該內(nèi)容的討論。如果對 HTTP 推送協(xié)議感興趣,不妨在這個地址看一下操作方法:http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt 。通過 HTTP 推送的好處之一是你可以使用任何 WebDAV 服務(wù)器,不需要為 Git 設(shè)定特殊環(huán)境;所以如果主機提供商支持通過 WebDAV 更新網(wǎng)站內(nèi)容,你也可以使用這項功能。
優(yōu)點
使用 HTTP 協(xié)議的好處是易于架設(shè)。幾條必要的命令就可以讓全世界讀取到倉庫的內(nèi)容。花費不過幾分鐘。HTTP 協(xié)議不會占用過多服務(wù)器資源。因為它一般只用到靜態(tài)的 HTTP 服務(wù)提供所有的數(shù)據(jù),普通的 Apache 服務(wù)器平均每秒能供應(yīng)數(shù)千個文件——哪怕是讓一個小型的服務(wù)器超載都很難。
你也可以通過HTTPS 提供只讀的倉庫,這意味著你可以加密傳輸內(nèi)容;你甚至可以要求客戶端使用特定簽名的 SSL 證書。一般情況下,如果到了這一步,使用 SSH 公共密鑰可能是更簡單的方案;不過也存在一些特殊情況,這時通過 HTTPS 使用帶簽名的 SSL 證書或者其他基于 HTTP 的只讀連接授權(quán)方式是更好的解決方案。
HTTP 還有個額外的好處:HTTP 是一個如此常見的協(xié)議,以至于企業(yè)級防火墻通常都允許其端口的通信。
缺點
HTTP 協(xié)議的消極面在于,相對來說客戶端效率更低。克隆或者下載倉庫內(nèi)容可能會花費更多時間,而且 HTTP 傳輸?shù)捏w積和網(wǎng)絡(luò)開銷比其他任何一個協(xié)議都大。因為它沒有按需供應(yīng)的能力——傳輸過程中沒有服務(wù)端的動態(tài)計算——因而 HTTP 協(xié)議經(jīng)常會被稱為 傻瓜(dumb) 協(xié)議。更多 HTTP 協(xié)議和其他協(xié)議效率上的差異見第九章。
在服務(wù)器部署 Git
開始架設(shè) Git 服務(wù)器的時候,需要把一個現(xiàn)存的倉庫導(dǎo)出為新的純倉庫——不包含當(dāng)前工作目錄的倉庫。方法非常直截了當(dāng)。把一個倉庫克隆為純倉庫,可以使用clone 命令的 --bare 選項。純倉庫的目錄名以 .git 結(jié)尾, 如下:
$ git clone --bare my_project my_project.git
Initialized empty Git repository in /opt/projects/my_project.git/
該命令的輸出有點迷惑人。由于 clone 基本上等于 gitinit 加 git fetch,這里出現(xiàn)的就是 git init 的輸出,它建立了一個空目錄。實際的對象轉(zhuǎn)換不會有任何輸出,不過確實發(fā)生了。現(xiàn)在在 my_project.git 中已經(jīng)有了一份 Git 目錄數(shù)據(jù)的副本。
大體上相當(dāng)于
$ cp -Rf my_project/.git my_project.git
在配置文件中有幾個小改變;不過從效果角度講,克隆的內(nèi)容是一樣的。它僅包含了 Git 目錄,沒有工作目錄,并且專門為之(譯注: Git 目錄)建立了一個單獨的目錄。
將純目錄轉(zhuǎn)移到服務(wù)器
有了倉庫的純副本以后,剩下的就是把它放在服務(wù)器上并設(shè)定相關(guān)的協(xié)議。假設(shè)一個域名為git.example.com 的服務(wù)器已經(jīng)架設(shè)好,并可以通過 SSH 訪問,而你想把所有的 Git 倉庫儲存在 /opt/git 目錄下。只要把純倉庫復(fù)制上去:
$ scp -r my_project.git user@git.example.com:/opt/git
現(xiàn)在,其他對該服務(wù)器具有 SSH 訪問權(quán)限并可以讀取 /opt/git 的用戶可以用以下命令克隆:
$ git clone user@git.example.com:/opt/git/my_project.git
假如一個 SSH 用戶對/opt/git/my_project.git 目錄有寫權(quán)限,他會自動具有推送權(quán)限。這時如果運行 git init 命令的時候加上--shared 選項,Git 會自動對該倉庫加入可寫的組。
$ ssh user@git.example.com
$ cd /opt/git/my_project.git
$ git init --bare --shared
可見選擇一個 Git 倉庫,創(chuàng)建一個純的版本,最后把它放在你和同事都有 SSH 訪問權(quán)的服務(wù)器上是多么容易。現(xiàn)在已經(jīng)可以開始在同一項目上密切合作了。
值得注意的是,這的的確確是架設(shè)一個少數(shù)人具有連接權(quán)的 Git 服務(wù)的全部——只要在服務(wù)器上加入可以用 SSH 接入的帳號,然后把純倉庫放在大家都有讀寫權(quán)限的地方。一切都做好了,無須更多。
下面的幾節(jié)中,你會了解如何擴展到更復(fù)雜的設(shè)定。這些內(nèi)容包含如何避免為每一個用戶建立一個賬戶,給倉庫添加公共讀取權(quán)限,架設(shè)網(wǎng)頁界面,使用 Gitosis 工具等等。然而,只是和幾個人在一個不公開的項目上合作的話,僅僅是一個SSH 服務(wù)器和純倉庫就足夠了,請牢記這一點。
小型安裝
如果設(shè)備較少或者你只想在小型的開發(fā)團隊里嘗試 Git ,那么一切都很簡單。架設(shè) Git 服務(wù)最復(fù)雜的方面之一在于賬戶管理。如果需要倉庫對特定的用戶可讀,而給另一部分用戶讀寫權(quán)限,那么訪問和許可的安排就比較困難。
SSH 連接
如果已經(jīng)有了一個所有開發(fā)成員都可以用 SSH 訪問的服務(wù)器,架設(shè)第一個服務(wù)器將變得異常簡單,幾乎什么都不用做(正如上節(jié)中介紹的那樣)。如果需要對倉庫進行更復(fù)雜的訪問控制,只要使用服務(wù)器操作系統(tǒng)的本地文件訪問許可機制就行了。
如果需要團隊里的每個人都對倉庫有寫權(quán)限,又不能給每個人在服務(wù)器上建立賬戶,那么提供 SSH 連接就是唯一的選擇了。我們假設(shè)用來共享倉庫的服務(wù)器已經(jīng)安裝了 SSH 服務(wù),而且你通過它訪問服務(wù)器。
有好幾個辦法可以讓團隊的每個人都有訪問權(quán)。第一個辦法是給每個人建立一個賬戶,直截了當(dāng)?shù)^于繁瑣。反復(fù)的運行adduser 并且給所有人設(shè)定臨時密碼可不是好玩的。
第二個辦法是在主機上建立一個 git賬戶,讓每個需要寫權(quán)限的人發(fā)送一個 SSH 公鑰,然后將其加入 git賬戶的 ~/.ssh/authorized_keys 文件。這樣一來,所有人都將通過 git 賬戶訪問主機。這絲毫不會影響提交的數(shù)據(jù)——訪問主機用的身份不會影響commit的記錄。
另一個辦法是讓 SSH服務(wù)器通過某個 LDAP 服務(wù),或者其他已經(jīng)設(shè)定好的集中授權(quán)機制,來進行授權(quán)。只要每個人都能獲得主機的 shell 訪問權(quán),任何可用的 SSH 授權(quán)機制都能達到相同效果。
生成 SSH 公鑰
話雖如此,大多數(shù)Git 服務(wù)器使用 SSH 公鑰來授權(quán)。為了得到授權(quán),系統(tǒng)中的每個沒有公鑰用戶都得生成一個新的。該過程在所有操作系統(tǒng)上都差不多。首先,確定一下是否已經(jīng)有一個公鑰了。SSH 公鑰默認儲存在賬戶的 ~/.ssh 目錄。進入那里并查看其內(nèi)容,有沒有公鑰一目了然:
$ cd ~/.ssh
$ ls
authorized_keys2? id_dsa?????? known_hosts
config??????????? id_dsa.pub
關(guān)鍵是看有沒有用 文件名 和 文件名.pub 來命名的一對文件,這個 文件名 通常是 id_dsa 或者id_rsa。 .pub 文件是公鑰,另一個文件是密鑰。假如沒有這些文件(或者干脆連 .ssh 目錄都沒有),你可以用ssh-keygen 的程序來建立它們,該程序在 Linux/Mac 系統(tǒng)由 SSH 包提供, 在 Windows 上則包含在 MSysGit 包里:
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local
它先要求你確認保存公鑰的位置(.ssh/id_rsa),然后它會讓你重復(fù)一個密碼兩次,如果不想在使用公鑰的時候輸入密碼,可以留空。
現(xiàn)在,所有做過這一步的用戶都得把它們的公鑰給你或者 Git 服務(wù)器的管理者(假設(shè) SSH 服務(wù)被設(shè)定為使用公鑰機制)。他們只需要復(fù)制.put 文件的內(nèi)容然后 e-email 之。公鑰的樣子大致如下:
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== schacon@agadorlaptop.local
關(guān)于在多個操作系統(tǒng)上設(shè)立相同 SSH 公鑰的教程,可以在 GitHub 有關(guān) SSH 公鑰的向?qū)е姓业?#xff1a;http://github.com/guides/providing-your-ssh-key。
架設(shè)服務(wù)器
現(xiàn)在我們過一邊服務(wù)器端架設(shè) SSH 訪問的流程。本例將使用 authorized_keys 方法來給用戶授權(quán)。我們還將假定使用類似 Ubuntu 這樣的標(biāo)準(zhǔn) Linux 發(fā)行版。首先,創(chuàng)建一個 'git' 用戶并為其創(chuàng)建一個 .ssh 目錄(譯注:在用戶的主目錄下)。
$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh
接下來,把開發(fā)者的SSH 公鑰添加到這個用戶的 authorized_keys 文件中。假設(shè)你通過 e-mail 收到了幾個公鑰并存到了臨時文件里。重復(fù)一下,公鑰大致看起來是這個樣子:
$ cat /tmp/id_rsa.john.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
dAv8JggJICUvax2T9va5 gsg-keypair
只要把它們加入 authorized_keys 文件(譯注:本例加入到了文件尾部):
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys
現(xiàn)在可以使用 --bare 選項運行 gitinit 來設(shè)定一個空倉庫,這會初始化一個不包含工作目錄的倉庫。
$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init
這時,Join,Josie 或者 Jessica 就可以把它加為遠程倉庫,推送一個分支,從而把第一個版本的工程上傳到倉庫里了。值得注意的是,每次添加一個新項目都需要通過 shell 登入主機并創(chuàng)建一個純倉庫。我們不妨以 gitserver 作為git 用戶和倉庫所在的主機名。如果你在網(wǎng)絡(luò)內(nèi)部運行該主機,并且在 DNS 中設(shè)定gitserver 指向該主機,那么以下這些命令都是可用的:
#在John的電腦上
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/opt/git/project.git
$ git push origin master
這樣,其他人的克隆和推送也一樣變得很簡單:
$ git clone git@gitserver:/opt/git/project.git
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master
用這個方法可以很快捷的為少數(shù)幾個開發(fā)者架設(shè)一個可讀寫的 Git 服務(wù)。
作為一個額外的防范措施,你可以用 Git 自帶的 git-shell 簡單工具來把 git 用戶的活動限制在僅與 Git 相關(guān)。把它設(shè)為 git用戶登入的 shell,那么該用戶就不能擁有主機正常的shell 訪問權(quán)。為了實現(xiàn)這一點,需要指明用戶的登入shell 是 git-shell ,而不是 bash 或者 csh。你可能得編輯/etc/passwd 文件:
$ sudo vim /etc/passwd
在文件末尾,你應(yīng)該能找到類似這樣的行:
git:x:1000:1000::/home/git:/bin/sh
把 bin/sh 改為/usr/bin/git-shell (或者用 whichgit-shell 查看它的位置)。該行修改后的樣子如下:
git:x:1000:1000::/home/git:/usr/bin/git-shell
現(xiàn)在 git 用戶只能用 SSH 連接來推送和獲取 Git 倉庫,而不能直接使用主機 shell。嘗試登錄的話,你會看到下面這樣的拒絕信息:
$ ssh git@gitserver
fatal: What do you think I am? A shell?(你以為我是個啥?shell嗎?)
Connection to gitserver closed.(gitserver連接已斷開。)
公共訪問
匿名的讀取權(quán)限該怎么實現(xiàn)呢?也許除了內(nèi)部私有的項目之外,你還需要托管一些開源項目。抑或你使用一些自動化的服務(wù)器來進行編譯,或者一些經(jīng)常變化的服務(wù)器群組,而又不想整天生成新的 SSH 密鑰——總之,你需要簡單的匿名讀取權(quán)限。
或許對小型的配置來說最簡單的辦法就是運行一個靜態(tài) web 服務(wù),把它的根目錄設(shè)定為 Git 倉庫所在的位置,然后開啟本章第一節(jié)提到的post-update 掛鉤。這里繼續(xù)使用之前的例子。假設(shè)倉庫處于 /opt/git 目錄,主機上運行著 Apache 服務(wù)。重申一下,任何 web 服務(wù)程序都可以達到相同效果;作為范例,我們將用一些基本的 Apache 設(shè)定來展示大體需要的步驟。
首先,開啟掛鉤:
$ cd project.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
假如使用的 Git 版本小于 1.6,那 mv 命令可以省略—— Git 是從較晚的版本才開始在掛鉤實例的結(jié)尾添加 .sample 后綴名的。
post-update 掛鉤是做什么的呢?其內(nèi)容大致如下:
$ cat .git/hooks/post-update
#!/bin/sh
exec git-update-server-info
意思是當(dāng)通過 SSH 向服務(wù)器推送時,Git 將運行這個命令來更新 HTTP 獲取所需的文件。
其次,在 Apache配置文件中添加一個 VirtualHost 條目,把根文件(譯注: DocumentRoot 參數(shù))設(shè)定為 Git 項目的根目錄。假定 DNS 服務(wù)已經(jīng)配置好,會把 .gitserver 發(fā)送到任何你所在的主機來運行這些:
<VirtualHost *:80>
??? ServerName git.gitserver
??? DocumentRoot /opt/git
??? <Directory /opt/git/>
??????? Order allow, deny
??????? allow from all
??? </Directory>
</VirtualHost>
另外,需要把 /opt/git 目錄的 Unix 用戶組設(shè)定為 www-data ,這樣 web 服務(wù)才可以讀取倉庫內(nèi)容,因為 Apache 運行 CGI 腳本的模塊(默認)使用的是該用戶:
$ chgrp -R www-data /opt/git
重啟 Apache 之后,就可以通過項目的 URL 來克隆該目錄下的倉庫了。
$ git clone http://git.gitserver/project.git
這一招可以讓你在幾分鐘內(nèi)為相當(dāng)數(shù)量的用戶架設(shè)好基于 HTTP 的讀取權(quán)限。另一個提供非授權(quán)訪問的簡單方法是開啟一個 Git 守護進程,不過這將要求該進程的常駐——下一節(jié)將是想走這條路的人準(zhǔn)備的。
網(wǎng)頁界面 GitWeb
如今我們的項目已經(jīng)有了讀寫和只讀的連接方式,也許應(yīng)該再架設(shè)一個簡單的網(wǎng)頁界面使其更加可視化。為此,Git 自帶了一個叫做 GitWeb 的CGI 腳本。你可以在類似 http://git.kernel.org 這樣的站點找到 GitWeb 的應(yīng)用實例(見圖 4-1)。
如果想知道項目的GitWeb 長什么樣,Git 自帶了一個命令,可以在類似 lighttpd 或 webrick 這樣輕量級的服務(wù)器程序上打開一個臨時的實例。在 Linux 主機上通常都安裝了lighttpd ,這時就可以在項目目錄里輸入 git instaweb 來運行它。如果使用的是 Mac ,Leopard 預(yù)裝了Ruby,所以 webrick 應(yīng)該是最好的選擇。使用 lighttpd 以外的程序來啟用 git instaweb, 可以通過它的--httpd 選項來實現(xiàn)。
$ git instaweb --httpd=webrick
[2009-02-21 10:02:21] INFO? WEBrick 1.3.1
[2009-02-21 10:02:21] INFO? ruby 1.8.6 (2008-03-03) [universal-darwin9.0]
這會在 1234 端口開啟一個 HTTPD 服務(wù),隨之在瀏覽器中顯示該頁。簡單的很。需要關(guān)閉服務(wù)的時候,只要使用相同命令的 --stop 選項就好了:
$ git instaweb --httpd=webrick --stop
如果需要為團隊或者某個開源項目長期的運行 web 界面,那么 CGI 腳本就要由正常的網(wǎng)頁服務(wù)來運行。一些 Linux 發(fā)行版可以通過 apt 或 yum安裝一個叫做 gitweb 的軟件包,不妨首先嘗試一下。我們將快速的介紹一下手動安裝 GitWeb 的流程。首先,你需要 Git 的源碼,其中帶有 GitWeb,并能生成 CGI 腳本:
$ git clone git://git.kernel.org/pub/scm/git/git.git
$ cd git/
$ make GITWEB_PROJECTROOT="/opt/git" \
??????? prefix=/usr gitweb/gitweb.cgi
$ sudo cp -Rf gitweb /var/www/
注意通過指定 GITWEB_PROJECTROOT 變量告訴編譯命令 Git 倉庫的位置。然后,讓 Apache 來提供腳本的 CGI,為此添加一個 VirtualHost:
<VirtualHost *:80>
??? ServerName gitserver
??? DocumentRoot /var/www/gitweb
??? <Directory /var/www/gitweb>
??????? Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
??????? AllowOverride All
??????? order allow,deny
??????? Allow from all
??????? AddHandler cgi-script cgi
??????? DirectoryIndex gitweb.cgi
??? </Directory>
</VirtualHost>
不難想象,GitWeb可以使用任何兼容 CGI 的網(wǎng)頁服務(wù)來運行;如果偏向使用其他的(譯注:這里指Apache 以外的服務(wù)),配置也不會很麻煩。現(xiàn)在,通過 http://gitserver 就可以在線訪問倉庫了,在 http://git.server 上還可以通過 HTTP 克隆和獲取倉庫的內(nèi)容。 Again, GitWeb can be served with any CGI capable web server; if youprefer to use something else, it shouldn’t be difficult to set up. At thispoint, you should be able to visit http://gitserver/ to view your repositories online, and you can use http://git.gitserver to clone and fetch your repositories over HTTP.
權(quán)限管理器 Gitosis
把所有用戶的公鑰保存在 authorized_keys 文件的做法只能暫時奏效。當(dāng)用戶數(shù)量到了幾百人的時候,它會變成一種痛苦。每一次都必須進入服務(wù)器的 shell,而且缺少對連接的限制——文件里的每個人都對所有項目擁有讀寫權(quán)限。
現(xiàn)在,是時候向廣泛使用的軟件 Gitosis 求救了。Gitosis 簡單的說就是一套用來管理 authorized_keys 文件和實現(xiàn)簡單連接限制的腳本。最有意思的是,該軟件用來添加用戶和設(shè)定權(quán)限的界面不是網(wǎng)頁,而是一個特殊的 Git 倉庫。你只需要設(shè)定好某個項目;然后推送,Gitosis 就會隨之改變服務(wù)器設(shè)定,酷吧?
Gitosis 的安裝算不上傻瓜化,不過也不算太難。用 Linux 服務(wù)器架設(shè)起來最簡單——以下例子中的服務(wù)器使用 Ubuntu 8.10 系統(tǒng)。
Gitosis 需要使用部分 Python 工具,所以首先要安裝 Python 的 setuptools 包,在 Ubuntu 中名為 python-setuptools:
$ apt-get install python-setuptools
接下來,從項目主頁克隆和安裝 Gitosis:
$ git clone git://eagain.net/gitosis.git
$ cd gitosis
$ sudo python setup.py install
這會安裝幾個Gitosis 用的可執(zhí)行文件。現(xiàn)在,Gitosis 想把它的倉庫放在 /home/git,倒也可以。不過我們的倉庫已經(jīng)建立在/opt/git 了,這時可以創(chuàng)建一個文件連接,而不用從頭開始重新配置:
$ ln -s /opt/git /home/git/repositories
Gitosis 將為我們管理公鑰,所以當(dāng)前的文件需要刪除,以后再重新添加公鑰,并且讓 Gitosis 自動控制 authorized_keys 文件。現(xiàn)在,把 authorized_keys文件移走:
$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak
然后恢復(fù) 'git' 用戶的 shell,假設(shè)之前把它改成了 git-shell 命令。其他人仍然不能通過它來登錄系統(tǒng),不過這次有 Gitosis 幫我們實現(xiàn)。所以現(xiàn)在把 /etc/passwd 文件的這一行
git:x:1000:1000::/home/git:/usr/bin/git-shell
恢復(fù)成:
git:x:1000:1000::/home/git:/bin/sh
現(xiàn)在就可以初始化Gitosis 了。需要通過自己的公鑰來運行 gitosis-init。如果公鑰不在服務(wù)器上,則必須復(fù)制一份:
$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/
這樣該公鑰的擁有者就能修改包含著 Gitosis 設(shè)置的那個 Git 倉庫了。然后手動將這個新的控制倉庫中的post-update 腳本加上執(zhí)行權(quán)限。
$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update
萬事俱備了。如果設(shè)定過程沒出什么差錯,現(xiàn)在可以試一下用初始化 Gitosis 公鑰的擁有者身份 SSH 進服務(wù)器。看到的結(jié)果應(yīng)該和下面類似:
$ ssh git@gitserver
PTY allocation request failed on channel 0
fatal: unrecognized command 'gitosis-serve schacon@quaternion'
? Connection to gitserver closed.
說明 Gitosis 認出了該用戶的身份,但由于沒有運行任何 Git 命令所以它切斷了連接。所以,現(xiàn)在運行一個確切的 Git 命令——克隆 Gitosis 的控制倉庫:
#在自己的電腦上
$ git clone git@gitserver:gitosis-admin.git
得到一個名為 gitosis-admin 的目錄,主要由兩部分組成:
$ cd gitosis-admin
$ find .
./gitosis.conf
./keydir
./keydir/scott.pub
gitosis.conf 文件是用來設(shè)置用戶、倉庫和權(quán)限的控制文件。keydir 目錄則是保存所有具有訪問權(quán)限用戶公鑰的地方——每人一個。你 keydir 中的文件名(前例中的 scott.pub)應(yīng)該有所不同—— Gitosis 從使用 gitosis-init 腳本導(dǎo)入的公鑰尾部的描述中獲取該名。
看一下 gitosis.conf 的內(nèi)容,它應(yīng)該只包含與剛剛克隆的gitosis-admin 相關(guān)的信息:
$ cat gitosis.conf
[gitosis]
?
[group gitosis-admin]
writable = gitosis-admin
members = scott
它顯示用戶 scott ——初始化 Gitosis 公鑰的擁有者——是唯一能訪問 gitosis-admin 項目的人。
現(xiàn)在我們添加一個新的項目。我們將添加一個名為 mobile 的新節(jié)段,在這里羅列手機開發(fā)團隊的開發(fā)者以及他們需要訪問權(quán)限的項目。由于'scott' 是系統(tǒng)中的唯一用戶,我們把它加成唯一的用戶,從創(chuàng)建一個叫做 iphone_project的新項目開始:
[group mobile]
writable = iphone_project
members = scott
一旦修改了 gitosis-admin 項目的內(nèi)容,只有提交并推送至服務(wù)器才能使之生效:
$ git commit -am 'add iphone_project and mobile group'
[master]: created 8962da8: "changed name"
1 files changed, 4 insertions(+), 0 deletions(-)
$ git push
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 272 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@gitserver:/opt/git/gitosis-admin.git
?? fb27aec..8962da8? master -> master
第一次向新工程 iphone_project 的推送需要在本地的版本中把服務(wù)器添加為一個 remote 然后推送。從此手動為新項目在服務(wù)器上創(chuàng)建純倉庫的麻煩就是歷史了—— Gitosis 會在第一次遇到推送的時候自動創(chuàng)建它們:
$ git remote add origin git@gitserver:iphone_project.git
$ git push origin master
Initialized empty Git repository in /opt/git/iphone_project.git/
Counting objects: 3, done.
Writing objects: 100% (3/3), 230 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:iphone_project.git
* [new branch]????? master -> master
注意到路徑被忽略了(加上它反而沒用),只有一個冒號加項目的名字—— Gitosis 會為你找到項目的位置。
要和朋友們共同在一個項目上共同工作,就得重新添加他們的公鑰。不過這次不用在服務(wù)器上一個一個手動添加到~/.ssh/authorized_keys 文件末端,而是在 keydir 目錄為每一個公鑰添加一個文件。文件的命名將決定在 gitosis.conf 文件中用戶的稱呼。現(xiàn)在我們?yōu)?John,Josie 和Jessica 添加公鑰:
$ cp /tmp/id_rsa.john.pub keydir/john.pub
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub
然后把他們都加進'mobile' 團隊,讓他們對 iphone_project 具有讀寫權(quán)限:
[group mobile]
writable = iphone_project
members = scott john josie jessica
如果你提交并推送這個修改,四個用戶將同時具有該項目的讀寫權(quán)限。
Gitosis 也具有簡單的訪問控制功能。如果想讓 John 只有讀權(quán)限,可以這樣做:
[group mobile]
writable = iphone_project
members = scott josie jessica
?
[group mobile_ro]
readonly = iphone_project
members = john
現(xiàn)在 John 可以克隆和獲取更新,但 Gitosis 不會允許他向項目推送任何內(nèi)容。這樣的組可以有盡可能有隨意多個,每一個包含不同的用戶和項目。甚至可以指定某個組為成員,來繼承它所有的成員。
如果出現(xiàn)了什么問題,把 loglevel=DEBUG 加入到 [gitosis] 部分或許有幫助(譯注:把日志設(shè)置到調(diào)試級別,記錄更詳細的信息)。如果你一不小心搞錯了配置,失去了推送權(quán)限,可以手動修改服務(wù)器上的/home/git/.gitosis 文件—— Gitosis 從該文件讀取信息。一次推送會把 gitosis.conf 保存在服務(wù)器上。如果你手動編輯該文件,它將在你下次向 gitosis-admin 推送之前它將保持原樣。
Git 進程
公共,非授權(quán)的只讀訪問要求我們在 HTTP 協(xié)議的基礎(chǔ)上使用 Git 協(xié)議。主因在于速度。Git 協(xié)議更為高效,進而比 HTTP 協(xié)議更迅速,所以它能節(jié)省很多時間。
重申一下,這一點只適用于非授權(quán)、只讀的訪問。如果在防火墻之外的服務(wù)器上,該服務(wù)的使用應(yīng)該局限于公諸于世的項目。假如是在防火墻之內(nèi),它也可以用于具有大量參與人員或者主機(長期整合資源或編譯的服務(wù)器)的只讀訪問的項目,可以省去為逐一添加 SSH 公鑰的麻煩。
無論哪種情況,Git 協(xié)議的設(shè)定都相對簡單。基本上,只要以長期守護進程的形式運行該命令:
git daemon --reuseaddr --base-path=/opt/git/ /opt/git/
--reuseaddr 使得服務(wù)無須等到舊的連接嘗試過期以后再重啟,--base-path 選項使得克隆項目的時候不用給出完整的路徑,而最后面的路徑告訴 Git 進程導(dǎo)出倉庫的位置。假如有防火墻,則需要為該主機的 9418 端口打個允許通信的洞。
有幾個不同的辦法可以讓該進程長期駐留,取決于不同的操作系統(tǒng)。在 Ubuntu 主機上,可以用 Upstart 腳本來完成。于是,在下面這個文件
/etc/event.d/local-git-daemon
加入該腳本內(nèi)容:
start on startup
stop on shutdown
exec /usr/bin/git daemon \
??? --user=git --group=git \
??? --reuseaddr \
??? --base-path=/opt/git/ \
??? /opt/git/
respawn
出于安全考慮,強烈建議用一個對倉庫只有讀取權(quán)限的用戶身份來運行該進程——只需要簡單的新創(chuàng)建一個 git-ro 用戶(譯注:并將它對倉庫的權(quán)限設(shè)為只讀),用它來運行進程。為了簡化,下面我們將依舊使用運行了 Gitosis 的 'git' 用戶。
重啟主機的時候,Git進程會自行啟動,一旦關(guān)閉了也會自行重啟。要不重啟就開啟它,可以運行這個命令:
initctl start local-git-daemon
在其他系統(tǒng)上,或許應(yīng)該使用 xinetd,sysinit 的一個腳本,或者其他的——只要能讓那個命令進程化和可監(jiān)控。
然后,必須告訴Gitosis 服務(wù)那些倉庫允許基于 Git 協(xié)議的非授權(quán)訪問。如果為每一個倉庫設(shè)立了自己的節(jié)段,就可以指定想讓 Git 進程給予可讀權(quán)限的倉庫。假如要允許通過 Git 協(xié)議訪問前面的 iphone 項目,可以把如下內(nèi)容加到 gitosis.conf 文件的結(jié)尾:
[repo iphone_project]
daemon = yes
在提交和推送完成以后,運行中的進程將開始相應(yīng)所有能訪問主機 9418 端口的人發(fā)來的項目請求。
假如不想使用Gitosis,而又想架設(shè)一個 Git 協(xié)議進程,則必須為每一個想使用 Git 進程的項目運行如下命令:
$ cd /path/to/project.git
$ touch git-daemon-export-ok
該文件(譯注:指空文件git-deamon-export-ok)告訴 Git 允許對該項目的非授權(quán)訪問。
Gitosis 還能控制 GitWeb 顯示哪些項目。首先,在 /etc/gitweb.conf 添加如下內(nèi)容:
$projects_list = "/home/git/gitosis/projects.list";
$projectroot = "/home/git/repositories";
$export_ok = "git-daemon-export-ok";
@git_base_url_list = ('git://gitserver');
通過在 Gitosis的設(shè)置文件里添加或刪除 gitweb 設(shè)定,就能控制 GitWeb 允許用戶瀏覽哪些項目。比如,我們想讓 iphone 項目在 GitWeb 里出現(xiàn),把 repo 的設(shè)定改成下面的樣子:
[repo iphone_project]
daemon = yes
gitweb = yes
如果現(xiàn)在提交和推送該項目,GitWeb 會自動開始展示我們的 iphone 項目。
Git 托管服務(wù)
如果不想經(jīng)歷自己架設(shè)Git 服務(wù)器的麻煩,網(wǎng)絡(luò)上有幾個專業(yè)的倉庫托管服務(wù)可供選擇。這樣做有幾大優(yōu)點:托管賬戶的建立通常比較省時,方便項目的啟動,而且不涉及服務(wù)其的維護和監(jiān)控。即使內(nèi)部創(chuàng)建并運行了自己的服務(wù)器,為開源的代碼使用一個公共托管站點還是有好處——讓開源社區(qū)更方便的找到該項目并給予幫助。
目前,可供選擇的托管服務(wù)數(shù)量繁多,各有利弊。在 Git 官方 wiki 上的Githosting 頁面有一個持續(xù)更新的托管服務(wù)列表:
http://git.or.cz/gitwiki/GitHosting
由于本書無法全部一一介紹它們,而本人(譯注:指本書作者 Scott Chacon )剛好在其中之一工作,我們將在這一節(jié)介紹一下在 GitHub建立賬戶和開啟新項目的過程。為你提供一個使用托管服務(wù)的大致印象。
GitHub 是到目前為止最大的開源 Git 托管服務(wù),并且是少數(shù)同時提供公共托管和私人托管服務(wù)的站點之一,所以你可以在一個站點同時保存開源和商業(yè)代碼。事實上,本書正是私下使用 GitHub 合寫的。(譯注:而本書的翻譯也是在 GitHub 上進行公共合作的)。
GitHub
GitHub 和大多數(shù)的代碼托管站點在處理項目命名空間的方式上略有不同。GitHub 的設(shè)計更側(cè)重于用戶,而不是而不是全部基于項目。意謂本人在 GitHub 上托管一個grit 項目的話,它將不會出現(xiàn)在 github.com/grit,而是在github.com/shacon/grit (譯注:作者在 GitHub 上的用戶名是 shacon)。不存在所謂某個項目的官方版本,所以假如第一作者放棄了某個項目,它可以無縫轉(zhuǎn)移到其它用戶的旗下。
GitHub 同時也是一個向使用私有倉庫的用戶收取費用的商業(yè)公司,不過所有人都可以快捷的得到一個免費賬戶并且在上面托管任意多的開源項目。我們將快速介紹一下該過程。
建立賬戶
第一個必要必要步驟是注冊一個免費的賬戶。訪問 Pricing and Signup (價格與注冊)頁面 http://github.com/plans 并點擊 Free acount (免費賬戶)的 "Sign Up(注冊)" 按鈕(見圖 4-2),進入注冊頁面。 The first thing you need to dois set up a free user account. If you visit the Pricing and Signup page at http://github.com/plans and click the "Sign Up" button on the Free account (seefigure 4-2), you’re taken to the signup page.
這里要求選擇一個系統(tǒng)中尚未存在的用戶名,提供一個與之相連的電郵地址,以及一個密碼(見圖 4-3)。
如果事先有準(zhǔn)備,可以順便提供 SSH 公鑰。我們在前文中的"小型安裝" 一節(jié)介紹過生成新公鑰的方法。把生成的鑰匙對中的公鑰粘貼到 SSHPublic Key (SSH 公鑰)文本框中。點擊"explain ssh keys" 鏈接可以獲取在所有主流操作系統(tǒng)上完成該步驟的介紹。點擊 "I agree,sign me up (同意條款,讓我注冊)" 按鈕就能進入新用戶的控制面板(見圖 4-4)。
然后就可以建立新倉庫了。
建立新倉庫
點擊用戶面板上倉庫旁邊的 "create a new one(新建)" 連接。進入 Create a New Repository (新建倉庫)表格(見圖 4-5)。
唯一必做的僅僅是提供一個項目名稱,當(dāng)然也可以添加一點描述。搞定這些以后,點 "Create Repository(建立倉庫)" 按鈕。新倉庫就建立起來了(見圖4-6)。
由于還沒有提交代碼,GitHub會展示如何創(chuàng)建一個新項目,如何推送一個現(xiàn)存項目,以及如何從一個公共的 Subversion 倉庫導(dǎo)入項目(譯注:這簡直是公開挖 google code 和 sourceforge 的墻角)(見圖 4-7)。
該指南和本書前文中的介紹類似。要把一個非 Git 項目變成 Git 項目,運行
$ git init
$ git add .
$ git commit -m 'initial commit'
一旦擁有一個本地Git 倉庫,把 GitHub 添加為遠程倉庫并推送master 分支:
$ git remote add origin git@github.com:testinguser/iphone_project.git
$ git push origin master
這時該項目就托管在GitHub 上了。你可以把它的 URL 發(fā)給每個希望分享該工程的人。本例的 URL 是 http://github.com/testinguser/iphone_project。你將在項目頁面的頭部發(fā)現(xiàn)有兩個 Git URL(見圖 4-8)。
PublicClone URL(公共克隆 URL)是一個公開的,只讀的Git URL,任何人都可以通過它克隆該項目。可以隨意的散播這個 URL,發(fā)步到個人網(wǎng)站之類的地方。
Your CloneURL(私用克隆 URL)是一個給予 SSH 的讀寫 URL,只有使用與上傳的 SSH 公鑰對應(yīng)的密鑰來連接時,才能通過它進行讀寫操作。其他用戶訪問項目頁面的時候看不到該URL——只有公共的那個。
從 Subversion 中導(dǎo)入項目
如果想把某個公共Subversion 項目導(dǎo)入 Git,GitHub 可以幫忙。在指南的最后有一個指向?qū)?Subversion 頁面的鏈接。點擊它,可以得到一個表格,它包含著有關(guān)導(dǎo)入流程的信息以及一個用來粘貼公共 Subversion 項目連接的文本框(見圖 4-9)。
如果項目很大,采用非標(biāo)準(zhǔn)結(jié)構(gòu),或者是私有的,那么該流程將不適用。在第七章,你將了解到手動導(dǎo)入復(fù)雜工程的方法。
開始合作
現(xiàn)在把團隊里其他的人也加進來。如果 John,Josie 和Jessica 都在 GitHub 注冊了賬戶,要給他們向倉庫推送的訪問權(quán),可以把它們加為項目合作者。這樣他們的公鑰就能用來向倉庫推送了。
點擊項目頁面上方的"edit(編輯)" 按鈕或者頂部的Admin (管理)標(biāo)簽進入項目管理頁面(見圖 4-10)。
為了給另一個用戶添加項目的寫權(quán)限,點擊 "Add another collaborator(添加另一個合作者)"鏈接。一個新文本框會出現(xiàn),用來輸入用戶名。在輸入用戶名的同時將會跳出一個幫助提示,顯示出可能匹配的用戶名。找到正確的用戶名以后,點 Add (添加)按鈕,把它變成該項目的合作者(見圖 4-11)。
添加完合作者以后,就可以在 Repository Collaborators (倉庫合作者)區(qū)域看到他們的列表(見圖 4-12)。
如果需要取消某人的訪問權(quán),點擊 "revoke (撤銷)",他的推送權(quán)限就被刪除了。在未來的項目中,可以通過復(fù)制現(xiàn)存項目的權(quán)限設(shè)定來得到相同的合作者群組。
項目頁面
在推送或從Subversion 導(dǎo)入項目之后,你會得到一個類似圖 4-13 的項目主頁。
其他人訪問你的項目時,他們會看到該頁面。它包含了該項目不同方面的標(biāo)簽。Commits 標(biāo)簽將按時間展示逆序的 commit 列表,與 git log 命令的輸出類似。Network 標(biāo)簽展示所有 fork 了該項目并做出貢獻的用戶的關(guān)系圖。Downloads 標(biāo)簽允許你上傳項目的二進制文件,并提供了指向該項目所有標(biāo)記過的位置的 tar/zip 打包下載連接。Wiki 標(biāo)簽提供了一個用來撰寫文檔或其他項目相關(guān)信息的 wiki。Graphs 標(biāo)簽包含了一些可視化的項目信息與數(shù)據(jù)。剛開始進入的 Source 標(biāo)簽頁面列出了項目的主目錄;并且在下方自動展示 README 文件的內(nèi)容(如果該文件存在的話)。該標(biāo)簽還包含了最近一次提交的相關(guān)信息。
派生(forking)項目
如果想向一個自己沒有推送權(quán)限的項目貢獻代碼,GitHub 提倡使用派生(forking)。在你發(fā)現(xiàn)一個感興趣的項目,打算在上面 Hack 一把的時候,可以點擊頁面上方的 "fork(派生)" 按鈕,GitHub 會為你的用戶復(fù)制一份該項目,這樣你就可以向它推送內(nèi)容了。
使用這個辦法,項目維護者不用操心為了推送權(quán)限把其他人加為合作者的麻煩。大家可以派生一個項目副本并進行推送,而后項目的主要維護者可以把這些副本添加為遠程倉庫,從中拉取更新的內(nèi)容進行合并。
要派生一個項目,到該項目的頁面(本例中是 mojombo/chronic)點擊上面的 "fork" 按鈕(見圖 4-14)。
幾秒鐘以后,你將進入新建的項目頁面,顯示出該項目是派生自另一個項目的副本(見圖 4-15)。
GitHub 小節(jié)
GitHub 就介紹這么多,不過意識到做到這些是多么快捷十分重要。不過幾分鐘的時間,你就能創(chuàng)建一個賬戶,添加一個新的項目并開始推送。如果你的項目是開源的,它還同時獲得了對龐大的開發(fā)者社區(qū)的可視性,社區(qū)成員可能會派生它并做出貢獻。退一萬步講,這至少是個快速開始嘗試 Git 的好辦法。
小節(jié)
幾個不同的方案可以讓你獲得遠程 Git 倉庫來與其他人合作或分享你的成果。
運行自己的服務(wù)器意味著更多的控制權(quán)以及在防火墻內(nèi)部操作的可能性,然而這樣的服務(wù)器通常需要投入一定的時間來架設(shè)和維護。如果把數(shù)據(jù)放在托管服務(wù)上,假設(shè)和維護變得十分簡單;然而,你不得不把代碼保存在別人的服務(wù)器上,很多公司不允許這種做法。
使用哪個方案或哪種方案的組合對你和你的團隊更合適,應(yīng)該不是一個太難的決定。
?
總結(jié)
以上是生活随笔為你收集整理的git学习——服务器上的 Git的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020牛客暑期多校训练营(第二场)Ju
- 下一篇: 2021牛客第一场 K.Knowledg