教你搭建你自己的Git服務器

      網友投稿 763 2025-04-04

      http://lib.csdn.net/article/git/50086

      直到現在,我們主要討論的還是以一個使用者的身份與 Git 進行交互。這篇文章中我將討論 Git 的管理,并且設計一個靈活的 Git 框架。你可能會覺得這聽起來是 “高階 Git 技術” 或者 “只有狂熱粉才能閱讀”的一句委婉的說法,但是事實是這里面的每個任務都不需要很深的知識或者其他特殊的訓練,就能基本理解 Git 的工作原理,有可能需要一丁點關于 Linux 的知識。

      共享Git服務器

      創建你自己的共享 Git 服務器意外地簡單,而且在很多情況下,遇到的這點麻煩是完全值得的。不僅僅是因為它保證你有權限查看自己的代碼,它還可以通過擴展為 Git 的使用敞開了一扇大門,例如個人 Git 鉤子、無限制的數據存儲、和持續集成與分發(CI & CD)。

      如果你知道如何使用 Git 和 SSH,那么你已經知道怎么創建一個 Git 服務器了。Git 的設計方式,就是讓你在創建或者 clone 一個倉庫的時候,就完成了一半服務器的搭建。然后允許用 SSH 訪問倉庫,而且任何有權限訪問的人都可以使用你的倉庫作為 clone 的新倉庫的基礎。

      但是,這是一個小的點對點環境(ad-hoc)。按照一些方案你可以創建一些帶有同樣的功能的設計優良的 Git 服務器,同時有更好的拓展性。

      教你搭建你自己的Git服務器

      首要之事:確認你的用戶們,現在的用戶以及之后的用戶都要考慮。如果你是唯一的用戶那么沒有任何改動的必要。但是如果你試圖邀請其他的代碼貢獻者使用,那么你應該允許一個專門的分享系統用戶給你的開發者們。

      假定你有一個可用的服務器(如果沒有,這不成問題,Git 會幫忙解決,CentOS 的 樹莓派 3 是個不錯的開始),然后第一步就是只允許使用 SSH 密鑰認證的 SSH 登錄。這比使用密碼登錄安全得多,因為這可以免于暴力破解,也可以通過直接刪除用戶密鑰而禁用用戶。

      一旦你啟用了 SSH 密鑰認證,創建 gituser 用戶。這是給你的所有授權的用戶們的公共用戶:

      $?su?-c?'adduser?gituser'

      然后切換到剛創建的 gituser 用戶,創建一個 ~/.ssh 的框架,并設置好合適的權限。這很重要,如果權限設置得太開放會使自己所保護的 SSH 沒有意義。

      $?su?-?gituser $?mkdir?.ssh?&&?chmod?700?.ssh $?touch?.ssh/authorized_keys $?chmod?600?.ssh/authorized_keys

      authorized_keys 文件里包含所有你的開發者們的 SSH 公鑰,你開放權限允許他們可以在你的 Git 項目上工作。他們必須創建他們自己的 SSH 密鑰對然后把他們的公鑰給你。復制公鑰到 gituser 用戶下的 authorized_keys 文件中。例如,為一個叫 Bob 的開發者,執行以下命令:

      $?cat?~/path/to/id_rsa.bob.pub?>>?/home/gituser/.ssh/authorized_keys

      只要開發者 Bob 有私鑰并且把相對應的公鑰給你,Bob 就可以用 gituser 用戶訪問服務器。

      但是,你并不是想讓你的開發者們能使用服務器,即使只是以 gituser 的身份訪問。你只是想給他們訪問 Git 倉庫的權限。因為這個特殊的原因,Git 提供了一個限制的 shell,準確的說是 git-shell。以 root 身份執行以下命令,把 git-shell 添加到你的系統中,然后設置成 gituser 用戶的默認 shell。

      #?grep?git-shell?/etc/shells?||?su?-c?"echo?`which?git-shell`?>>?/etc/shells" #?su?-c?'usermod?-s?git-shell?gituser'

      現在 gituser 用戶只能使用 SSH 來 push 或者 pull Git 倉庫,并且無法使用任何一個可以登錄的 shell。你應該把你自己添加到和 gituser 一樣的組中,在我們的樣例服務器中這個組的名字也是 gituser。

      舉個例子:

      #?usermod?-a?-G?gituser?seth

      僅剩下的一步就是創建一個 Git 倉庫。因為沒有人能在服務器上直接與 Git 交互(也就是說,你之后不能 SSH 到服務器然后直接操作這個倉庫),所以創建一個空的倉庫 。如果你想使用這個放在服務器上的倉庫來完成工作,你可以從它的所在處 clone 下來,然后在你的 home 目錄下進行工作。

      嚴格地講,你不是必須創建這個空的倉庫;它和一個正常的倉庫一樣工作。但是,一個空的倉庫沒有工作分支(working tree) (也就是說,使用 checkout 并沒有任何分支顯示)。這很重要,因為不允許遠程使用者們 push 到一個有效的分支上(如果你正在 dev 分支工作然后突然有人把一些變更 push 到你的工作分支,你會有怎么樣的感受?)。因為一個空的倉庫可以沒有有效的分支,所以這不會成為一個問題。

      你可以把這個倉庫放到任何你想放的地方,只要你想要放開權限給用戶和用戶組,讓他們可以在倉庫下工作。千萬不要保存目錄到比如說一個用戶的 home 目錄下,因為那里有嚴格的權限限制。保存到一個常規的共享地址,例如 /opt 或者 /usr/local/share。

      以 root 身份創建一個空的倉庫:

      #?git?init?--bare?/opt/jupiter.git #?chown?-R?gituser:gituser?/opt/jupiter.git #?chmod?-R?770?/opt/jupiter.git

      現在任何一個用戶,只要他被認證為 gituser 或者在 gituser 組中,就可以從 jupiter.git 庫中讀取或者寫入。在本地機器嘗試以下操作:

      $?git?clone?gituser@example.com:/opt/jupiter.git?jupiter.clone Cloning?into?'jupiter.clone'... Warning:?you?appear?to?have?cloned?an?empty?repository.

      謹記:開發者們一定要把他們的 SSH 公鑰加入到 gituser 用戶下的 authorized_keys 文件里,或者說,如果他們有服務器上的用戶(如果你給了他們用戶),那么他們的用戶必須屬于 gituser 用戶組。

      Git鉤子

      運行你自己的 Git 服務器最贊的一件事之一就是可以使用 Git 鉤子。Git 托管服務有時提供一個鉤子類的接口,但是他們并不會給你真正的 Git 鉤子來讓你訪問文件系統。Git 鉤子是一個腳本,它將在一個 Git 過程的某些點運行;鉤子可以運行在當一個倉庫即將接收一個 commit 時、或者接受一個 commit 之后,或者即將接收一次 push 時,或者一次 push 之后等等。

      這是一個簡單的系統:任何放在 .git/hooks 目錄下的腳本、使用標準的命名體系,就可按設計好的時間運行。一個腳本是否應該被運行取決于它的名字; pre-push 腳本在 push 之前運行,post-receive 腳本在接受 commit 之后運行等等。這或多或少的可以從名字上看出來。

      腳本可以用任何語言寫;如果在你的系統上有可以執行的腳本語言,例如輸出 ‘hello world’ ,那么你就可以這個語言來寫 Git 鉤子腳本。Git 默認帶了一些例子,但是并不有啟用。

      想要動手試一個?這很簡單。如果你沒有現成的 Git 倉庫,首先創建一個 Git 倉庫:

      $?mkdir?jupiter $?cd?jupiter $?git?init?.

      然后寫一個 “hello world” 的 Git 鉤子。因為我為了支持老舊系統而使用 tsch,所以我仍然用它作為我的腳本語言,你可以自由的使用自己喜歡的語言(Bash,Python,Ruby,Perl,Rust,Swift,Go):

      $?echo?"#/!/bin/tcsh"?>?.git/hooks/post-commit $?echo?"echo?'POST-COMMIT?SCRIPT?TRIGGERED'"?>>?~/jupiter/.git/hooks/post-commit $?chmod?+x?~/jupiter/.git/hooks/post-commit

      現在測試它的輸出:

      $?echo?"hello?world"?>?foo.txt $?git?add?foo.txt $?git?commit?-m?'first?commit' !?POST-COMMIT?SCRIPT?TRIGGERED [master?(root-commit)?c8678e0]?first?commit 1?file?changed,?1?insertion(+) create?mode?100644?foo.txt

      現在你已經實現了:你的第一個有功能的 Git 鉤子。

      有名的push-to-web鉤子

      Git 鉤子最流行的用法就是自動 push 更改的代碼到一個正在使用中的產品級 Web 服務器目錄下。這是擺脫 FTP 的很好的方式,對于正在使用的產品保留完整的版本控制,整合并自動化內容的發布。

      如果操作正確,網站發布工作會像以前一樣很好的完成,而且在某種程度上,很精準。Git 真的好棒。我不知道誰最初想到這個主意,但是我是從 Emacs 和 Git 方面的專家,IBM 的 Bill von Hagen 那里第一次聽到它的。他的文章包含關于這個過程的權威介紹:Git 改變了分布式網頁開發的游戲規則。

      Git 變量

      Git 鉤子并不是被用戶直接執行,所以要弄清楚如何收集可能會混淆的重要信息。事實上,Git 鉤子腳本類似于其他的腳本,像 BASH、Python、C++ 等等一樣從標準輸入讀取參數。不同的是,我們不會給它提供這個輸入,所以,你在使用的時候,需要知道可能的輸入參數。

      在寫 Git 鉤子之前,看一下 Git 在你的項目目錄下 .git/hooks 目錄中提供的一些例子。舉個例子,在這個 pre-push.sample 文件里,注釋部分說明了如下內容:

      #?$1?--?即將?push?的遠程倉庫的名字 #?$2?--?即將?push?的遠程倉庫的?URL #?如果?push?的時候,并沒有一個命名的遠程倉庫,那么這兩個參數將會一樣。 #?提交的信息將以下列形式按行發送給標準輸入 #

      并不是所有的例子都是這么清晰,而且關于鉤子獲取變量的文檔依舊缺乏(除非你去讀 Git 的源碼)。但是,如果你有疑問,你可以從線上其他用戶的嘗試中學習,或者你只是寫一些基本的腳本,比如 echo $1, $2, $3 等等。

      分支檢測示例

      我發現,對于生產環境來說有一個共同的需求,就是需要一個只有在特定分支被修改之后,才會觸發事件的鉤子。以下就是如何跟蹤分支的示例。

      首先,Git 鉤子本身是不受版本控制的。 Git 并不會跟蹤它自己的鉤子,因為對于鉤子來說,它是 Git 的一部分,而不是你倉庫的一部分。所以,Git 鉤子可以監控你的 Git 服務器上的一個空倉庫的 commit 記錄和 push 記錄,而不是你本地倉庫的一部分。

      我們來寫一個 post-receive(也就是說,在 commit 被接受之后觸發)鉤子。第一步就是需要確定分支名:

      #!/bin/tcsh foreach?arg?(?$

      這個 for 循環用來讀入第一個參數 $1 ,然后循環用第二個參數 $2 去覆蓋它,然后用第三個參數 $3 再這樣。在 Bash 中有一個更好的方法,使用 read 命令,并且把值放入數組里。但是,這里是 tcsh,并且變量的順序可以預測的,所以,這個方法也是可行的。

      當我們有了 commit 記錄的 refname,我們就能使用 Git 去找到這個分支的供人看的名字:

      set?branch?=?`git?rev-parse?--symbolic?--abbrev-ref?$refname` echo?$branch?#DEBUG

      然后把這個分支名和我們想要觸發的事件的分支名關鍵字進行比較:

      if?(?"$branch"?==?"master"?)?then ??echo?"Branch?detected:?master" ??git?/ ????--work-tree=/path/to/where/you/want/to/copy/stuff/to?/ ????checkout?-f?$branch?||?echo?"master?fail" else?if?(?"$branch"?==?"dev"?)?then ??echo?"Branch?detected:?dev" ??Git?/ ????--work-tree=/path/to/where/you/want/to/copy/stuff/to?/ ????checkout?-f?$branch?||?echo?"dev?fail" ??else ????echo?"Your?push?was?successful." ????echo?"Private?branch?detected.?No?action?triggered." endif

      給這個腳本分配可執行權限:

      $?chmod?+x?~/jupiter/.git/hooks/post-receive

      現在,當一個用戶提交到服務器的 master 分支,那些代碼就會被復制到一個生產環境的目錄,提交到 dev 分支則會被復制到另外的地方,其他分支將不會觸發這些操作。

      同時,創造一個 pre-commit 腳本也很簡單。比如,判斷一個用戶是否在他們不該 push 的分支上 push 代碼,或者對 commit 信息進行解析等等。

      Git 鉤子也可以變得復雜,而且它們因為 Git 的工作流的抽象層次不同而變得難以理解,但是它們確實是一個強大的系統,讓你能夠在你的 Git 基礎設施上針對所有的行為進行對應的操作。如果你是一個 Git 重度用戶,或者一個全職 Git 管理員,那么 Git 鉤子是值得學習的,只有當你熟悉這個過程,你才能真正掌握它。

      在我們這個系列下一篇也是最后一篇文章中,我們將會學習如何使用 Git 來管理非文本的二進制數據,比如音頻和圖片。

      本文地址:http://www.linuxprobe.com/found-git-server.html

      免費提供最新Linux技術教程書籍,為開源技術愛好者努力做得更多更好:http://www.linuxprobe.com/

      Git ssh

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何制作加粗的邊框表格?
      下一篇:兩種方法教你在excel里快速篩選出兩個表格的不同之處
      相關文章
      亚洲国产区男人本色在线观看| 色噜噜综合亚洲av中文无码| 亚洲人成高清在线播放| 亚洲成AV人片一区二区密柚| 国产精品亚洲综合一区| 日韩精品亚洲专区在线影视| 99亚洲乱人伦aⅴ精品| 亚洲日本在线电影| 亚洲日韩精品无码AV海量| 亚洲人成免费网站| 亚洲一区二区三区免费在线观看 | 亚洲国产精品不卡毛片a在线| 久久亚洲AV成人无码国产电影| 最新亚洲春色Av无码专区| 7777久久亚洲中文字幕| 亚洲人成网男女大片在线播放| 亚洲av乱码一区二区三区 | 亚洲国产日韩在线人成下载| 亚洲综合激情视频| 91嫩草亚洲精品| 国产精品亚洲四区在线观看 | 亚洲国产三级在线观看| 国产精品亚洲а∨无码播放| 精品久久香蕉国产线看观看亚洲| 国产亚洲一区二区手机在线观看| 亚洲高清专区日韩精品| 亚洲丝袜美腿视频| 亚洲日产2021三区在线 | 亚洲精品成人片在线观看| 国产精品亚洲产品一区二区三区| 国产亚洲精品无码拍拍拍色欲 | 亚洲欧洲日韩极速播放| 亚洲欧洲AV无码专区| 国产精品亚洲精品日韩动图| 亚洲欧洲中文日韩av乱码| 久久亚洲中文字幕精品一区四| 亚洲色精品aⅴ一区区三区| 亚洲AV午夜成人影院老师机影院| 久久亚洲AV成人无码软件| 亚洲乱码一二三四区国产| 亚洲精品无码永久在线观看男男|