English ▾ 主題 ▾ 最新版本 ▾ git-cvsserver 最後更新於 2.50.0

名稱

git-cvsserver - Git 的 CVS 伺服器模擬器

概要

SSH

export CVS_SERVER="git cvsserver"
cvs -d :ext:user@server/path/repo.git co <HEAD_name>

pserver (/etc/inetd.conf)

cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver

用法

git-cvsserver [<options>] [pserver|server] [<directory> …​]

描述

此應用程式是 Git 的 CVS 模擬層。

它功能齊全。然而,並非所有方法都已實作,且對於已實作的方法,也非所有開關(switches)皆已實作。

已使用 CLI CVS 客戶端及 Eclipse CVS 外掛程式進行測試。大多數功能在這兩個客戶端上都能運作良好。

選項

顯然,所有這些選項僅在由伺服器端強制執行時才有意義。實作這些選項的目的是為了儘可能模仿 git-daemon[1] 的選項。

--base-path <路徑>

path 前置於請求的 CVSROOT

--strict-paths

不允許遞迴進入子目錄

--export-all

不檢查設定檔中的 gitcvs.enabled。若要使用此選項,您還必須指定允許的目錄清單(見下文)。

-V
--version

列印版本資訊並退出

-h
-H
--help

列印用法資訊並退出

<directory>

剩餘參數提供目錄清單。若未給定目錄,則允許所有目錄。除非指定了 --export-all,否則這些目錄內的儲存庫仍需要 gitcvs.enabled 設定選項。

限制

CVS 客戶端無法進行標記(tag)、分支(branch)或執行 Git 合併(merge)。

git-cvsserver 將 Git 分支對映到 CVS 模組。這與大多數 CVS 使用者所預期的非常不同,因為在 CVS 中,模組通常代表一個或多個目錄。

安裝

  1. 若您打算透過 pserver 提供 CVS 存取,請在 /etc/inetd.conf 中新增一行,例如

       cvspserver stream tcp nowait nobody git-cvsserver pserver

    注意:某些 inetd 伺服器允許您獨立於 argv[0] 的值(即程式假設其執行時的名稱)指定可執行檔名稱。在此情況下,/etc/inetd.conf 中的正確行如下所示

       cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver

    預設情況下,pserver 僅提供匿名存取。若要進行 commit,您必須建立 pserver 帳號,只需在您希望 cvsserver 允許寫入的儲存庫設定檔中新增 gitcvs.authdb 設定,例如

       [gitcvs]
    	authdb = /etc/cvsserver/passwd

    這些檔案的格式為使用者名稱後接加密密碼,例如

       myuser:sqkNi8zPf01HI
       myuser:$1$9K7FzU28$VfF6EoPYCJEYcVQwATgOP/
       myuser:$5$.NqmNH1vwfzGpV8B$znZIcumu1tNLATgV2l6e1/mY8RzhUDHMOaVOeL1cxV3

    您可以使用 Apache 隨附的 htpasswd 工具來製作這些檔案,但僅限使用 -d 選項(若您的系統支援,也可使用 -B)。

    建議使用您平台特定的工具來管理密碼雜湊建立(例如 Linux 下的 mkpasswd、OpenBSD 下的 encrypt 或 NetBSD 下的 pwhash),並將其貼到正確位置。

    然後透過 pserver 方法提供您的密碼,例如

       cvs -d:pserver:someuser:somepassword@server:/path/repo.git co <HEAD_name>

    除 Git 工具需在 PATH 中外,SSH 存取無需特殊設定。若您的客戶端不接受 CVS_SERVER 環境變數,您可以將 git-cvsserver 重新命名為 cvs

    注意:較新的 CVS 版本 (>= 1.12.11) 也支援直接在 CVSROOT 中指定 CVS_SERVER,如下所示

       cvs -d ":ext;CVS_SERVER=git cvsserver:user@server/path/repo.git" co <HEAD_name>

    這樣做的好處是它會被儲存在您的 CVS/Root 檔案中,您無需擔心總是設定正確的環境變數。受限於 git-shell 的 SSH 使用者不需要(也不應該)用 CVS_SERVER 覆蓋預設值,因為 git-shell 會將 cvs 解讀為 git-cvsserver,並假裝另一端執行的是真正的 cvs

  2. 對於每個您希望從 CVS 存取的儲存庫,您需要編輯該儲存庫中的 config 並新增以下區段。

       [gitcvs]
            enabled=1
            # optional for debugging
    	logFile=/path/to/logfile

    注意:您需要確保每個將要呼叫 git-cvsserver 的使用者對記錄檔和資料庫都有寫入權限(參閱 資料庫後端)。若您希望透過 SSH 提供寫入存取權,使用者當然也需要對 Git 儲存庫本身擁有寫入權限。

    您還需要確保每個儲存庫都是「裸庫」(bare,沒有 Git 索引檔),這樣 cvs commit 才能運作。參閱 gitcvs-migration[7]

    所有設定變數也可以針對特定的存取方法進行覆蓋。有效的方法名稱為 "ext"(用於 SSH 存取)和 "pserver"。以下範例設定將停用 pserver 存取,同時仍允許透過 SSH 存取。

       [gitcvs]
            enabled=0
    
       [gitcvs "ext"]
            enabled=1
  3. 若您未在 checkout 指令中直接指定 CVSROOT/CVS_SERVER(從而自動儲存在您的 CVS/Root 檔案中),則您需要在環境中明確設定它們。CVSROOT 應按正常方式設定,但目錄應指向相應的 Git 儲存庫。如上所述,對於受限於 git-shell 的 SSH 客戶端,CVS_SERVER 應設定為 git-cvsserver

       export CVSROOT=:ext:user@server:/var/git/project.git
       export CVS_SERVER="git cvsserver"
  4. 對於將執行 commit 的 SSH 客戶端,請確保其伺服器端的 .ssh/environment 檔案(或根據其特定 shell 的 .bashrc 等)匯出了 GIT_AUTHOR_NAME、GIT_AUTHOR_EMAIL、GIT_COMMITTER_NAME 和 GIT_COMMITTER_EMAIL 的適當值。對於登入 shell 為 bash 的 SSH 客戶端,.bashrc 可能是一個合理的替代方案。

  5. 客戶端現在應該能夠簽出(check out)專案了。使用 CVS 模組名稱來指示您要簽出的 Git head。除非您用 -d <目錄名稱> 另行指定,否則這也會設定您剛簽出目錄的名稱。例如,這會將 master 分支簽出到 project-master 目錄

       cvs co -d project-master master

資料庫後端

git-cvsserver 為每個 Git head(即 CVS 模組)使用一個資料庫來儲存有關儲存庫的資訊,以保持一致的 CVS 修訂版本號。資料庫需要在每次 commit 後更新(即寫入)。

若 commit 是直接使用 git 完成的(相對於使用 git-cvsserver),則更新將需要在下次 git-cvsserver 存取儲存庫時進行,這與存取方法和請求的操作無關。

這意味著即使您只提供讀取存取權(例如透過 pserver 方法),git-cvsserver 也必須具有資料庫的寫入權限才能可靠運作(否則您需要確保每次執行 git-cvsserver 時資料庫都是最新的)。

預設情況下,它會在 Git 目錄中使用 SQLite 資料庫,命名為 gitcvs.<模組名稱>.sqlite。請注意,SQLite 後端在寫入時會在與資料庫檔案相同的目錄中建立暫存檔,因此,僅賦予使用 git-cvsserver 的使用者對資料庫檔案的寫入權限,而不給予對該目錄的寫入權限,可能是不夠的。

在所追蹤的分支發生變更後,資料庫無法可靠地以一致的形式重新產生。範例:對於合併的分支,git-cvsserver 僅追蹤一個開發分支,而在 git merge 之後,增量更新的資料庫可能會追蹤與從頭重新產生的資料庫不同的分支,從而導致不一致的 CVS 修訂版本號。 git-cvsserver 無法得知若在合併前進行增量執行,它會選擇哪一個分支。因此,如果您必須全部或部分(從舊備份)重新產生資料庫,則應該對預先存在的 CVS 砂盒(sandbox)保持懷疑。

您可以使用以下設定變數來設定資料庫後端

設定資料庫後端

git-cvsserver 使用 Perl DBI 模組。若要變更這些變數,請務必閱讀其說明文件,特別是關於 DBI->connect() 的部分。

gitcvs.dbName

資料庫名稱。確切含義取決於所選的資料庫驅動程式,對於 SQLite,這是一個檔名。支援變數代換(見下文)。不可包含分號 (;)。預設:%Ggitcvs.%m.sqlite

gitcvs.dbDriver

使用的 DBI 驅動程式。您可以在此指定任何可用的驅動程式,但它可能無法運作。cvsserver 已在 DBD::SQLite 上測試,據報在 DBD::Pg 上可運作,並據報無法DBD::mysql 上運作。請將此視為實驗性功能。不可包含冒號 (:)。預設:SQLite

gitcvs.dbuser

資料庫使用者。僅在設定 dbDriver 時有用,因為 SQLite 沒有資料庫使用者的概念。支援變數代換(見下文)。

gitcvs.dbPass

資料庫密碼。僅在設定 dbDriver 時有用,因為 SQLite 沒有資料庫密碼的概念。

gitcvs.dbTableNamePrefix

資料庫資料表名稱字首。支援變數代換(見下文)。任何非字母字元將被底線取代。

所有變數也可以針對每個存取方法進行設定,參閱上文

變數代換

dbDriverdbUser 中,您可以使用以下變數

%G

Git 目錄名稱

%g

Git 目錄名稱,其中除字母數字、.- 以外的所有字元都被 _ 取代(若有需要,這應能更容易將目錄名稱用於檔名中)

%m

CVS 模組/Git head 名稱

%a

存取方法("ext" 或 "pserver" 之一)

%u

執行 git-cvsserver 的使用者名稱。若無法確定名稱,則使用數字 uid。

環境變數

這些變數在某些情況下免除了命令列選項的需求,允許透過 git-shell 進行更簡便的受限使用。

GIT_CVSSERVER_BASE_PATH

此變數取代了 --base-path 的參數。

GIT_CVSSERVER_ROOT

此變數指定單一目錄,取代了 <directory>... 參數清單。除非指定了 --export-all,否則該儲存庫仍需要 gitcvs.enabled 設定選項。

當設定了這些環境變數時,可能無法使用對應的命令列參數。

ECLIPSE CVS 客戶端注意事項

若要使用 Eclipse CVS 客戶端進行簽出

  1. 選擇「建立新專案 → 從 CVS 簽出 (Create a new project → From CVS checkout)」

  2. 建立一個新位置。關於如何選擇正確協定的詳細資訊,請參閱下方的注意事項。

  3. 瀏覽可用的 模組。它會給您一份儲存庫中的 head 清單。您將無法從那裡瀏覽樹狀結構,僅能瀏覽 head。

  4. 當詢問要簽出哪個分支/標記時,請選擇 HEAD。取消勾選「啟動 commit 精靈 (launch commit wizard)」以避免提交 .project 檔案。

協定注意事項:若您透過 pserver 使用匿名存取,直接選擇該選項即可。使用 SSH 存取的應選擇 ext 協定,並在「喜好設定→團隊→CVS→外部連線 (Preferences→Team→CVS→ExtConnection)」面板中設定 ext 存取。將 CVS_SERVER 設定為 "git cvsserver"。請注意,使用 ext 時密碼支援不佳,您絕對會希望設定 SSH 金鑰。

或者,您可以直接使用 Eclipse 提供的非標準 extssh 協定。在這種情況下,CVS_SERVER 會被忽略,您必須將伺服器上的 cvs 工具替換為 git-cvsserver,或操作您的 .bashrc,以便呼叫 cvs 實際上會呼叫 git-cvsserver

已知可用的客戶端

  • Debian 上的 CVS 1.12.9

  • MacOSX 上的 CVS 1.11.17(來自 Fink 套件)

  • MacOSX 上的 Eclipse 3.0, 3.1.2(參閱 Eclipse CVS 客戶端注意事項)

  • TortoiseCVS

支援的操作

支援正常使用所需的所有操作,包括 checkout、diff、status、update、log、add、remove、commit。

大多數讀取 CVS 標記或修訂號(通常為 -r)的 CVS 指令參數皆可運作,並且也支援任何 git refspec(標記、分支、commit ID 等)。然而,非預設分支的 CVS 修訂號模擬得並不完善,且 cvs log 根本不顯示標記或分支。(非主分支的 CVS 修訂號表面上類似於 CVS 修訂號,但實際上它們直接編碼了 git commit ID,而不是代表自分支點以來的修訂次數。)

請注意,簽出特定分支有兩種方法。如本頁其他地方所述,cvs checkout 的「模組」參數會被解釋為分支名稱,並成為主分支。即使您透過 cvs update -r 暫時使另一個分支成為 sticky,它對於給定的砂盒而言仍保持為主分支。或者,-r 參數可以指定要簽出的另一個分支,即使模組仍為「主」分支。權衡(如目前實作):每個新「模組」都會在磁碟上建立一個具有該模組歷程的新資料庫,而在資料庫建立後,針對該主分支的操作很快。或者,-r 不會佔用任何額外的磁碟空間,但對於許多操作(如 cvs update)來說可能會顯著變慢。

若您想參照具有 CVS 不允許之字元的 git refspec,您有兩個選擇。首先,直接將 git refspec 提供給相應的 CVS -r 參數可能直接可行;某些 CVS 客戶端似乎不會對參數進行太多健全性檢查。其次,若失敗,您可以使用僅使用 CVS 標記中有效字元的特殊字元跳脫機制。形式為 (底線 ("_")、破折號 ("-")、一或兩個字元、破折號 ("-")) 的 4 或 5 個字元序列,可以根據這一或兩個字母編碼各種字元:"s" 代表斜線 ("/")、"p" 代表句點 (".")、"u" 代表底線 ("_"),或任何位元組值的兩個十六進位數字(通常為 ASCII 數字,或者可能是 UTF-8 編碼字元的一部分)。

不支援舊有的監控操作(edit、watch 及相關操作)。在此階段不支援匯出(Exports)和標記(標記與分支)。

CRLF 行尾轉換

預設情況下,伺服器將所有檔案的 -k 模式留空,這會導致 CVS 客戶端將其視為文字檔案,在某些平台上會進行行尾轉換。

您可以透過設定 gitcvs.usecrlfattr 設定變數,讓伺服器使用行尾轉換屬性來設定檔案的 -k 模式。有關行尾轉換的更多資訊,請參閱 gitattributes[5]

或者,若未啟用 gitcvs.usecrlfattr 設定,或屬性無法自動偵測檔名,則伺服器會將 gitcvs.allBinary 設定用於預設設定。若設定了 gitcvs.allBinary,則未另行指定的檔案預設為 -kb 模式。否則 -k 模式將留空。但若 gitcvs.allBinary 設定為 "guess",則會根據檔案內容猜測正確的 -k 模式。

為了與 cvs 保持最佳一致性,最好的方法可能是將 gitcvs.usecrlfattr 設定為 true,並將 gitcvs.allBinary 設定為 "guess" 來覆蓋預設值。

依賴項目

git-cvsserver 依賴 DBD::SQLite。

GIT

git[1] 套件的一部分