1. 程式人生 > >git伺服器的建立——Git折騰小記

git伺服器的建立——Git折騰小記

這兩天剛完成了一個小專案,整理資料發現現在寫程式碼跟文件又沒有版本控制的意識,剛好前兩天電腦出問題,差點所有程式碼跟文件全丟掉,所以這兩天又在自己的桌上型電腦上架起了git,做所謂的程式碼伺服器,之前折騰過一次,因為時間原因沒有總結下來,結果這次弄的時候,又得滿世界找資料,所以這次準備總結一下,也做了一個參考資料彙總,以備以後再折騰時用。

git簡介

git是幹嘛的呢?記得聽哪位大牛說:沒有版本控制意識的程式設計師,都不是好程式設計師!如果你認同這句話,那麼Git就是用來幫助你成為好程式的。Git應該是當下最受人推崇的版本管理系統了(僅僅是感覺,沒有依據),之所以受推崇,除了因為它是Linux核心開發者
Linus Torvalds
最初開發的,其確實有很多其他版本控制系統所沒有的特點,否則其也很難管理像Linux核心專案這樣的超大專案。那麼它有什麼特點了? 首先,與以前廣為流行的SVN不同,git是分散式的,其沒有伺服器端與客戶端之分(雖然在專案管理過程中,一般會人為地指定某一臺非開發用的機器作為“伺服器”,但就git自身功能來說,完全可以沒有這個臺“伺服器”,至於實際中為什麼會有,後面將會講到)。 然後,git的分支(branch)與合併(merge)功能非常強大與智慧。據維基百科所說:git最為出色的就是它的合併跟蹤(merge tracing)能力。作為SVN與git的使用者,親身體驗告訴我,git提供的分支間程式碼合併功能的確非常強大,很少出現需要手動合併程式碼的情況,即使出現,其提供的衝突提示與解決方案也非常方便跟簡單。 最後,它是開源的,它正在變得越來越強大跟方便,同時,好用配套工具也越來越多,使得git的使用與管理更簡單方便。 當然,它一樣是有缺點的,比如其學習曲線相對比較抖,但是隻要你想學,網上系統的資料越來越多了。本人現在也基本算入門,本文也僅僅是一個備忘錄,權當一個可能不大好的入門材料。本文的最後列出了一些可以更系統學習的資料。同時,git自身沒有許可權控制,需要額外的許可權控制工具,但是現在也有不錯的工具可以彌補了,本文也有舉例介紹我自己當前在用的。 好,閒話說得夠多了,下面開始介紹git的安裝,包括git本身的安裝,以及“伺服器”上一些配套的管理工具的安裝,包括用於許可權管理的gitolite,使用者web瀏覽檔案的gitweb。

git安裝

git安裝

git自身的安裝其實是很簡單的,不論是windows下還是Linux下(以我自己用的ubuntu為例),尤其是如果你僅作為“客戶端”(即別人不會直接從你的電腦上clone程式碼,不會向你的電腦提交或者獲取程式碼),你只需要跟安裝一個普通軟體一樣傻瓜式安裝即可:
windows下直接下載可執行安裝程式 msysgit (選擇git for windows 或者 msysgit都可以),然後雙擊執行,根據提示安裝即可,非常簡單! Linux的安裝也很簡單,尤其如果你用的Ubuntu或者Debian等有本地包管理系統的linux系統,一條命令即可解決問題(Ubuntu為例):
  1. sudo apt-get install git-core  

非常簡單吧!(當然,除了跨平臺可能是git的優勢跟特點外,安裝簡便肯定不是它的特點,因為很多其他軟體也一樣……) 但是,如果你是在為你的小組或者自己配置專門的程式碼伺服器,供所有成員備份程式碼、共享程式碼、交流程式碼、合作開發,你可能就需要一些額外的工作了。仍然以Ubuntu系統為例,參考這篇文章,記錄一下整個配置的過程: 首先,git的資料交換跟互動是基於ssh的,所以為了使所有成員都能從該機器上獲取和提交程式碼,需要給系統配置ssh服務,當然,如果你已經配置了ssh服務,那麼這一步就可以省了,所以你可以先通過下面的命令檢視下自己是否已經配置了ssh服務:
  1. ps -ef|grep "sshd"  

如果你能看到一些sshd相關的程序資訊,則說明你已經有這個服務了,否則(或者你想更新的話),使用下面的命令安裝openssh
  1. sudo apt-get install openssh-server openssh-client  

然後,安裝git“伺服器”
  1. sudo apt-get install git-core  

再然後,為自己配置身份資訊,這樣多個人提交程式碼的時候,就可以方便的檢視是誰提交的,該如何聯絡ta了(如果該機器只做伺服器,不做開發,本步驟應該可以省略)
  1. git config --global user.name "yourname"  
  2. git config --global user.email "[email protected]"  

以上步驟是每個git使用者都需要的,接下來,作為“伺服器”,為了更好的管理,我們需要進行一些必要的配置!包括環境的配置、管理工具的安裝與配置等。 首先,我們最好為其配置一個專門的git使用者並設定密碼,專門對程式碼進行管理
  1. sudo useradd -m git  
  2. sudo passwd git(change to yours)  
說明:上述命令生成一個使用者名稱與密碼均為git的賬戶,也可以自己建立別的使用者名稱跟密碼,只要進行相關操作(比如clone)時指定使用者名稱即可(本文章一律以git為例),-m 選項是讓其在home目錄下生成使用者的主資料夾,我們的程式碼倉庫會佈置在這個主資料夾下。 然後,在新建的git使用者主目錄下建立一個資料夾作為git的倉庫,併為這個倉庫配備最基本的安防——許可權控制
  1. sudo mkdir /home/git/repositories # 最好使用repositories作為資料夾名稱,這樣可以簡化後面的操作  
  2. sudo chown git:git /home/git/repositories  
  3. sudo chmod 755 /home/git/repositories  

至此,一個簡單(非常簡單)的git伺服器已經搭建好了,可以自己建立一個簡單的工程測試一下。
為了方便後面的操作,我們先切換到git使用者下
  1. su git  
在respositories下新建一個目錄(倉庫),並切換到這個目錄
  1. mkdir helloworld  
  2. cd helloworld  
在此處初始化一個空的倉庫(只能接受push/pull程式碼,不能本地commit)
  1. git --bare init  
好了,一個空的倉庫建立好了,用另外一臺安裝了git的機器(比如你的開發機)測試一下,此處假設你上面所用的伺服器IP為192.168.0.123
  1. git clone [email protected]:/home/git/repositories/helloworld  
然後在開發機上進行一些基本操作測試:為這個專案add一些檔案,然後commit,然後push,如果除了要幾次輸入git使用者的密碼外,其他一切正常的話,那說明上面的安裝與配置就已經成功了
在上面的測試過程中,是不是發現那個clone的路徑好長,很容易錯?幾個步驟都需要輸入git使用者的密碼(clone、push),是不是很煩,而且照這個節奏,每增加一個開發成員,就得告訴他git使用者的密碼,是不是既繁瑣又不安全?所以,如果能clone的時候只要指定專案名稱,clone/push/pull自動完成身份認證,並且最好能對不同的倉庫給予不同使用者不同的許可權,那就好了!接下來介紹的工具與配置就可以搞定這一切,讓git倉庫的管理變得更簡單,操作更方便! 首先,針對身份認證的問題,我們前面已經提到git的資料交換與操作都是基於ssh的,所以,我們的身份認證自然可以通過配置ssh來解決。ssh是通過金鑰進行認證管理的,金鑰包括一個公鑰(交給伺服器)和一個私鑰(自己保留),每個公鑰對應一個私鑰,每個私鑰也只對應一個公鑰。。。。此處省略若干字。。。。,所以一個簡單的解決自動身份認證的方式就是:每個需要訪問程式碼倉庫的人員,在自己的機器上通過ssh-keygen生成自己的公鑰與私鑰,將公鑰提交給伺服器,伺服器管理員將改使用者的公鑰新增到伺服器git使用者的.ssh/authorized_keys檔案中,可能用到的命令如下(Ubuntu終端/Windows下使用Git Bash):
  1. # 某開發機上  
  2. ssh-keygen #接下來一路回車就好了,在預設目錄下生成預設金鑰檔案  
  3. cp ~/.ssh/id_rsa.pub /path/to/one/visiabl/fold/ #將隱藏資料夾下的公鑰檔案拷貝到一個可以資料夾下(如果接下來用scp提交,此步驟可省略)  
  4. # 將上面的公鑰檔案以某種方式提交給伺服器  
  5. # 管理員在伺服器下  
  6. # 將開發機提交上來的公鑰檔案,新增到/home/git/.ssh/authorized_keys檔案中(每行一個)  
這種方式可以在開發人員較少,管理的倉庫較少的時候使用,因為簡單,但是其許可權控制比較單一(均可以read/update程式碼),而且如果人一多,要管理authorized_keys檔案也是個頭疼的事情,所以不是很推薦這種方式,建議採用後面介紹的工具。 然後,對於預設路徑的問題,這個我真的只知道通過下面的管理工具來配置了。所以,接下來介紹一個git倉庫的開源管理工具gitolite

gitolite安裝

gitolite官方介紹是這樣的:Hosting git repositories -- Gitolite allows you to setup git hosting on a central server, with very fine-grained access control and many (many!) more powerful features.如其所述,它的主要功能就是對git倉庫進行許可權控制,並提供其他很多給力的方便管理的特性。其實我本來是要介紹gitosis的,但是自己在弄的時候,gitosis的配置出了一個非常詭異的問題,不管我怎麼配置,甚至重新安裝從零開始配置,總是再我更新它的配置檔案後,之前的配置就不起作用了,折騰了我一天,最終發現了它的升級版——gitolite,所以決定採用它了。它們的本質都是上面介紹的ssh驗證,只是它們提供更方便的管理方式,然後自動生成authorized_keys檔案。這兩個工具最有意思的一點就是,它們自身就是一個特殊的git版本庫(gitolite-admin),他們的管理與配置都可以通過git的方式,分散式的進行修改,然後通過push的方式提交到伺服器,伺服器會通過所謂的鉤子指令碼自動更新許可權控制檔案。 下面介紹它的安裝,它的官方主頁上有詳細的安裝介紹,我這權當翻譯跟經驗分享。 首先,因為我的git倉庫是在git使用者下,所以,切換或者登陸到git使用者下
  1. su git  
上面說過,gitolite本質就是根據你的配置,自動生成authorized_keys檔案,所以它要求你的authorized_keys檔案必須是空的,或者不存在,所以我們乾脆刪了它(請注意一定要切換到git使用者,否則,誤刪除了其他使用者下的authorized_keys檔案導致伺服器的其他功能受影響,那就悲劇了,這應該也算是為什麼要專門弄一個git使用者來管理的原因吧)
  1. rm ~/.ssh/authorized_keys  
然後,gitolite在初始化時需要通過某一使用者的公鑰檔案指定一個超級管理員,gitolite安裝成功後,只有這個超級管理員可以更新gitolite以更新各種許可權控制(包括對其自身的更新許可權控制),所以在初始化時需要指定該超級管理員賬戶的公鑰檔案(最好直接將其拷貝到git使用者的主資料夾下)(下面的示例程式使用同一伺服器上的另一常用管理員使用者admin)
  1. su admin  
  2. ssh-keygen  
  3. sudo cp ~/.ssh/id_rsa.pub /home/git/id_rsa.pub  
  4. su git  
好~準備工作已經完成了,開始安裝gitolite
  1. cd ~ # 回到git主資料夾下  
  2. git clone git://github.com/sitaramc/gitolite # 獲取gitolite的原始碼  
  3. mkdir -p $HOME/bin  #為gitolite的二進位制檔案生成建立目錄  
  4. gitolite/install -to $HOME/bin  # 編譯生成安裝檔案  
  5. $HOME/bin/gitolite setup -pk id_rsa.pub # 安裝並初始化,指定id_rsa.pub公鑰檔案對應的使用者為超級管理員  
Bingo! gitolite安裝完成!不過,你要用它來進行管理,那還需要一定的操作。上面提到,gitolite安裝後本身是一個特殊的git版本庫——gitolite-admin,分散式的進行修改,然後通過push的方式提交,其會通過鉤子指令碼執行許可權更新。看一下上述步驟的最後一步你會發現,gitolite自動生成了兩個版本庫:gitolite-admin.git和testing.git,其中的gitol-admin.git就是那個特殊的神奇版本庫。所以,接下來我們要做的,就是回到你剛剛指定的超級管理員賬戶的電腦跟賬戶下,clone出gitolite-admin這個特殊的git版本庫(當前情況下,只有該超級管理員賬戶可以clone並更新gitolite-admin這個版本庫),然後根據自己的需要對其進行配置(如新增更多的管理員賬戶、新增新的版本庫併為不同的使用者指定許可權)
  1. su admin # 回到指定的超級管理員賬戶  
  2. git clone [email protected]:gitolite-admin.git # clonegitolite-admin這個特殊的版本庫  
如果上面的步驟都成功了的話,應該可以檢視到有一個gitolite-admin的資料夾,資料夾下有兩個目錄conf、keydir 如果你回到git使用者,檢視repositories目錄(如果之前建立倉庫時,建立的資料夾不是repositories,gitolite會自動建立這個資料夾,並將該資料夾作為預設訪問時的預設路徑),目錄下就會多了gitolite-admin.git與testing.git兩個版本庫。
有沒有發現,這次clone的時候,後面的路徑變短了?密碼也不用輸了?腰不酸腿不痛了?對,你沒猜錯,這一切gitolite已經自動幫你搞定了:預設路徑是/home/git/repositories,許可權控制是隻有當前的超級管理員使用者可以訪問gitolite-admin和testing兩個版本庫,你之前測試建立的版本庫也已經無法訪問,如果你嘗試再次clone之前建立的測試版本庫,應該就會提示如下錯誤資訊:
  1. # 假設你之前建立了helloworld版本庫,現在使用git clone [email protected]:helloworld試圖clone  
  2. FATAL: R any helloworld id_rsa DENIED by fallthru  
  3. (or you mis-spelled the reponame)  
  4. fatal: The remote end hung up unexppectedly   
要繼續訪問之前建立的專案,需要將這個專案新增到gitolite的許可權控制內,下面演示一下為當前的超級管理員使用者指定之前建立的helloworld測試版本庫的讀寫許可權(可讀可寫),以此演示gitolite指定許可權的一般流程: 1、將需要指定許可權的使用者的ssh公鑰檔案,存放在gitolite-admin版本庫的keydir目錄下(如果提交的都是id_rsa.pub,可以將其重新命名為該使用者的id或者名稱,同時也推薦這樣重新命名,以明示哪個公鑰檔案是哪個使用者的),因為我們初始化時,gitolite已經將該超級管理員的公鑰檔案自動拷進去了,所以省略此步驟 2、編輯conf目錄下的gitolite.conf檔案,新增helloworld版本庫管理組,為超級管理員指定讀寫許可權(RW+,具體的許可權定義,參考gitolite官方文件)
  1. repo helloworld  
  2.     RW+  =   id_rsa  

3、commit到本地
  1. git commit -am 'add the helloworld repo and add RW+ to id_rsa'  

4、push到git倉庫
  1. git push  

如果push成功,當前超級管理員使用者應該就可以成功clone helloworld版本庫,並進行新增、刪除、修改與push等操作了。 以上便是一個經典的管理過程,至於具體的許可權控制、配置檔案的格式、更多高階功能等,如果都介紹的話,這文章也太長了,所以讀者還是參考官方文件(簡單介紹詳細版本)吧,順便學學英語。 一個基本的git伺服器算基本完成了,當然如果要管理好,裡面涉及到管理細節(不論是技術細節,還是管理策略)還有很多很多,我自己現在也只知道些皮毛,同時因為沒有大專案的程式碼管理經驗,都是我自己的小打小鬧,所以就完全不敢出來獻醜了,更多技術細節,大家可以檢視官方文件,有機會我也許會再做點筆記分享,至於管理策略,推薦這個:A successful Git branching model ,這個也有”中文版“

git基本操作

其實這個已經有很多不錯的資料了,所以也就懶得自己寫了,羅列一點自己看過的資料好了: 我第一次接觸git時,大哥推薦給我的資料:Git魔法,有pdf版本的,讀者自己找找吧,如果沒找到,也可以找我要,僅限學習~ git官網貌似一直就沒上去過,看看這個中文翻譯版本一個不錯的git簡易指南



1.在伺服器端建立專用帳號,所有使用者通過此帳號訪問git庫,一般方便易記,選擇git作為專用帳號名稱。
$sudo adduser --system --shell /bin/bash --group git
新增git使用者到ssh使用者組中
$sudo adduser git ssh
為git使用者設定口令,當整個git服務配置完成,最好取消git口令,只允許公匙認證。
$sudo passwd git
 2.到管理員主機將管理員公匙新增到伺服器主機的.ssh/authorized_keys檔案中,建立新的公匙認證,如:
$ssh-copy-id -i .ssh/<filename>.pub  git@server

3.伺服器切換到git使用者
$su git
安裝gitolite
$sudo apt-get install gitolite
執行gitolite安裝
$gl-setup  /<filename>.pub 以管理員公匙安裝gitolite
安裝過程會詢問是否修改配置檔案,一般會自動開啟vi編輯.gitolite.rc檔案。有些配置需要修改
$REPO_BASE="repositories"
用於設定Git伺服器的根目錄,預設是git使用者主目錄下的repositories目錄,可以使用絕對路徑。所有git庫都
部署在該路徑下。
$REPO_UMASK=0007;#gets you 'rwxrwx--'
版本庫建立使用的掩碼。即新建立的版本庫許可權為‘rwxrwx’
$GL_BIG_CONFIG=0
如果授權檔案非常複雜,更改此項配置為1,以免產生龐大的授權編譯檔案。
$GL_DILDREPOS=1
支援萬用字元版本庫授權。
退出儲存。
如果安裝時沒有配置,後續可以開啟git使用者跟目錄下.gitolate.rc檔案配置。

4.管理gitolite
當gitolite安裝完成後,在伺服器端建立了一個用於管理gitolite的庫gitolite-admin.git

切換到管理員主機  $git clone git@server:gitolite-admin.git
$cd gitolite-admin
$ls -F
conf/   keydir/
$ls /conf
gitolite.conf
$ls keydir/
<filename>.pub
我們可以看出gitolite-admin目錄下有兩個目錄conf/和keydir/.
keydir/<filename>.pub檔案
目錄keydir下初始時只有一個使用者公匙,及管理員使用者的公匙。
conf/gitolite.conf檔案
該檔案為授權檔案,初始內容為
#gitolite conf
# please see conf/example.conf for details on syntax and features

repo gitolite-admin
    RW+                 = admin

repo testing
    RW+                 = @all

預設授權檔案中只設置了兩個版本庫的授權:

    gitolite-admin

    即本版本庫(gitolite管理版本庫)只有 admin 使用者有讀寫和強制更新的許可權。

    testing

    預設設定的測試版本庫,設定為任何人都可以讀寫以及強制更新。

5.增加新使用者
只用將信使用者的公匙新增到gitolite-admin版本庫的Keydir目錄下,即完成新使用者的新增。如:
$ cp /path/to/dev1.pub keydir/
$ cp /path/to/dev2.pub keydir/
$ cp /path/to/jiangxin.pub keydir/
執行 git add 命令,將公鑰新增入版本庫。

$ git add keydir
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   keydir/dev1.pub
#       new file:   keydir/dev2.pub
#       new file:   keydir/jiangxin.pub
#
$ git commit -m "add user: jiangxin, dev1, dev2"
[master bd81884] add user: jiangxin, dev1, dev2
 3 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 keydir/dev1.pub
 create mode 100644 keydir/dev2.pub
 create mode 100644 keydir/jiangxin.pub

執行 git push,同步到伺服器,才真正完成新使用者的新增。

$ git push
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 1.38 KiB, done.
Total 6 (delta 0), reused 0 (delta 0)
remote: Already on 'master'
remote:
remote:                 ***** WARNING *****
remote:         the following users (pubkey files in parens) do not appear in the config file:
remote: dev1(dev1.pub),dev2(dev2.pub),jiangxin(jiangxin.pub)

6.更改授權
新使用者新增完畢,可能需要重新進行授權。更改授權的方法也非常簡單,即修改 conf/gitolite.conf 配置檔案,提交併 push。

    管理員進入 gitolite-admin 本地克隆版本庫中,編輯 conf/gitolite.conf 。

    $ vi conf/gitolite.conf

    授權指令比較複雜,我們先通過建立新使用者組嘗試一下更改授權檔案。

    考慮到之前我們增加了三個使用者公鑰之後,伺服器端發出了使用者尚未在授權檔案中出現的警告。我們就在這個示例中解決這個問題。

        例如我們在其中加入使用者組 @team1,將新新增的使用者 jiangxin, dev1, dev2 都歸屬到這個組中。

        我們只需要在 conf/gitolite.conf 檔案的檔案頭加入如下指令。使用者之間用空格分隔。

        @team1 = dev1 dev2 jiangxin
編輯結束,提交改動。

$ git add conf/gitolite.conf
$ git commit -q -m "new team @team1 auth for repo testing."

執行 git push ,同步到伺服器,才真正完成授權檔案的編輯


7.建立倉庫示例
在conf/gitolite.conf中新增類似下面的內容進去
repo notes
  PW = <filename>
儲存,提交,並推送到伺服器
git add -u
git commit -m 'add new repo notes '
git push
推送的時候應該看到類似這樣的資訊

Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 395 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Initialized empty Git repository in /home/git/repositories/notes.git/
To git@desktop:gitolite-admin
   6de90b8..52737aa  master -> master

注意remote開頭的一行,它已經幫你建立了這個倉庫

萬用字元建立倉庫示例
萬用字元倉庫事先不能確定名字,所以不會幫你建立,在你clone的時候才會建立

編輯conf/gitolite.conf檔案在裡面加入類似下面的內容

repo e2source/.+$
  C      =   <filename>
  RW+C   =   <filename>

注意C = username的一行必不可少,這裡的C是指建立倉庫的意思,下一行的RW+C中的C是指建立引用(branch,tag)的意思

儲存後提交併推送到服務上去

git add -u
git commit -m 'add wildcard repo'
git push

注意看push時輸出的資訊,應該沒有建立倉庫的資訊

這時filename克隆倉庫的時候會自動建立

輸出應該類似這樣

Cloning into 'enigam2-plugins'...
Initialized empty Git repository in /home/git/repositories/e2source/enigam2-plugins.git/
warning: You appear to have cloned an empty repository.

如果你的輸出報這樣的錯

FATAL: R any e2source/enigam2-plugins jenny DENIED by fallthru
(or you mis-spelled the reponame)
fatal: The remote end hung up unexpectedly

一般是沒有C = username這一行,注意是隻有C的一行