<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## Git詳解之四 服務器上的Git **服務器上的 Git** 到目前為止,你應該已經學會了使用 Git來完成日常工作。然而,如果想與他人合作,還需要一個遠程的 Git倉庫。盡管技術上可以從個人的倉庫里推送和拉取修改內容,但我們不鼓勵這樣做,因為一不留心就很容易弄混其他人的進度。另外,你也一定希望合作者們即使在自己不開機的時候也能從倉庫獲取數據 —擁有一個更穩定的公共倉庫十分有用。因此,更好的合作方式是建立一個大家都可以訪問的共享倉庫,從那里推送和拉取數據。我們將把這個倉庫稱為 “Git服務器”;代理一個 Git倉庫只需要花費很少的資源,幾乎從不需要整個服務器來支持它的運行。 架設一臺 Git服務器并不難。第一步是選擇與服務器通訊的協議。本章第一節將介紹可用的協議以及各自優缺點。下面一節將介紹一些針對各個協議典型的設置以及如何在服務器上實施。最后,如果你不介意在他人服務器上保存你的代碼,又想免去自己架設和維護服務器的麻煩,倒可以試試我們介紹的幾個倉庫托管服務。 如果你對架設自己的服務器沒興趣,可以跳到本章最后一節去看看如何申請一個代碼托管服務的賬戶然后繼續下一章,我們會在那里討論分布式源碼控制環境的林林總總。 遠程倉庫通常只是一個_裸倉庫(bare repository)_ — 即一個沒有當前工作目錄的倉庫。因為該倉庫只是一個合作媒介,所以不需要從硬盤上取出最新版本的快照;倉庫里存放的僅僅是 Git的數據。簡單地說,裸倉庫就是你工作目錄中.git?子目錄內的內容。 ? ? **4.1?協議** Git 可以使用四種主要的協議來傳輸數據:本地傳輸,SSH協議,Git 協議和 HTTP 協議。下面分別介紹一下哪些情形應該使用(或避免使用)這些協議。 值得注意的是,除了 HTTP協議外,其他所有協議都要求在服務器端安裝并運行 Git。 **本地協議** 最基本的就是_本地協議(Local protocol)_,所謂的遠程倉庫在該協議中的表示,就是硬盤上的另一個目錄。這常見于團隊每一個成員都對一個共享的文件系統(例如 NFS)擁有訪問權,或者比較少見的多人共用同一臺電腦的情況。后面一種情況并不安全,因為所有代碼倉庫實例都儲存在同一臺電腦里,增加了災難性數據損失的可能性。 如果你使用一個共享的文件系統,就可以在一個本地文件系統中克隆倉庫,推送和獲取。克隆的時候只需要將遠程倉庫的路徑作為 URL使用,比如下面這樣: ~~~ $ git clone /opt/git/project.git ~~~ 或者這樣: ~~~ $ git clone file:///opt/git/project.git ~~~ 如果在 URL開頭明確使用?file://?,那么Git會以一種略微不同的方式運行。如果你只給出路徑,Git會嘗試使用硬鏈接或直接復制它所需要的文件。如果使用了file://?,Git會調用它平時通過網絡來傳輸數據的工序,而這種方式的效率相對較低。使用?file://?前綴的主要原因是當你需要一個不包含無關引用或對象的干凈倉庫副本的時候 — 一般指從其他版本控制系統導入的,或類似情形(參見第 9章的維護任務)。我們這里僅僅使用普通路徑,這樣更快。 要添加一個本地倉庫作為現有 Git項目的遠程倉庫,可以這樣做: ~~~ $ git remote add local_proj /opt/git/project.git ~~~ 然后就可以像在網絡上一樣向這個遠程倉庫推送和獲取數據了。 **優點** 基于文件倉庫的優點在于它的簡單,同時保留了現存文件的權限和網絡訪問權限。如果你的團隊已經有一個全體共享的文件系統,建立倉庫就十分容易了。你只需把一份裸倉庫的副本放在大家都能訪問的地方,然后像對其他共享目錄一樣設置讀寫權限就可以了。我們將在下一節“在服務器上部署 Git ”中討論如何導出一個裸倉庫的副本。 這也是從別人工作目錄中獲取工作成果的快捷方法。假如你和你的同事在一個項目中合作,他們想讓你檢出一些東西的時候,運行類似?git pull /home/john/project?通常會比他們推送到服務器,而你再從服務器獲取簡單得多。 **缺點** 這種方法的缺點是,與基本的網絡連接訪問相比,難以控制從不同位置來的訪問權限。如果你想從家里的筆記本電腦上推送,就要先掛載遠程硬盤,這和基于網絡連接的訪問相比更加困難和緩慢。 另一個很重要的問題是該方法不一定就是最快的,尤其是對于共享掛載的文件系統。本地倉庫只有在你對數據訪問速度快的時候才快。在同一個服務器上,如果二者同時允許 Git訪問本地硬盤,通過 NFS訪問倉庫通常會比 SSH慢。 **SSH協議** Git 使用的傳輸協議中最常見的可能就是SSH了。這是因為大多數環境已經支持通過 SSH對服務器的訪問 — 即便還沒有,架設起來也很容易。SSH也是唯一一個同時支持讀寫操作的網絡協議。另外兩個網絡協議(HTTP和 Git)通常都是只讀的,所以雖然二者對大多數人都可用,但執行寫操作時還是需要 SSH。SSH同時也是一個驗證授權的網絡協議;而因為其普遍性,一般架設和使用都很容易。 通過 SSH克隆一個 Git 倉庫,你可以像下面這樣給出 ssh://的 URL: ~~~ $ git clone ssh://user@server:project.git ~~~ 或者不指明某個協議 —這時 Git 會默認使用 SSH : ~~~ $ git clone user@server:project.git ~~~ 如果不指明用戶,Git會默認使用當前登錄的用戶名連接服務器。 **優點** 使用 SSH的好處有很多。首先,如果你想擁有對網絡倉庫的寫權限,基本上不可能不使用 SSH。其次,SSH架設相對比較簡單 — SSH守護進程很常見,很多網絡管理員都有一些使用經驗,而且很多操作系統都自帶了它或者相關的管理工具。再次,通過 SSH進行訪問是安全的 — 所有數據傳輸都是加密和授權的。最后,和 Git及本地協議一樣,SSH也很高效,會在傳輸之前盡可能壓縮數據。 **缺點** SSH 的限制在于你不能通過它實現倉庫的匿名訪問。即使僅為讀取數據,人們也必須在能通過 SSH訪問主機的前提下才能訪問倉庫,這使得 SSH不利于開源的項目。如果你僅僅在公司網絡里使用,SSH可能是你唯一需要使用的協議。如果想允許對項目的匿名只讀訪問,那么除了為自己推送而架設 SSH協議之外,還需要支持其他協議以便他人訪問讀取。 **Git協議** 接下來是 Git協議。這是一個包含在 Git軟件包中的特殊守護進程;它會監聽一個提供類似于 SSH服務的特定端口(9418),而無需任何授權。打算支持 Git協議的倉庫,需要先創建git-export-daemon-ok?文件 —它是協議進程提供倉庫服務的必要條件 —但除此之外該服務沒有什么安全措施。要么所有人都能克隆 Git倉庫,要么誰也不能。這也意味著該協議通常不能用來進行推送。你可以允許推送操作;然而由于沒有授權機制,一旦允許該操作,網絡上任何一個知道項目 URL的人將都有推送權限。不用說,這是十分罕見的情況。 **優點** Git 協議是現存最快的傳輸協議。如果你在提供一個有很大訪問量的公共項目,或者一個不需要對讀操作進行授權的龐大項目,架設一個 Git守護進程來供應倉庫是個不錯的選擇。它使用與 SSH協議相同的數據傳輸機制,但省去了加密和授權的開銷。 **缺點** Git 協議消極的一面是缺少授權機制。用Git協議作為訪問項目的唯一方法通常是不可取的。一般的做法是,同時提供 SSH接口,讓幾個開發者擁有推送(寫)權限,其他人通過git://?擁有只讀權限。Git協議可能也是最難架設的協議。它要求有單獨的守護進程,需要定制 —我們將在本章的 “Gitosis”一節詳細介紹它的架設 —需要設定xinetd?或類似的程序,而這些工作就沒那么輕松了。該協議還要求防火墻開放 9418端口,而企業級防火墻一般不允許對這個非標準端口的訪問。大型企業級防火墻通常會封鎖這個少見的端口。 **HTTP/S協議** 最后還有 HTTP協議。HTTP 或 HTTPS 協議的優美之處在于架設的簡便性。基本上,只需要把 Git的裸倉庫文件放在 HTTP的根目錄下,配置一個特定的post-update?掛鉤(hook)就可以搞定(Git掛鉤的細節見第 7 章)。此后,每個能訪問 Git 倉庫所在服務器上 web 服務的人都可以進行克隆操作。下面的操作可以允許通過 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?掛鉤會默認運行合適的命令(git update-server-info)來確保通過 HTTP 的獲取和克隆正常工作。這條命令在你用 SSH向倉庫推送內容時運行;之后,其他人就可以用下面的命令來克隆倉庫: ~~~ $ git clone http://example.com/gitproject.git ~~~ 在本例中,我們使用了 Apache設定中常用的?/var/www/htdocs?路徑,不過你可以使用任何靜態web服務 — 把裸倉庫放在它的目錄里就行。Git 的數據是以最基本的靜態文件的形式提供的(關于如何提供文件的詳情見第 9章)。 通過 HTTP進行推送操作也是可能的,不過這種做法不太常見,并且牽扯到復雜的 WebDAV設定。由于很少用到,本書將略過對該內容的討論。如果對 HTTP推送協議感興趣,不妨打開這個地址看一下操作方法:http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt?。通過 HTTP 推送的好處之一是你可以使用任何 WebDAV服務器,不需要為 Git設定特殊環境;所以如果主機提供商支持通過 WebDAV更新網站內容,你也可以使用這項功能。 **優點** 使用 HTTP協議的好處是易于架設。幾條必要的命令就可以讓全世界讀取到倉庫的內容。花費不過幾分鐘。HTTP協議不會占用過多服務器資源。因為它一般只用到靜態的 HTTP服務提供所有數據,普通的 Apache服務器平均每秒能支撐數千個文件的并發訪問 —哪怕讓一個小型服務器超載都很難。 你也可以通過 HTTPS提供只讀的倉庫,這意味著你可以加密傳輸內容;你甚至可以要求客戶端使用特定簽名的 SSL證書。一般情況下,如果到了這一步,使用 SSH公共密鑰可能是更簡單的方案;不過也存在一些特殊情況,這時通過 HTTPS使用帶簽名的 SSL 證書或者其他基于 HTTP 的只讀連接授權方式是更好的解決方案。 HTTP 還有個額外的好處:HTTP是一個如此常見的協議,以至于企業級防火墻通常都允許其端口的通信。 **缺點** HTTP 協議的消極面在于,相對來說客戶端效率更低。克隆或者下載倉庫內容可能會花費更多時間,而且 HTTP傳輸的體積和網絡開銷比其他任何一個協議都大。因為它沒有按需供應的能力 —傳輸過程中沒有服務端的動態計算 —因而 HTTP 協議經常會被稱為_傻瓜(dumb)_協議。更多 HTTP 協議和其他協議效率上的差異見第 9。 **4.2?在服務器上部署 Git** 開始架設 Git服務器前,需要先把現有倉庫導出為裸倉庫 —即一個不包含當前工作目錄的倉庫。做法直截了當,克隆時用?--bare?選項即可。裸倉庫的目錄名一般以.git?結尾,像這樣: ~~~ $ git clone --bare my_project my_project.git Initialized empty Git repository in/opt/projects/my_project.git/ ~~~ 該命令的輸出或許會讓人有些不解。其實?clone?操作基本上相當于?git init?加?git fetch,所以這里出現的其實是git init?的輸出,先由它建立一個空目錄,而之后傳輸數據對象的操作并無任何輸出,只是悄悄在幕后執行。現在my_project.git?目錄中已經有了一份 Git 目錄數據的副本。 整體上的效果大致相當于: ~~~ $ cp -Rf my_project/.git my_project.git ~~~ 但在配置文件中有若干小改動,不過對用戶來講,使用方式都一樣,不會有什么影響。它僅取出 Git倉庫的必要原始數據,存放在該目錄中,而不會另外創建工作目錄。 **把裸倉庫移到服務器上** 有了裸倉庫的副本后,剩下的就是把它放到服務器上并設定相關協議。假設一個域名為?git.example.com?的服務器已經架設好,并可以通過SSH訪問,我們打算把所有Git倉庫儲存在/opt/git?目錄下。只要把裸倉庫復制過去: ~~~ $ scp -r my_project.git user@git.example.com:/opt/git ~~~ 現在,所有對該服務器有 SSH訪問權限,并可讀取?/opt/git?目錄的用戶都可以用下面的命令克隆該項目: ~~~ $ git clone user@git.example.com:/opt/git/my_project.git ~~~ 如果某個 SSH用戶對?/opt/git/my_project.git?目錄有寫權限,那他就有推送權限。如果到該項目目錄中運行?git init?命令,并加上?--shared?選項,那么 Git 會自動修改該倉庫目錄的組權限為可寫(譯注:實際上?--shared?可以指定其他行為,只是默認為將組權限改為可寫并執行?g+sx,所以最后會得到?rws。)。 ~~~ $ ssh user@git.example.com $ cd /opt/git/my_project.git $ git init --bare --shared ~~~ 由此可見,根據現有的 Git倉庫創建一個裸倉庫,然后把它放上你和同事都有 SSH訪問權的服務器是多么容易。現在已經可以開始在同一項目上密切合作了。 值得注意的是,這的的確確是架設一個少數人具有連接權的 Git服務的全部 — 只要在服務器上加入可以用 SSH 登錄的帳號,然后把裸倉庫放在大家都有讀寫權限的地方。一切都準備停當,無需更多。 下面的幾節中,你會了解如何擴展到更復雜的設定。這些內容包含如何避免為每一個用戶建立一個賬戶,給倉庫添加公共讀取權限,架設網頁界面,使用 Gitosis工具等等。然而,只是和幾個人在一個不公開的項目上合作的話,僅僅是一個 SSH服務器和裸倉庫就足夠了,記住這點就可以了。 **小型安裝** 如果設備較少或者你只想在小型開發團隊里嘗試 Git,那么一切都很簡單。架設 Git服務最復雜的地方在于賬戶管理。如果需要倉庫對特定的用戶可讀,而給另一部分用戶讀寫權限,那么訪問和許可的安排就比較困難。 **SSH連接** 如果已經有了一個所有開發成員都可以用 SSH訪問的服務器,架設第一個服務器將變得異常簡單,幾乎什么都不用做(正如上節中介紹的那樣)。如果需要對倉庫進行更復雜的訪問控制,只要使用服務器操作系統的本地文件訪問許可機制就行了。 如果需要團隊里的每個人都對倉庫有寫權限,又不能給每個人在服務器上建立賬戶,那么提供 SSH連接就是唯一的選擇了。我們假設用來共享倉庫的服務器已經安裝了 SSH服務,而且你通過它訪問服務器。 有好幾個辦法可以讓團隊的每個人都有訪問權。第一個辦法是給每個人建立一個賬戶,直截了當但略過繁瑣。反復運行adduser?并給所有人設定臨時密碼可不是好玩的。 第二個辦法是在主機上建立一個?git?賬戶,讓每個需要寫權限的人發送一個 SSH 公鑰,然后將其加入?git?賬戶的~/.ssh/authorized_keys?文件。這樣一來,所有人都將通過?git?賬戶訪問主機。這絲毫不會影響提交的數據 — 訪問主機用的身份不會影響提交對象的提交者信息。 另一個辦法是讓 SSH服務器通過某個 LDAP服務,或者其他已經設定好的集中授權機制,來進行授權。只要每個人都能獲得主機的 shell訪問權,任何可用的 SSH授權機制都能達到相同效果。 ? **4.3?生成 SSH 公鑰** 大多數 Git服務器都會選擇使用 SSH公鑰來進行授權。系統中的每個用戶都必須提供一個公鑰用于授權,沒有的話就要生成一個。生成公鑰的過程在所有操作系統上都差不多。首先先確認一下是否已經有一個公鑰了。SSH公鑰默認儲存在賬戶的主目錄下的~/.ssh?目錄。進去看看: ~~~ $ cd ~/.ssh $ ls authorized_keys2?id_dsa?????? known_hosts config???????????id_dsa.pub ~~~ 關鍵是看有沒有用?something?和?something.pub?來命名的一對文件,這個?something?通常就是?id_dsa?或?id_rsa。有?.pub后綴的文件就是公鑰,另一個文件則是密鑰。假如沒有這些文件,或者干脆連.ssh?目錄都沒有,可以用?ssh-keygen?來創建。該程序在Linux/Mac系統上由 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:3aschacon@agadorlaptop.local ~~~ 它先要求你確認保存公鑰的位置(.ssh/id_rsa),然后它會讓你重復一個密碼兩次,如果不想在使用公鑰的時候輸入密碼,可以留空。 現在,所有做過這一步的用戶都得把它們的公鑰給你或者 Git服務器的管理員(假設 SSH服務被設定為使用公鑰機制)。他們只需要復制?.pub?文件的內容然后發郵件給管理員。公鑰的樣子大致如下: ~~~ $ cat ~/.ssh/id_rsa.pub ssh-rsaAAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx NrRFi9wrf+M7Q== schacon@agadorlaptop.local ~~~ 關于在多個操作系統上設立相同 SSH公鑰的教程,可以查閱 GitHub上有關 SSH 公鑰的向導:http://github.com/guides/providing-your-ssh-key。 ? **4.4?架設服務器** 現在我們過一邊服務器端架設 SSH訪問的流程。本例將使用?authorized_keys?方法來給用戶授權。我們還將假定使用類似 Ubuntu 這樣的標準 Linux發行版。首先,創建一個名為 ‘git’的用戶,并為其創建一個.ssh?目錄。 ~~~ $ sudo adduser git $ su git $ cd $ mkdir .ssh ~~~ 接下來,把開發者的 SSH公鑰添加到這個用戶的?authorized_keys?文件中。假設你通過電郵收到了幾個公鑰并存到了臨時文件里。重復一下,公鑰大致看起來是這個樣子: ~~~ $ cat /tmp/id_rsa.john.pub ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/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 ~~~ 現在可以用?--bare?選項運行?git init?來建立一個裸倉庫,這會初始化一個不包含工作目錄的倉庫。 ~~~ $ cd /opt/git $ mkdir project.git $ cd project.git $ git --bare init ~~~ 這時,Join,Josie或者 Jessica 就可以把它加為遠程倉庫,推送一個分支,從而把第一個版本的項目文件上傳到倉庫里了。值得注意的是,每次添加一個新項目都需要通過 shell登入主機并創建一個裸倉庫目錄。我們不妨以gitserver?作為?git?用戶及項目倉庫所在的主機名。如果在網絡內部運行該主機,并在 DNS 中設定?gitserver?指向該主機,那么以下這些命令都是可用的: ~~~ # 在John 的電腦上 $ cd myproject $ git init $ git add . $ git commit -m 'initial commit' $ git remote add origingit@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 ~~~ 用這個方法可以很快捷地為少數幾個開發者架設一個可讀寫的 Git服務。 作為一個額外的防范措施,你可以用 Git自帶的?git-shell?工具限制?git?用戶的活動范圍。只要把它設為git?用戶登入的 shell,那么該用戶就無法使用普通的 bash或者 csh 什么的 shell 程序。編輯?/etc/passwd?文件: ~~~ $ sudo vim /etc/passwd ~~~ 在文件末尾,你應該能找到類似這樣的行: git:x:1000:1000::/home/git:/bin/sh 把?bin/sh?改為?/usr/bin/git-shell?(或者用?which git-shell?查看它的實際安裝路徑)。該行修改后的樣子如下: git:x:1000:1000::/home/git:/usr/bin/git-shell 現在?git?用戶只能用 SSH 連接來推送和獲取 Git倉庫,而不能直接使用主機 shell。嘗試普通 SSH登錄的話,會看到下面這樣的拒絕信息: ~~~ $ ssh git@gitserver fatal: What do you think I am? A shell? Connection to gitserver closed. ~~~ **4.5?公共訪問** 匿名的讀取權限該怎么實現呢?也許除了內部私有的項目之外,你還需要托管一些開源項目。或者因為要用一些自動化的服務器來進行編譯,或者有一些經常變化的服務器群組,而又不想整天生成新的 SSH密鑰 — 總之,你需要簡單的匿名讀取權限。 或許對小型的配置來說最簡單的辦法就是運行一個靜態 web服務,把它的根目錄設定為 Git倉庫所在的位置,然后開啟本章第一節提到的?post-update?掛鉤。這里繼續使用之前的例子。假設倉庫處于/opt/git?目錄,主機上運行著Apache服務。重申一下,任何web服務程序都可以達到相同效果;作為范例,我們將用一些基本的 Apache設定來展示大體需要的步驟。 首先,開啟掛鉤: ~~~ $ cd project.git $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update ~~~ 如果用的是 Git 1.6之前的版本,則可以省略?mv?命令 — Git是從較晚的版本才開始在掛鉤實例的結尾添加 .sample后綴名的。 post-update?掛鉤是做什么的呢?其內容大致如下: ~~~ $ cat .git/hooks/post-update #!/bin/sh exec git-update-server-info ~~~ 意思是當通過 SSH向服務器推送時,Git將運行這個?git-update-server-info?命令來更新匿名 HTTP訪問獲取數據時所需要的文件。 接下來,在 Apache配置文件中添加一個 VirtualHost條目,把文檔根目錄設為 Git項目所在的根目錄。這里我們假定 DNS服務已經配置好,會把對.gitserver?的請求發送到這臺主機: ~~~ ??? ServerNamegit.gitserver ??? DocumentRoot/opt/git ??????????????Order allow, deny ??????? allow fromall ~~~ 另外,需要把?/opt/git?目錄的 Unix 用戶組設定為?www-data?,這樣web服務才可以讀取倉庫內容,因為運行CGI腳本的Apache 實例進程默認就是以該用戶的身份起來的: ~~~ $ chgrp -R www-data /opt/git ~~~ 重啟 Apache之后,就可以通過項目的 URL來克隆該目錄下的倉庫了。 ~~~ $ git clone http://git.gitserver/project.git ~~~ 這一招可以讓你在幾分鐘內為相當數量的用戶架設好基于 HTTP的讀取權限。另一個提供非授權訪問的簡單方法是開啟一個 Git守護進程,不過這將要求該進程作為后臺進程常駐 —接下來的這一節就要討論這方面的細節。 ? **4.6? GitWeb** 現在我們的項目已經有了可讀可寫和只讀的連接方式,不過如果能有一個簡單的 web界面訪問就更好了。Git自帶一個叫做 GitWeb的 CGI 腳本,運行效果可以到http://git.kernel.org?這樣的站點體驗下(見圖 4-1)。 Figure 4-1. 基于網頁的 GitWeb用戶界面 如果想看看自己項目的效果,不妨用 Git自帶的一個命令,可以使用類似?lighttpd?或?webrick?這樣輕量級的服務器啟動一個臨時進程。如果是在 Linux 主機上,通常都預裝了lighttpd?,可以到項目目錄中鍵入?git instaweb?來啟動。如果用的是Mac,Leopard 預裝了Ruby,所以webrick?應該是最好的選擇。如果要用 lighttpd 以外的程序來啟動?git instaweb,可以通過--httpd?選項指定: ~~~ $ 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服務,隨之在瀏覽器中顯示該頁,十分簡單。關閉服務時,只需在原來的命令后面加上--stop?選項就可以了: ~~~ $ git instaweb --httpd=webrick --stop ~~~ 如果需要為團隊或者某個開源項目長期運行 GitWeb,那么 CGI腳本就要由正常的網頁服務來運行。一些 Linux發行版可以通過?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=/usrgitweb/gitweb.cgi $ sudo cp -Rf gitweb /var/www/ ~~~ 注意,通過指定?GITWEB_PROJECTROOT?變量告訴編譯命令 Git 倉庫的位置。然后,設置 Apache以 CGI 方式運行該腳本,添加一個 VirtualHost配置: ~~~ ??? ServerNamegitserver ??? DocumentRoot/var/www/gitweb ??????????????Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch ???????AllowOverride All ??????? orderallow,deny ??????? Allow fromall ??????? AddHandlercgi-script cgi ???????DirectoryIndex gitweb.cgi ~~~ 不難想象,GitWeb可以使用任何兼容 CGI的網頁服務來運行;如果偏向使用其他 web服務器,配置也不會很麻煩。現在,通過?http://gitserver?就可以在線訪問倉庫了,在http://git.server?上還可以通過HTTP克隆和獲取倉庫的內容。 **4.7? Gitosis** 把所有用戶的公鑰保存在?authorized_keys?文件的做法,只能湊和一陣子,當用戶數量達到幾百人的規模時,管理起來就會十分痛苦。每次改刪用戶都必須登錄服務器不去說,這種做法還缺少必要的權限管理 — 每個人都對所有項目擁有完整的讀寫權限。 幸好我們還可以選擇應用廣泛的 Gitosis項目。簡單地說,Gitosis就是一套用來管理?authorized_keys?文件和實現簡單連接限制的腳本。有趣的是,用來添加用戶和設定權限的并非通過網頁程序,而只是管理一個特殊的 Git 倉庫。你只需要在這個特殊倉庫內做好相應的設定,然后推送到服務器上,Gitosis就會隨之改變運行策略,聽起來就很酷,對吧? Gitosis 的安裝算不上傻瓜化,但也不算太難。用 Linux服務器架設起來最簡單 —以下例子中,我們使用裝有 Ubuntu 8.10系統的服務器。 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使用的工具。默認 Gitosis會把?/home/git?作為存儲所有Git倉庫的根目錄,這沒什么不好,不過我們之前已經把項目倉庫都放在/opt/git?里面了,所以為方便起見,我們可以做一個符號連接,直接劃轉過去,而不必重新配置: ~~~ $ ln -s /opt/git /home/git/repositories ~~~ Gitosis 將會幫我們管理用戶公鑰,所以先把當前控制文件改名備份,以便稍后重新添加,準備好讓 Gitosis自動管理authorized_keys?文件: ~~~ $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak ~~~ 接下來,如果之前把?git?用戶的登錄 shell 改為?git-shell?命令的話,先恢復‘git’用戶的登錄shell。改過之后,大家仍然無法通過該帳號登錄(譯注:因為authorized_keys?文件已經沒有了。),不過不用擔心,這會交給 Gitosis 來實現。所以現在先打開?/etc/passwd?文件,把這行: git:x:1000:1000::/home/git:/usr/bin/git-shell 改回: git:x:1000:1000::/home/git:/bin/sh 好了,現在可以初始化 Gitosis了。你可以用自己的公鑰執行?gitosis-init?命令,要是公鑰不在服務器上,先臨時復制一份: ~~~ $ 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的那個特殊 Git 倉庫了。接下來,需要手工對該倉庫中的?post-update?腳本加上可執行權限: ~~~ $ sudo chmod 755/opt/git/gitosis-admin.git/hooks/post-update ~~~ 基本上就算是好了。如果設定過程沒出什么差錯,現在可以試一下用初始化 Gitosis的公鑰的擁有者身份 SSH登錄服務器,應該會看到類似下面這樣: ~~~ $ ssh git@gitserver PTY allocation request failed on channel 0 fatal: unrecognized command 'gitosis-serveschacon@quaternion' ? Connection togitserver closed. ~~~ 說明 Gitosis認出了該用戶的身份,但由于沒有運行任何 Git命令,所以它切斷了連接。那么,現在運行一個實際的 Git命令 — 克隆 Gitosis 的控制倉庫: ~~~ # 在你本地計算機上 $ git clone git@gitserver:gitosis-admin.git ~~~ 這會得到一個名為?gitosis-admin?的工作目錄,主要由兩部分組成: ~~~ $ cd gitosis-admin $ find . ./gitosis.conf ./keydir ./keydir/scott.pub ~~~ gitosis.conf?文件是用來設置用戶、倉庫和權限的控制文件。keydir?目錄則是保存所有具有訪問權限用戶公鑰的地方—每人一個。在keydir?里的文件名(比如上面的?scott.pub)應該跟你的不一樣 — Gitosis 會自動從使用?gitosis-init?腳本導入的公鑰尾部的描述中獲取該名字。 看一下?gitosis.conf?文件的內容,它應該只包含與剛剛克隆的?gitosis-admin?相關的信息: ~~~ $ cat gitosis.conf [gitosis] [group gitosis-admin] writable = gitosis-admin members = scott ~~~ 它顯示用戶?scott?—初始化 Gitosis公鑰的擁有者 — 是唯一能管理?gitosis-admin?項目的人。 現在我們來添加一個新項目。為此我們要建立一個名為?mobile?的新段落,在其中羅列手機開發團隊的開發者,以及他們擁有寫權限的項目。由于 ‘scott’ 是系統中的唯一用戶,我們把他設為唯一用戶,并允許他讀寫名為iphone_project?的新項目: ~~~ [group mobile] writable = iphone_project members = scott ~~~ 修改完之后,提交?gitosis-admin?里的改動,并推送到服務器使其生效: ~~~ $ git commit -am 'add iphone_project and mobile group' [master]: created 8962da8: "changed name" ?1 files changed, 4insertions(+), 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?里首次推送數據到服務器前,得先設定該服務器地址為遠程倉庫。但你不用事先到服務器上手工創建該項目的裸倉庫— Gitosis 會在第一次遇到推送時自動創建: ~~~ $ 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 ?* [newbranch]????? master -> master ~~~ 請注意,這里不用指明完整路徑(實際上,如果加上反而沒用),只需要一個冒號加項目名字即可 — Gitosis會自動幫你映射到實際位置。 要和朋友們在一個項目上協同工作,就得重新添加他們的公鑰。不過這次不用在服務器上一個一個手工添加到~/.ssh/authorized_keys?文件末端,而只需管理keydir?目錄中的公鑰文件。文件的命名將決定在?gitosis.conf?中對用戶的標識。現在我們為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?具有讀寫權限: ~~~ [group mobile] writable = iphone_project members = scott john josie jessica ~~~ 如果你提交并推送這個修改,四個用戶將同時具有該項目的讀寫權限。 Gitosis 也具有簡單的訪問控制功能。如果想讓 John只有讀權限,可以這樣做: ~~~ [group mobile] writable = iphone_project members = scott josie jessica [group mobile_ro] readonly = iphone_project members = john ~~~ 現在 John可以克隆和獲取更新,但 Gitosis不會允許他向項目推送任何內容。像這樣的組可以隨意創建,多少不限,每個都可以包含若干不同的用戶和項目。甚至還可以指定某個組為成員之一(在組名前加上@?前綴),自動繼承該組的成員: ~~~ [group mobile_committers] members = scott josie jessica [group mobile] writable? =iphone_project members?? =@mobile_committers [group mobile_2] writable? =another_iphone_project members?? =@mobile_committers john ~~~ 如果遇到意外問題,試試看把?loglevel=DEBUG?加到?[gitosis]?的段落(譯注:把日志設置為調試級別,記錄更詳細的運行信息。)。如果一不小心搞錯了配置,失去了推送權限,也可以手工修改服務器上的/home/git/.gitosis.conf?文件 — Gitosis 實際是從該文件讀取信息的。它在得到推送數據時,會把新的?gitosis.conf?存到該路徑上。所以如果你手工編輯該文件的話,它會一直保持到下次向?gitosis-admin?推送新版本的配置內容為止。 **4.8? Gitolite** Note: thelatest copy of this section of the ProGit book is always available within the[gitolite documentation](http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd). The author would alsolike to humbly state that, while this section is accurate, and**can**?(andoften?**has**) been used to install gitolite without reading any otherdocumentation, it is of necessity not complete, and cannot completely replacethe enormous amount of documentation that gitolite comes with. Git hasstarted to become very popular in corporate environments, which tend to have someadditional requirements in terms of access control. Gitolite was originallycreated to help with those requirements, but it turns out that it’s equallyuseful in the open source world: the Fedora Project controls access to theirpackage management repositories (over 10,000 of them!) using gitolite, and thisis probably the largest gitolite installation anywhere too. Gitoliteallows you to specify permissions not just by repository, but also by branch ortag names within each repository. That is, you can specify that certain people(or groups of people) can only push certain “refs” (branches or tags) but notothers. **Installing** InstallingGitolite is very easy, even if you don’t read the extensive documentation thatcomes with it. You need an account on a Unix server of some kind; various Linuxflavours, and Solaris 10, have been tested. You do not need root access,assuming git, perl, and an openssh compatible ssh server are already installed.In the examples below, we will use thegitolite?accounton a host called?gitserver. Gitoliteis somewhat unusual as far as “server” software goes – access is via ssh, andso every userid on the server is a potential “gitolite host”. As a result,there is a notion of “installing” the software itself, and then “setting up” auser as a “gitolite host”. Gitolitehas 4 methods of installation. People using Fedora or Debian systems can obtainan RPM or a DEB and install that. People with root access can install itmanually. In these two methods, any user on the system can then become a“gitolite host”. Peoplewithout root access can install it within their own userids. And finally,gitolite can be installed by running a script**on the workstation**, from abash shell. (Even the bash that comes with msysgit will do, in case you’re wondering.) We willdescribe this last method in this article; for the other methods please see thedocumentation. You startby obtaining public key based access to your server, so that you can log infrom your workstation to the server without getting a password prompt. Thefollowing method works on Linux; for other workstation OSs you may have to dothis manually. We assume you already had a key pair generated using?ssh-keygen. ~~~ $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver ~~~ This willask you for the password to the gitolite account, and then set up public keyaccess. This is**essential**?for the install script, so check to makesure you can run a command without getting a password prompt: ~~~ $ ssh gitolite@gitserver pwd /home/gitolite ~~~ Next, youclone Gitolite from the project’s main site and run the “easy install” script(the third argument is your name as you would like it to appear in theresulting gitolite-admin repository): ~~~ $ git clone git://github.com/sitaramc/gitolite $ cd gitolite/src $ ./gl-easy-install -q gitolite gitserver sitaram ~~~ And you’redone! Gitolite has now been installed on the server, and you now have a brandnew repository calledgitolite-admin?in the home directory of yourworkstation. You administer your gitolite setup by making changes to thisrepository and pushing. That lastcommand does produce a fair amount of output, which might be interesting toread. Also, the first time you run this, a new keypair is created; you willhave to choose a passphrase or hit enter for none. Why a second keypair isneeded, and how it is used, is explained in the “ssh troubleshooting” documentthat comes with Gitolite. (Hey the documentation has to be good for**something**!) Reposnamed?gitolite-admin?and?testing?arecreated on the server by default. If you wish to clone either of these locally(from an account that has SSH console access to the gitolite account via**authorized_keys**),type: ~~~ $ git clone gitolite:gitolite-admin $ git clone gitolite:testing To clonethese same repos from any other account: $ git clone gitolite@servername:gitolite-admin $ git clone gitolite@servername:testing ~~~ **Customising the Install** While thedefault, quick, install works for most people, there are some ways to customisethe install if you need to. If you omit the-q?argument,you get a “verbose” mode install – detailed information on what the install isdoing at each step. The verbose mode also allows you to change certainserver-side parameters, such as the location of the actual repositories, byediting an “rc” file that the server uses. This “rc” file is liberallycommented so you should be able to make any changes you need quite easily, saveit, and continue. This file also contains various settings that you can changeto enable or disable some of gitolite’s advanced features. **Config File and Access Control Rules** Once theinstall is done, you switch to the?gitolite-admin?repository(placed in your HOME directory) and poke around to see what you got: ~~~ $ cd ~/gitolite-admin/ $ ls conf/? keydir/ $ find conf keydir -type f conf/gitolite.conf keydir/sitaram.pub $ cat conf/gitolite.conf #gitolite conf # please see conf/example.conf for details on syntax andfeatures ? repo gitolite-admin ??? RW+???????????????? = sitaram ? repo testing ??? RW+???????????????? = @all ~~~ Noticethat “sitaram” (the last argument in the?gl-easy-install?commandyou gave earlier) has read-write permissions on thegitolite-admin?repositoryas well as a public key file of the same name. The configfile syntax for gitolite is liberally documented in?conf/example.conf, so we’ll only mention some highlights here. You cangroup users or repos for convenience. The group names are just like macros; whendefining them, it doesn’t even matter whether they are projects or users; thatdistinction is only made when you**use**?the “macro”. ~~~ @oss_repos????? =linux perl rakudo git gitolite @secret_repos?? =fenestra pear ? @admins???????? =scott???? # Adams, not Chacon, sorry :) @interns??????? =ashok???? # get the spelling right,Scott! @engineers????? =sitaram dilbert wally alice @staff????????? =@admins @engineers @interns ~~~ You cancontrol permissions at the “ref” level. In the following example, interns canonly push the “int” branch. Engineers can push any branch whose name startswith “eng-“, and tags that start with “rc” followed by a digit. And the adminscan do anything (including rewind) to any ref. ~~~ repo @oss_repos ??? RW? int$??????????????? = @interns ??? RW?eng-??????????????? = @engineers ??? RW? refs/tags/rc[0-9]?? = @engineers ??? RW+???????????????????? = @admins ~~~ Theexpression after the?RW?or?RW+?isa regular expression (regex) that the refname (ref) being pushed is matchedagainst. So we call it a “refex”! Of course, a refex can be far more powerfulthan shown here, so don’t overdo it if you’re not comfortable with perlregexes. Also, asyou probably guessed, Gitolite prefixes?refs/heads/?asa syntactic convenience if the refex does not begin withrefs/. Animportant feature of the config file’s syntax is that all the rules for arepository need not be in one place. You can keep all the common stufftogether, like the rules for alloss_repos?shown above, then add specific rulesfor specific cases later on, like so: repo gitolite ??? RW+???????????????????? = sitaram That rulewill just get added to the ruleset for the?gitolite?repository. At thispoint you might be wondering how the access control rules are actually applied,so let’s go over that briefly. There aretwo levels of access control in gitolite. The first is at the repository level;if you have read (or write) access to**any**?ref in the repository,then you have read (or write) access to the repository. The secondlevel, applicable only to “write” access, is by branch or tag within arepository. The username, the access being attempted (W?or+),and the refname being updated are known. The access rules are checked in orderof appearance in the config file, looking for a match for this combination (butremember that the refname is regex-matched, not merely string-matched). If amatch is found, the push succeeds. A fallthrough results in access beingdenied. **Advanced Access Control with “deny” rules** So far,we’ve only seen permissions to be one or?R,?RW,orRW+. However, gitolite allows another permission:?-,standing for “deny”. This gives you a lot more power, at the expense of somecomplexity, because now fallthrough is not the**only**?way for accessto be denied, so the?**order of the rules now matters**! Let ussay, in the situation above, we want engineers to be able to rewind any branch**except**?masterand integ. Here’s how to do that: ~~~ ??? RW? master integ??? = @engineers ??? -?? master integ??? = @engineers ??? RW+???????????????? = @engineers ~~~ Again, yousimply follow the rules top down until you hit a match for your access mode, ora deny. Non-rewind push to master or integ is allowed by the first rule. Arewind push to those refs does not match the first rule, drops down to thesecond, and is therefore denied. Any push (rewind or non-rewind) to refs otherthan master or integ won’t match the first two rules anyway, and the third ruleallows it. **Restricting pushes by files changed** Inaddition to restricting what branches a user can push changes to, you can alsorestrict what files they are allowed to touch. For example, perhaps theMakefile (or some other program) is really not supposed to be changed by justanyone, because a lot of things depend on it or would break if the changes arenot done?**just right**. You can tell gitolite: ~~~ repo foo ??? RW????????????????? =?? @junior_devs @senior_devs ? ??? RW? NAME/?????????? =??@senior_devs ??? -?? NAME/Makefile?? =??@junior_devs ??? RW? NAME/?????????? =??@junior_devs Thispowerful feature is documented in?conf/example.conf. ~~~ **Personal Branches** Gitolitealso has a feature called “personal branches” (or rather, “personal branchnamespace”) that can be very useful in a corporate environment. A lot ofcode exchange in the git world happens by “please pull” requests. In acorporate environment, however, unauthenticated access is a no-no, and adeveloper workstation cannot do authentication, so you have to push to thecentral server and ask someone to pull from there. This wouldnormally cause the same branch name clutter as in a centralised VCS, plussetting up permissions for this becomes a chore for the admin. Gitolitelets you define a “personal” or “scratch” namespace prefix for each developer(for example,refs/personal/?/*?); see the “personal branches” sectionin?doc/3-faq-tips-etc.mkd?for details. **“Wildcard” repositories** Gitoliteallows you to specify repositories with wildcards (actually perl regexes),like, for exampleassignments/s[0-9][0-9]/a[0-9][0-9], to pick a random example. This is a**very**?powerfulfeature, which has to be enabled by setting$GL_WILDREPOS = 1;?in the rc file. It allows you to assign a newpermission mode (”C”) which allows users to create repositories based on suchwild cards, automatically assigns ownership to the specific user who createdit, allows him/her to hand out R and RW permissions to other users tocollaborate, etc. This feature is documented indoc/4-wildcard-repositories.mkd. **Other Features** We’llround off this discussion with a sampling of other features, all of which, andmany more, are described in great detail in the “faqs, tips, etc” and otherdocuments. **Logging**: Gitolite logs all successful accesses. Ifyou were somewhat relaxed about giving people rewind permissions (RW+) and some kid blew away “master”, the log file is a lifesaver, in terms of easily and quickly finding the SHA that got hosed. **Gitoutside normal PATH**: Oneextremely useful convenience feature in gitolite is support for git installedoutside the normal$PATH?(this is more common than you think;some corporate environments or even some hosting providers refuse to installthings system-wide and you end up putting them in your own directories).Normally, you are forced to make the**client-side**?git aware of thisnon-standard location of the git binaries in some way. With gitolite, justchoose a verbose install and set$GIT_PATH?in the “rc” files. No client-sidechanges are required after that :-) **Accessrights reporting**: Anotherconvenient feature is what happens when you try and just ssh to the server.Gitolite shows you what repos you have access to, and what that access may be.Here’s an example: ??? hello sitaram,the gitolite version here is v1.5.4-19-ga3397d4 ??? the gitoliteconfig gives you the following access: ???????? R???? anu-wsd ???????? R???? entrans ???????? R? W?git-notes ???????? R? W?gitolite ???????? R? W?gitolite-admin ???????? R???? indic_web_input ???????? R???? shreelipi_converter **Delegation**: For really large installations, you candelegate responsibility for groups of repositories to various people and havethem manage those pieces independently. This reduces the load on the mainadmin, and makes him less of a bottleneck. This feature has its owndocumentation file in the?doc/?directory. **Gitwebsupport**: Gitolite supportsgitweb in several ways. You can specify which repos are visible via gitweb. Youcan set the “owner” and “description” for gitweb from the gitolite config file.Gitweb has a mechanism for you to implement access control based on HTTPauthentication, so you can make it use the “compiled” config file that gitoliteproduces, which means the same access control rules (for read access) apply forgitweb and gitolite. **Mirroring**: Gitolite can help you maintain multiplemirrors, and switch between them easily if the primary server goes down. ? **4.9? Git守護進程** 對于提供公共的,非授權的只讀訪問,我們可以拋棄 HTTP協議,改用 Git 自己的協議,這主要是出于性能和速度的考慮。Git協議遠比 HTTP 協議高效,因而訪問速度也快,所以它能節省很多用戶的時間。 重申一下,這一點只適用于非授權的只讀訪問。如果建在防火墻之外的服務器上,那么它所提供的服務應該只是那些公開的只讀項目。如果是在防火墻之內的服務器上,可用于支撐大量參與人員或自動系統(用于持續集成或編譯的主機)只讀訪問的項目,這樣可以省去逐一配置 SSH 公鑰的麻煩。 但不管哪種情形,Git協議的配置設定都很簡單。基本上,只要以守護進程的形式運行該命令即可: git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ 這里的?--reuseaddr?選項表示在重啟服務前,不等之前的連接超時就立即重啟。而?--base-path?選項則允許克隆項目時不必給出完整路徑。最后面的路徑告訴 Git 守護進程允許開放給用戶訪問的倉庫目錄。假如有防火墻,則需要為該主機的 9418端口設置為允許通信。 以守護進程的形式運行該進程的方法有很多,但主要還得看用的是什么操作系統。在 Ubuntu主機上,可以用 Upstart腳本達成。編輯該文件: /etc/event.d/local-git-daemon 加入以下內容: ~~~ start on startup stop on shutdown exec /usr/bin/git daemon \ ??? --user=git--group=git \ ??? --reuseaddr \ ???--base-path=/opt/git/ \ ??? /opt/git/ respawn ~~~ 出于安全考慮,強烈建議用一個對倉庫只有讀取權限的用戶身份來運行該進程 —只需要簡單地新建一個名為?git-ro?的用戶(譯注:新建用戶默認對倉庫文件不具備寫權限,但這取決于倉庫目錄的權限設定。務必確認git-ro?對倉庫只能讀不能寫。),并用它的身份來啟動進程。這里為了簡化,后面我們還是用之前運行 Gitosis 的用戶 ‘git’。 這樣一來,當你重啟計算機時,Git進程也會自動啟動。要是進程意外退出或者被殺掉,也會自行重啟。在設置完成后,不重啟計算機就啟動該守護進程,可以運行: initctl start local-git-daemon 而在其他操作系統上,可以用?xinetd,或者?sysvinit?系統的腳本,或者其他類似的腳本 — 只要能讓那個命令變為守護進程并可監控。 接下來,我們必須告訴 Gitosis哪些倉庫允許通過 Git協議進行匿名只讀訪問。如果每個倉庫都設有各自的段落,可以分別指定是否允許 Git進程開放給用戶匿名讀取。比如允許通過 Git協議訪問 iphone_project,可以把下面兩行加到gitosis.conf?文件的末尾: ~~~ [repo iphone_project] daemon = yes ~~~ 在提交和推送完成后,運行中的 Git守護進程就會響應來自 9418端口對該項目的訪問請求。 如果不考慮 Gitosis,單單起了 Git守護進程的話,就必須到每一個允許匿名只讀訪問的倉庫目錄內,創建一個特殊名稱的空文件作為標志: ~~~ $ cd /path/to/project.git $ touch git-daemon-export-ok ~~~ 該文件的存在,表明允許 Git守護進程開放對該項目的匿名只讀訪問。 Gitosis 還能設定哪些項目允許放在GitWeb上顯示。先打開 GitWeb的配置文件?/etc/gitweb.conf,添加以下四行: ~~~ $projects_list ="/home/git/gitosis/projects.list"; $projectroot = "/home/git/repositories"; $export_ok = "git-daemon-export-ok"; @git_base_url_list = ('git://gitserver'); ~~~ 接下來,只要配置各個項目在 Gitosis中的?gitweb?參數,便能達成是否允許GitWeb用戶瀏覽該項目。比如,要讓iphone_project項目在 GitWeb 里出現,把repo?的設定改成下面的樣子: ~~~ [repo iphone_project] daemon = yes gitweb = yes ~~~ 在提交并推送過之后,GitWeb就會自動開始顯示 iphone_project項目的細節和歷史。 **4.10? Git托管服務** 如果不想經歷自己架設 Git服務器的麻煩,網絡上有幾個專業的倉庫托管服務可供選擇。這樣做有幾大優點:托管賬戶的建立通常比較省時,方便項目的啟動,而且不涉及服務器的維護和監控。即使內部創建并運行著自己的服務器,同時為開源項目提供一個公共托管站點還是有好處的 —讓開源社區更方便地找到該項目,并給予幫助。 目前,可供選擇的托管服務數量繁多,各有利弊。在 Git官方 wiki 上的 Githosting 頁面有一個最新的托管服務列表: http://git.or.cz/gitwiki/GitHosting 由于本書無法全部一一介紹,而本人(譯注:指本書作者 Scott Chacon。)剛好在其中一家公司工作,所以接下來我們將會介紹如何在 GitHub上建立新賬戶并啟動項目。至于其他托管服務大體也是這么一個過程,基本的想法都是差不多的。 GitHub 是目前為止最大的開源Git 托管服務,并且還是少數同時提供公共代碼和私有代碼托管服務的站點之一,所以你可以在上面同時保存開源和商業代碼。事實上,本書就是放在 GitHub上合作編著的。(譯注:本書的翻譯也是放在 GitHub上廣泛協作的。) **GitHub** GitHub 和大多數的代碼托管站點在處理項目命名空間的方式上略有不同。GitHub的設計更側重于用戶,而不是完全基于項目。也就是說,如果我在 GitHub上托管一個名為grit?的項目的話,它的地址不會是?github.com/grit,而是按在用戶底下github.com/shacon/grit?(譯注:本書作者 Scott Chacon 在 GitHub上的用戶名是shacon。)。不存在所謂某個項目的官方版本,所以假如第一作者放棄了某個項目,它可以無縫轉移到其它用戶的名下。 GitHub 同時也是一個向使用私有倉庫的用戶收取費用的商業公司,但任何人都可以方便快捷地申請到一個免費賬戶,并在上面托管數量不限的開源項目。接下來我們快速介紹一下 GitHub的基本使用。 **建立新賬戶** 首先注冊一個免費賬戶。訪問 Pricing and Signup頁面?http://github.com/plans?并點擊 Free acount里的 Sign Up 按鈕(見圖 4-2),進入注冊頁面。 圖 4-2.GitHub服務簡介頁面 選擇一個系統中尚未使用的用戶名,提供一個與之相關聯的電郵地址,并輸入密碼(見圖 4-3): 圖 4-3.GitHub用戶注冊表單 如果方便,現在就可以提供你的 SSH公鑰。我們在前文的”小型安裝”一節介紹過生成新公鑰的方法。把新生成的公鑰復制粘貼到 SSH Public Key文本框中即可。要是對生成公鑰的步驟不太清楚,也可以點擊 “explain ssh keys”鏈接,會顯示各個主流操作系統上完成該步驟的介紹。點擊 “I agree,sign me up”按鈕完成用戶注冊,并轉到該用戶的 dashboard頁面(見圖 4-4): 圖 4-4.GitHub的用戶面板 接下來就可以建立新倉庫了。 **建立新倉庫** 點擊用戶面板上倉庫旁邊的 “create a new one”鏈接,顯示 Create a New Repository的表單(見圖4-5): 圖 4-5. 在 GitHub 上建立新倉庫 當然,項目名稱是必不可少的,此外也可以適當描述一下項目的情況或者給出官方站點的地址。然后點擊 “Create Repository”按鈕,新倉庫就建立起來了(見圖4-6): 圖 4-6.GitHub上各個項目的概要信息 由于尚未提交代碼,點擊項目主頁后 GitHub會顯示一個簡要的指南,告訴你如何新建一個項目并推送上來,如何從現有項目推送,以及如何從一個公共的 Subversion倉庫導入項目(見圖 4-7): 圖 4-7. 新倉庫指南 該指南和本書前文介紹的類似,對于新的項目,需要先在本地初始化為 Git項目,添加要管理的文件并作首次提交: ~~~ $ git init $ git add . $ git commit -m 'initial commit' ~~~ 然后在這個本地倉庫內把 GitHub添加為遠程倉庫,并推送 master分支上來: ~~~ $ git remote add origingit@github.com:testinguser/iphone_project.git $ git push origin master ~~~ 現在該項目就托管在 GitHub上了。你可以把它的 URL分享給每位對此項目感興趣的人。本例的 URL是http://github.com/testinguser/iphone_project。而在項目頁面的摘要部分,你會發現有兩個 Git URL地址(見圖 4-8): 圖 4-8. 項目摘要中的公共URL 和私有URL PublicClone URL是一個公開的,只讀的 Git URL,任何人都可以通過它克隆該項目。可以隨意散播這個 URL,比如發布到個人網站之類的地方等等。 Your CloneURL是一個基于SSH 協議的可讀可寫URL,只有使用與上傳的SSH公鑰對應的密鑰來連接時,才能通過它進行讀寫操作。其他用戶訪問該項目頁面時只能看到之前那個公共的 URL,看不到這個私有的 URL。 **從 Subversion導入項目** 如果想把某個公共 Subversion項目導入 Git,GitHub可以幫忙。在指南的最后有一個指向導入 Subversion頁面的鏈接。點擊它會看到一個表單,包含有關導入流程的信息以及一個用來粘貼公共 Subversion項目連接的文本框(見圖 4-9): 圖 4-9.Subversion導入界面 如果項目很大,采用非標準結構,或者是私有的,那就無法借助該工具實現導入。到第 7章,我們會介紹如何手工導入復雜工程的具體方法。 **添加協作開發者** 現在把團隊里的其他人也加進來。如果 John,Josie和 Jessica 都在 GitHub 注冊了賬戶,要賦予他們對該倉庫的推送權限,可以把他們加為項目協作者。這樣他們就可以通過各自的公鑰訪問我的這個倉庫了。 點擊項目頁面上方的 “edit”按鈕或者頂部的 Admin標簽,進入該項目的管理頁面(見圖 4-10): 圖 4-10.GitHub的項目管理頁面 為了給另一個用戶添加項目的寫權限,點擊 “Add another collaborator”鏈接,出現一個用于輸入用戶名的表單。在輸入的同時,它會自動跳出一個符合條件的候選名單。找到正確用戶名之后,點 Add按鈕,把該用戶設為項目協作者(見圖 4-11): 圖 4-11. 為項目添加協作者 添加完協作者之后,就可以在 Repository Collaborators區域看到他們的名單(見圖 4-12): 圖 4-12. 項目協作者名單 如果要取消某人的訪問權,點擊 “revoke”即可取消他的推送權限。對于將來的項目,你可以從現有項目復制協作者名單,或者直接借用協作者群組。 **項目頁面** 在推送或從 Subversion導入項目之后,你會看到一個類似圖 4-13的項目主頁: 圖 4-13.GitHub上的項目主頁 別人訪問你的項目時看到的就是這個頁面。它有若干導航標簽,Commits標簽用于顯示提交歷史,最新的提交位于最上方,這和?git log?命令的輸出類似。Network標簽展示所有派生了該項目并做出貢獻的用戶的關系圖譜。Downloads標簽允許你上傳項目的二進制文件,提供下載該項目各個版本的 tar/zip包。Wiki 標簽提供了一個用于撰寫文檔或其他項目相關信息的 wiki站點。Graphs 標簽包含了一些可視化的項目信息與數據。默認打開的 Source標簽頁面,則列出了該項目的目錄結構和概要信息,并在下方自動展示 README文件的內容(如果該文件存在的話),此外還會顯示最近一次提交的相關信息。 **派生項目** 如果要為一個自己沒有推送權限的項目貢獻代碼,GitHub鼓勵使用派生(fork)。到那個感興趣的項目主頁上,點擊頁面上方的 “fork”按鈕,GitHub 就會為你復制一份該項目的副本到你的倉庫中,這樣你就可以向自己的這個副本推送數據了。 采取這種辦法的好處是,項目擁有者不必忙于應付賦予他人推送權限的工作。隨便誰都可以通過派生得到一個項目副本并在其中展開工作,事后只需要項目維護者將這些副本倉庫加為遠程倉庫,然后提取更新合并即可。 要派生一個項目,到原始項目的頁面(本例中是 mojombo/chronic)點擊“fork”按鈕(見圖4-14): 圖 4-14. 點擊 “fork” 按鈕獲得任意項目的可寫副本 幾秒鐘之后,你將進入新建的項目頁面,會顯示該項目派生自哪一個項目(見圖 4-15): 圖 4-15. 派生后得到的項目副本 **GitHub小結** 關于 GitHub就先介紹這么多,能夠快速達成這些事情非常重要(譯注:門檻的降低和完成基本任務的簡單高效,對于推動開源項目的協作發展有著舉足輕重的意義。)。短短幾分鐘內,你就能創建一個新賬戶,添加一個項目并開始推送。如果項目是開源的,整個龐大的開發者社區都可以立即訪問它,提供各式各樣的幫助和貢獻。最起碼,這也是一種 Git 新手立即體驗嘗試 Git的捷徑。 **4.11?小結** 我們討論并介紹了一些建立遠程 Git倉庫的方法,接下來你可以通過這些倉庫同他人分享或合作。 運行自己的服務器意味著更多的控制權以及在防火墻內部操作的可能性,當然這樣的服務器通常需要投入一定的時間精力來架設維護。如果直接托管,雖然能免去這部分工作,但有時出于安全或版權的考慮,有些公司禁止將商業代碼托管到第三方服務商。 所以究竟采取哪種方案,并不是個難以取舍的問題,或者其一,或者相互配合,哪種合適就用哪種。 ?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看