簡體中文 ▾ 主題 ▾ 最新版本 ▾ 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 模擬層。

它功能強大。但是,並非所有方法都已實現,並且對於已實現的方法,並非所有開關都已實現。

已使用 CLI CVS 客戶端和 Eclipse CVS 外掛進行了測試。大多數功能在這兩個客戶端上都能正常工作。

選項

所有這些選項顯然只有在伺服器端強制執行時才有意義。它們已實現,以儘可能接近 git-daemon[1] 選項。

--base-path <path>

在請求的 CVSROOT 前面加上 path

--strict-paths

不允許遞迴到子目錄

--export-all

不要在配置中檢查 gitcvs.enabled。如果希望使用此選項,還必須指定允許的目錄列表(見下文)。

-V
--version

列印版本資訊並退出

-h
-H
--help

列印用法資訊並退出

<directory>

其餘引數是目錄列表。如果沒有給出目錄,則允許所有目錄。除非指定了 --export-all,否則這些目錄中的儲存庫仍然需要 gitcvs.enabled 配置選項。

侷限性

CVS 客戶端無法標記、分支或執行 Git 合併。

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 只提供匿名訪問。要提交,您需要建立 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>

    SSH 訪問不需要特殊設定,只需在 PATH 中包含 Git 工具即可。如果您有不支援 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 儲存庫本身具有寫入許可權。

    您還需要確保每個儲存庫都是“裸”(沒有 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. 對於將要進行提交的 SSH 客戶端,請確保他們的伺服器端 .ssh/environment 檔案(或 .bashrc 等,根據他們的特定 shell)匯出 GIT_AUTHOR_NAME、GIT_AUTHOR_EMAIL、GIT_COMMITTER_NAME 和 GIT_COMMITTER_EMAIL 的適當值。對於登入 shell 為 bash 的 SSH 客戶端,.bashrc 可能是一個合理的替代方案。

  5. 客戶端現在應該能夠檢出專案。使用 CVS 模組名稱來指示您想檢出哪個 Git head。這也將設定您新檢出目錄的名稱,除非您使用 -d <dir-name> 另行指定。例如,這將檢出 master 分支到 project-master 目錄

       cvs co -d project-master master

資料庫後端

git-cvsserver 為每個 Git head(即 CVS 模組)使用一個數據庫來儲存有關儲存庫的資訊,以維護一致的 CVS 版本號。每次提交後都需要更新(即寫入)資料庫。

如果提交是直接使用 git(而不是使用 git-cvsserver)完成的,則需要在下次 git-cvsserver 訪問儲存庫時進行更新,而不管訪問方法和請求的操作如何。

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

預設情況下,它使用 Git 目錄中的 SQLite 資料庫,名為 gitcvs.<module-name>.sqlite。請注意,SQLite 後端在寫入時會在資料庫檔案所在的目錄中建立臨時檔案,因此授予使用 git-cvsserver 的使用者對資料庫檔案的寫入訪問許可權可能不足以讓他們寫入目錄,也需要授予他們目錄的寫入許可權。

在分支發生更改後,無法以一致的形式可靠地重新生成資料庫。示例:對於合併的分支,git-cvsserver 只跟蹤一個開發分支,並且在 git merge 之後,增量更新的資料庫可能跟蹤與從頭開始重新生成的資料庫不同的分支,從而導致不一致的 CVS 版本號。git-cvsserver 無法知道如果它在合併前以增量方式執行會選擇哪個分支。因此,如果您必須完全或部分(從舊備份)重新生成資料庫,您應該警惕預先存在的 CVS 沙盒。

您可以使用以下配置變數配置資料庫後端:

配置資料庫後端

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>... 引數列表。儲存庫仍然需要 gitcvs.enabled 配置選項,除非指定了 --export-all

當設定了這些環境變數時,可能不會使用相應的命令列引數。

Eclipse CVS 客戶端注意事項

要使用 Eclipse CVS 客戶端進行檢出:

  1. 選擇“建立新專案 → 從 CVS 檢出”

  2. 建立新位置。有關如何選擇正確協議的詳細資訊,請參閱下面的注意事項。

  3. 瀏覽可用的模組。它將為您提供儲存庫中 head 的列表。您將無法在此處瀏覽樹。只能瀏覽 head。

  4. 在詢問要檢出的分支/標籤時,選擇 HEAD。取消選中“啟動提交嚮導”以避擴音交 .project 檔案。

協議注意事項:如果您正在使用 pserver 進行匿名訪問,請選擇該選項。使用 SSH 訪問的人員應選擇 ext 協議,並在 Preferences→Team→CVS→ExtConnection 窗格中配置 ext 訪問。將 CVS_SERVER 設定為“git cvsserver”。請注意,使用 ext 時密碼支援不佳,您絕對需要設定 SSH 金鑰。

或者,您也可以使用 Eclipse 提供的非標準 extssh 協議。在這種情況下,將忽略 CVS_SERVER,您必須將伺服器上的 cvs 工具替換為 git-cvsserver 或修改您的 .bashrc,以便呼叫 cvs 有效地呼叫 git-cvsserver

已知可正常工作的客戶端

  • CVS 1.12.9 (Debian)

  • CVS 1.11.17 (MacOSX,來自 Fink 包)

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

  • TortoiseCVS

支援的操作

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

大多數讀取 CVS 標籤或修訂號的 CVS 命令引數(通常是 -r)都可以工作,並且還支援任何 git refspec(標籤、分支、提交 ID 等)。但是,非預設分支的 CVS 修訂號的模擬效果不佳,並且 cvs log 完全不顯示標籤或分支。(非主分支的 CVS 修訂號表面上類似於 CVS 修訂號,但實際上它們直接編碼了 git 提交 ID,而不是代表自分支點以來的修訂數量。)

請注意,有兩種方法可以檢出一個特定分支。如本頁其他地方所述,cvs checkout 的“module”引數被解釋為分支名稱,它成為主分支。即使您使用 cvs update -r 暫時使另一個分支具有粘性,它對於給定的沙盒來說仍然是主分支。或者,-r 引數可以表示要實際檢出的其他分支,即使模組仍然是“主”分支。權衡(當前實現):每個新的“模組”都會在磁碟上建立一個新的資料庫,其中包含給定模組的歷史記錄,並且在建立資料庫後,對該主分支的操作將很快。或者,-r 不會佔用額外的磁碟空間,但對於許多操作(如 cvs update)可能非常慢。

如果您想引用一個包含 CVS 不允許的字元的 git refspec,您有兩個選擇。首先,直接將 git refspec 提供給適當的 CVS -r 引數可能有效;一些 CVS 客戶端似乎並沒有對該引數進行太多健全性檢查。其次,如果失敗,您可以使用特殊的字元轉義機制,該機制僅使用 CVS 標籤中有效的字元。形式為(下劃線("_")、連字元("-")、一個或兩個字元,以及連字元("-"))的 4 或 5 個字元序列可以根據一個或兩個字母來編碼各種字元:"s" 表示斜槓("/"),"p" 表示句點("."),"u" 表示下劃線("_"),或者任意位元組值的兩個十六進位制數字(通常是 ASCII 數字,或可能是 UTF-8 編碼字元的一部分)。

不支援舊的監控操作(edit、watch 及相關操作)。目前不支援匯出和標記(標籤和分支)。

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] 套件的一部分