自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Git系列(六):如何搭建你自己的Git服務(wù)器

系統(tǒng) Linux 開(kāi)源
現(xiàn)在我們將要學(xué)習(xí)如何搭建 git 服務(wù)器,如何編寫自定義的 Git 鉤子來(lái)在特定的事件觸發(fā)相應(yīng)的動(dòng)作(例如通知),或者是發(fā)布你的代碼到一個(gè)站點(diǎn)。我們主要討論的還是以一個(gè)使用者的身份與 Git 進(jìn)行交互。這篇文章中我將討論 Git 的管理,并且設(shè)計(jì)一個(gè)靈活的 Git 框架。

[[172092]]

現(xiàn)在我們將要學(xué)習(xí)如何搭建 git 服務(wù)器,如何編寫自定義的 Git 鉤子來(lái)在特定的事件觸發(fā)相應(yīng)的動(dòng)作(例如通知),或者是發(fā)布你的代碼到一個(gè)站點(diǎn)。

直到現(xiàn)在,我們主要討論的還是以一個(gè)使用者的身份與 Git 進(jìn)行交互。這篇文章中我將討論 Git 的管理,并且設(shè)計(jì)一個(gè)靈活的 Git 框架。你可能會(huì)覺(jué)得這聽(tīng)起來(lái)是 “高階 Git 技術(shù)” 或者 “只有狂熱粉才能閱讀”的一句委婉的說(shuō)法,但是事實(shí)是這里面的每個(gè)任務(wù)都不需要很深的知識(shí)或者其他特殊的訓(xùn)練,就能基本理解 Git 的工作原理,有可能需要一丁點(diǎn)關(guān)于 Linux 的知識(shí)。

共享 Git 服務(wù)器

創(chuàng)建你自己的共享 Git 服務(wù)器意外地簡(jiǎn)單,而且在很多情況下,遇到的這點(diǎn)麻煩是完全值得的。不僅僅是因?yàn)樗WC你有權(quán)限查看自己的代碼,它還可以通過(guò)擴(kuò)展為 Git 的使用敞開(kāi)了一扇大門,例如個(gè)人 Git 鉤子、***制的數(shù)據(jù)存儲(chǔ)、和持續(xù)集成與分發(fā)(CI & CD)。

如果你知道如何使用 Git 和 SSH,那么你已經(jīng)知道怎么創(chuàng)建一個(gè) Git 服務(wù)器了。Git 的設(shè)計(jì)方式,就是讓你在創(chuàng)建或者 clone 一個(gè)倉(cāng)庫(kù)的時(shí)候,就完成了一半服務(wù)器的搭建。然后允許用 SSH 訪問(wèn)倉(cāng)庫(kù),而且任何有權(quán)限訪問(wèn)的人都可以使用你的倉(cāng)庫(kù)作為 clone 的新倉(cāng)庫(kù)的基礎(chǔ)。

但是,這是一個(gè)小的點(diǎn)對(duì)點(diǎn)環(huán)境(ad-hoc)。按照一些方案你可以創(chuàng)建一些帶有同樣的功能的設(shè)計(jì)優(yōu)良的 Git 服務(wù)器,同時(shí)有更好的拓展性。

首要之事:確認(rèn)你的用戶們,現(xiàn)在的用戶以及之后的用戶都要考慮。如果你是唯一的用戶那么沒(méi)有任何改動(dòng)的必要。但是如果你試圖邀請(qǐng)其他的代碼貢獻(xiàn)者使用,那么你應(yīng)該允許一個(gè)專門的分享系統(tǒng)用戶給你的開(kāi)發(fā)者們。

假定你有一個(gè)可用的服務(wù)器(如果沒(méi)有,這不成問(wèn)題,Git 會(huì)幫忙解決,CentOS 的 樹(shù)莓派 3 是個(gè)不錯(cuò)的開(kāi)始),然后***步就是只允許使用 SSH 密鑰認(rèn)證的 SSH 登錄。這比使用密碼登錄安全得多,因?yàn)檫@可以免于暴力破解,也可以通過(guò)直接刪除用戶密鑰而禁用用戶。

一旦你啟用了 SSH 密鑰認(rèn)證,創(chuàng)建 gituser 用戶。這是給你的所有授權(quán)的用戶們的公共用戶: 

  1. $ su -c 'adduser gituser' 

然后切換到剛創(chuàng)建的 gituser 用戶,創(chuàng)建一個(gè) ~/.ssh 的框架,并設(shè)置好合適的權(quán)限。這很重要,如果權(quán)限設(shè)置得太開(kāi)放會(huì)使自己所保護(hù)的 SSH 沒(méi)有意義。

  1. $ su - gituser 
  2. $ mkdir .ssh && chmod 700 .ssh 
  3. $ touch .ssh/authorized_keys 
  4. $ chmod 600 .ssh/authorized_keys 

authorized_keys 文件里包含所有你的開(kāi)發(fā)者們的 SSH 公鑰,你開(kāi)放權(quán)限允許他們可以在你的 Git 項(xiàng)目上工作。他們必須創(chuàng)建他們自己的 SSH 密鑰對(duì)然后把他們的公鑰給你。復(fù)制公鑰到 gituser 用戶下的 authorized_keys 文件中。例如,為一個(gè)叫 Bob 的開(kāi)發(fā)者,執(zhí)行以下命令:

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

只要開(kāi)發(fā)者 Bob 有私鑰并且把相對(duì)應(yīng)的公鑰給你,Bob 就可以用 gituser 用戶訪問(wèn)服務(wù)器。

但是,你并不是想讓你的開(kāi)發(fā)者們能使用服務(wù)器,即使只是以 gituser 的身份訪問(wèn)。你只是想給他們?cè)L問(wèn) Git 倉(cāng)庫(kù)的權(quán)限。因?yàn)檫@個(gè)特殊的原因,Git 提供了一個(gè)限制的 shell,準(zhǔn)確的說(shuō)是 git-shell。以 root 身份執(zhí)行以下命令,把 git-shell 添加到你的系統(tǒng)中,然后設(shè)置成 gituser 用戶的默認(rèn) shell。

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

現(xiàn)在 gituser 用戶只能使用 SSH 來(lái) push 或者 pull Git 倉(cāng)庫(kù),并且無(wú)法使用任何一個(gè)可以登錄的 shell。你應(yīng)該把你自己添加到和 gituser 一樣的組中,在我們的樣例服務(wù)器中這個(gè)組的名字也是 gituser。

舉個(gè)例子:

  1. # usermod -a -G gituser seth 

僅剩下的一步就是創(chuàng)建一個(gè) Git 倉(cāng)庫(kù)。因?yàn)闆](méi)有人能在服務(wù)器上直接與 Git 交互(也就是說(shuō),你之后不能 SSH 到服務(wù)器然后直接操作這個(gè)倉(cāng)庫(kù)),所以創(chuàng)建一個(gè)空的倉(cāng)庫(kù) 。如果你想使用這個(gè)放在服務(wù)器上的倉(cāng)庫(kù)來(lái)完成工作,你可以從它的所在處 clone 下來(lái),然后在你的 home 目錄下進(jìn)行工作。

嚴(yán)格地講,你不是必須創(chuàng)建這個(gè)空的倉(cāng)庫(kù);它和一個(gè)正常的倉(cāng)庫(kù)一樣工作。但是,一個(gè)空的倉(cāng)庫(kù)沒(méi)有工作分支(working tree) (也就是說(shuō),使用 checkout 并沒(méi)有任何分支顯示)。這很重要,因?yàn)椴辉试S遠(yuǎn)程使用者們 push 到一個(gè)有效的分支上(如果你正在 dev 分支工作然后突然有人把一些變更 push 到你的工作分支,你會(huì)有怎么樣的感受?)。因?yàn)橐粋€(gè)空的倉(cāng)庫(kù)可以沒(méi)有有效的分支,所以這不會(huì)成為一個(gè)問(wèn)題。

你可以把這個(gè)倉(cāng)庫(kù)放到任何你想放的地方,只要你想要放開(kāi)權(quán)限給用戶和用戶組,讓他們可以在倉(cāng)庫(kù)下工作。千萬(wàn)不要保存目錄到比如說(shuō)一個(gè)用戶的 home 目錄下,因?yàn)槟抢镉袊?yán)格的權(quán)限限制。保存到一個(gè)常規(guī)的共享地址,例如 /opt 或者 /usr/local/share。

以 root 身份創(chuàng)建一個(gè)空的倉(cāng)庫(kù):

  1. # git init --bare /opt/jupiter.git 
  2. # chown -R gituser:gituser /opt/jupiter.git 
  3. # chmod -R 770 /opt/jupiter.git 

現(xiàn)在任何一個(gè)用戶,只要他被認(rèn)證為 gituser 或者在 gituser 組中,就可以從 jupiter.git 庫(kù)中讀取或者寫入。在本地機(jī)器嘗試以下操作:

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

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

Git 鉤子

運(yùn)行你自己的 Git 服務(wù)器最贊的一件事之一就是可以使用 Git 鉤子。Git 托管服務(wù)有時(shí)提供一個(gè)鉤子類的接口,但是他們并不會(huì)給你真正的 Git 鉤子來(lái)讓你訪問(wèn)文件系統(tǒng)。Git 鉤子是一個(gè)腳本,它將在一個(gè) Git 過(guò)程的某些點(diǎn)運(yùn)行;鉤子可以運(yùn)行在當(dāng)一個(gè)倉(cāng)庫(kù)即將接收一個(gè) commit 時(shí)、或者接受一個(gè) commit 之后,或者即將接收一次 push 時(shí),或者一次 push 之后等等。

這是一個(gè)簡(jiǎn)單的系統(tǒng):任何放在 .git/hooks 目錄下的腳本、使用標(biāo)準(zhǔn)的命名體系,就可按設(shè)計(jì)好的時(shí)間運(yùn)行。一個(gè)腳本是否應(yīng)該被運(yùn)行取決于它的名字; pre-push 腳本在 push 之前運(yùn)行,post-receive 腳本在接受 commit 之后運(yùn)行等等。這或多或少的可以從名字上看出來(lái)。

腳本可以用任何語(yǔ)言寫;如果在你的系統(tǒng)上有可以執(zhí)行的腳本語(yǔ)言,例如輸出 ‘hello world’ ,那么你就可以這個(gè)語(yǔ)言來(lái)寫 Git 鉤子腳本。Git 默認(rèn)帶了一些例子,但是并不有啟用。

想要?jiǎng)邮衷囈粋€(gè)?這很簡(jiǎn)單。如果你沒(méi)有現(xiàn)成的 Git 倉(cāng)庫(kù),首先創(chuàng)建一個(gè) Git 倉(cāng)庫(kù):

  1. $ mkdir jupiter 
  2. $ cd jupiter 
  3. $ git init . 

然后寫一個(gè) “hello world” 的 Git 鉤子。因?yàn)槲覟榱酥С掷吓f系統(tǒng)而使用 tsch,所以我仍然用它作為我的腳本語(yǔ)言,你可以自由的使用自己喜歡的語(yǔ)言(Bash,Python,Ruby,Perl,Rust,Swift,Go):

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

現(xiàn)在測(cè)試它的輸出:

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

現(xiàn)在你已經(jīng)實(shí)現(xiàn)了:你的***個(gè)有功能的 Git 鉤子。

有名的 push-to-web 鉤子

Git 鉤子***的用法就是自動(dòng) push 更改的代碼到一個(gè)正在使用中的產(chǎn)品級(jí) Web 服務(wù)器目錄下。這是擺脫 FTP 的很好的方式,對(duì)于正在使用的產(chǎn)品保留完整的版本控制,整合并自動(dòng)化內(nèi)容的發(fā)布。

如果操作正確,網(wǎng)站發(fā)布工作會(huì)像以前一樣很好的完成,而且在某種程度上,很精準(zhǔn)。Git 真的好棒。我不知道誰(shuí)最初想到這個(gè)主意,但是我是從 Emacs 和 Git 方面的專家,IBM 的 Bill von Hagen 那里***次聽(tīng)到它的。他的文章包含關(guān)于這個(gè)過(guò)程的權(quán)威介紹:Git 改變了分布式網(wǎng)頁(yè)開(kāi)發(fā)的游戲規(guī)則。

Git 變量

每一個(gè) Git 鉤子都有一系列不同的變量對(duì)應(yīng)觸發(fā)鉤子的不同 Git 行為。你需不需要這些變量,主要取決于你寫的程序。如果你只是需要一個(gè)當(dāng)某人 push 代碼時(shí)候的通用郵件通知,那么你就不需要什么特殊的東西,甚至也不需要編寫額外的腳本,因?yàn)橐呀?jīng)有現(xiàn)成的適合你的樣例腳本。如果你想在郵件里查看 commit 信息和 commit 的作者,那么你的腳本就會(huì)變得相對(duì)麻煩些。

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

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

  1. # $1 -- 即將 push 的遠(yuǎn)程倉(cāng)庫(kù)的名字 
  2. # $2 -- 即將 push 的遠(yuǎn)程倉(cāng)庫(kù)的 URL 
  3. # 如果 push 的時(shí)候,并沒(méi)有一個(gè)命名的遠(yuǎn)程倉(cāng)庫(kù),那么這兩個(gè)參數(shù)將會(huì)一樣。 
  4. # 提交的信息將以下列形式按行發(fā)送給標(biāo)準(zhǔn)輸入 
  5. # <local ref> <local sha1> <remote ref> <remote sha1> 

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

分支檢測(cè)示例

我發(fā)現(xiàn),對(duì)于生產(chǎn)環(huán)境來(lái)說(shuō)有一個(gè)共同的需求,就是需要一個(gè)只有在特定分支被修改之后,才會(huì)觸發(fā)事件的鉤子。以下就是如何跟蹤分支的示例。

首先,Git 鉤子本身是不受版本控制的。 Git 并不會(huì)跟蹤它自己的鉤子,因?yàn)閷?duì)于鉤子來(lái)說(shuō),它是 Git 的一部分,而不是你倉(cāng)庫(kù)的一部分。所以,Git 鉤子可以監(jiān)控你的 Git 服務(wù)器上的一個(gè)空倉(cāng)庫(kù)的 commit 記錄和 push 記錄,而不是你本地倉(cāng)庫(kù)的一部分。

我們來(lái)寫一個(gè) post-receive(也就是說(shuō),在 commit 被接受之后觸發(fā))鉤子。***步就是需要確定分支名:

  1. #!/bin/tcsh 
  2. foreach arg ( $< ) 
  3.   set argv = ( $arg ) 
  4.   set refname = $1 
  5. end 

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

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

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

然后把這個(gè)分支名和我們想要觸發(fā)的事件的分支名關(guān)鍵字進(jìn)行比較:

  1. if ( "$branch" == "master" ) then 
  2.   echo "Branch detected: master" 
  3.   git \ 
  4.     --work-tree=/path/to/where/you/want/to/copy/stuff/to \ 
  5.     checkout -f $branch || echo "master fail" 
  6. else if ( "$branch" == "dev" ) then 
  7.   echo "Branch detected: dev" 
  8.   Git \ 
  9.     --work-tree=/path/to/where/you/want/to/copy/stuff/to \ 
  10.     checkout -f $branch || echo "dev fail" 
  11.   else 
  12.     echo "Your push was successful." 
  13.     echo "Private branch detected. No action triggered." 
  14. endif 

給這個(gè)腳本分配可執(zhí)行權(quán)限:

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

現(xiàn)在,當(dāng)一個(gè)用戶提交到服務(wù)器的 master 分支,那些代碼就會(huì)被復(fù)制到一個(gè)生產(chǎn)環(huán)境的目錄,提交到 dev 分支則會(huì)被復(fù)制到另外的地方,其他分支將不會(huì)觸發(fā)這些操作。

同時(shí),創(chuàng)造一個(gè) pre-commit 腳本也很簡(jiǎn)單。比如,判斷一個(gè)用戶是否在他們不該 push 的分支上 push 代碼,或者對(duì) commit 信息進(jìn)行解析等等。

Git 鉤子也可以變得復(fù)雜,而且它們因?yàn)?Git 的工作流的抽象層次不同而變得難以理解,但是它們確實(shí)是一個(gè)強(qiáng)大的系統(tǒng),讓你能夠在你的 Git 基礎(chǔ)設(shè)施上針對(duì)所有的行為進(jìn)行對(duì)應(yīng)的操作。如果你是一個(gè) Git 重度用戶,或者一個(gè)全職 Git 管理員,那么 Git 鉤子是值得學(xué)習(xí)的,只有當(dāng)你熟悉這個(gè)過(guò)程,你才能真正掌握它。

在我們這個(gè)系列下一篇也是***一篇文章中,我們將會(huì)學(xué)習(xí)如何使用 Git 來(lái)管理非文本的二進(jìn)制數(shù)據(jù),比如音頻和圖片。

責(zé)任編輯:龐桂玉 來(lái)源: Linux中國(guó)
相關(guān)推薦

2014-03-06 09:23:19

Git服務(wù)器Github

2021-02-05 05:29:51

服務(wù)器GitGogs

2022-10-10 12:15:38

CentOSgit服務(wù)器

2023-04-01 18:19:38

團(tuán)隊(duì)MIT開(kāi)源

2020-01-18 18:41:13

GitGit服務(wù)器開(kāi)源

2011-04-11 11:05:07

FreeBSD 8.1

2015-07-08 09:57:59

Git服務(wù)器分步詳解

2021-03-09 00:05:40

服務(wù)器GiteaGogs

2013-04-02 10:13:35

Git服務(wù)器系統(tǒng)GitHub

2022-08-24 08:33:27

Git系統(tǒng)Linux

2016-08-05 12:58:44

GitLinux開(kāi)源

2020-08-14 08:00:39

Git數(shù)據(jù)層控制層

2019-12-03 10:45:35

NodeMySQLGit

2016-08-03 15:32:50

GitLinux開(kāi)源

2016-08-02 11:06:34

開(kāi)源Linux版本控制

2018-02-28 17:05:19

UbuntuGo語(yǔ)言Git

2021-03-30 08:43:29

黑客PHP團(tuán)隊(duì)Git

2011-08-11 09:28:48

2012-02-27 13:56:19

Java服務(wù)器

2018-03-26 10:20:13

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)