## 命名

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-daemon [1] 选项类似。

--base-path <path>

预先`path`申请 CVSROOT

--strict-paths

不要允许递归到子目录中

--export-all

不要`gitcvs.enabled`在配置中检查。如果要使用此选项，还必须指定允许的目录列表（请参见下文）。

-V --version

打印版本信息并退出

-h -H --help

打印使用情况信息并退出

<directory>

您可以指定允许的目录列表。如果没有给出目录，则全部允许。这是一个额外的限制，gitcvs 访问仍然需要`gitcvs.enabled`配置选项启用，除非`--export-all`被给予。

## 描述

此应用程序是 Git 的 CVS 仿真层。

它功能强大。但是并非所有方法都已实施，对于已实施的方法，并非所有交换机都已实施。

使用 CLI CVS 客户端和 Eclipse CVS 插件完成了测试。大多数功能都可以与这两个客户端正常工作。

## 限制

CVS 客户端不能标记，分支或执行 Git 合并。

`git-cvsserver`将 Git 分支映射到 CVS 模块。这与大多数 CVS 用户所期望的完全不同，因为在 CVS 中，模块通常代表一个或多个目录。

## 安装

1. 如果您要通过 pserver 提供 CVS 访问，请在 /etc/inetd.conf 中添加一行，如 cvspserver stream tcp nowait nobody git-cvsserver pserver

注意：某些 inetd 服务器允许您指定独立于 argv0 值的可执行文件的名称。在这种情况下，/etc/inetd.conf 中的正确行看起来像

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

pserve 默认只提供匿名访问。要提交，您必须创建 pserver 帐户，只需在要让 cvsserver 允许写入的存储库的配置文件中添加 gitcvs.authdb 设置，例如：

      [gitcvs]         authdb = /etc/cvsserver/passwd

这些文件的格式是用户名后跟加密的密码，例如：

      myuser:$1Oyx5r9mdGZ2    myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./

您可以使用`htpasswd` Apache 提供的工具来生成这些文件，但是 Apache 的 MD5 加密方法与大多数 C 库的 crypt（）函数所使用的方法不同，因此不要使用 -m 选项。

或者，你可以用 perl 的 crypt（）运算符产生密码：

      perl -e 'my ($user, $pass) = @ARGV; printf "%s:%s\n", $user, crypt($user, $pass)' $USER password

然后通过 pserver 方法提供您的密码，例如：

      cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD\_name>

除了在 PATH 中使用 Git 工具之外，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`文件中，你不必担心总是设置正确的环境变量。受限制的 SSH 用户`git-shell`不需要用 CVS_SERVER 覆盖缺省值（而且不应该）`git-shell`理解`cvs`为意味着`git-cvsserver`并假装另一端运行得`cvs`更好。

1. 对于您想要从 CVS 访问的每个回购，您需要编辑回购中的配置并添加以下部分。gitcvs enabled = 1＃可选，用于调试 logFile = / path / to / logfile

注意：您需要确保要调用的每个用户`git-cvsserver`都有对日志文件和数据库的写入权限（请参阅 Database Backend 。如果您想通过 SSH 提供写入权限，用户当然也需要对 Git 的写入权限存储库本身。

您还需要确保每个存储库都是 “bare”（没有 Git 索引文件）`cvs commit`才能工作。请参阅 gitcvs-migration [7]。

对于特定的访问方法，所有配置变量也可以被覆盖。有效的方法名称是 “ext”（用于 SSH 访问）和 “pserver” 。以下示例配置将禁用 pserver 访问，同时仍允许通过 SSH 进行访问。

      [gitcvs]         enabled=0     [gitcvs "ext"]         enabled=1

1. 如果您没有直接在 checkout 命令中指定 CVSROOT / CVS_SERVER ，将其自动保存在`CVS/Root`文件中，那么您需要在您的环境中明确设置它们。CVSROOT 应该按照正常进行设置，但目录应该指向适当的 Git 仓库。如上所述，对于`not`限制为 SSH 的客户端`git-shell`，应将 CVS_SERVER 设置为`git-cvsserver`。export CVSROOT =：ext：user @ server：/var/git/project.git export CVS_SERVER =“git cvsserver”

2. 对于将进行提交的 SSH 客户端，请确保其服务器端 .ssh /environment 文件（或 .bashrc 等，根据其特定的外壳）为 GIT_AUTHOR_NAME ，GIT_AUTHOR_EMAIL ，GIT_COMMITTER_NAME 和 GIT_COMMITTER_EMAIL 导出适当的值。对于登录 shell 为 bash 的 SSH 客户端，.bashrc 可能是一个合理的选择。

3. 客户现在应该能够检查项目。使用 CVS `module`名称来表明`head`你想要签出的 Git 。这也设置了新检出目录的名称，除非您另有说明`-d <dir_name>`。例如，这将检查`master`分支到`project-master`目录：cvs co -d project-master master

## 数据库后端

`git-cvsserver`每个 Git 头部（即 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

数据库表名称前缀。支持变量替换（见下文）。任何非字母字符将被替换为下划线。

所有变量也可以根据访问方法设置，参见上文。

#### 变量替代

在`dbDriver`和`dbUser`你可以使用以下变量：

%G

Git 目录名称

%g

Git 的目录名，其中除字母数字以外的所有字符`.`，并`-`与更换`_`（这应该更容易地在文件名中使用的目录名称，如果想）

%m

CVS 模块 / Git 头名称

%a

访问方法（“ext” 或 “pserver” 之一）

%u

正在运行的用户的名称`git-cvsserver`。如果不能确定名称，则使用数字 uid 。

## 环境

在某些情况下，这些变量可以避免使用命令行选项，从而通过 git-shell 更容易地限制使用。

GIT_CVSSERVER_BASE_PATH 取代了 --base-path 的参数。

GIT_CVSSERVER_ROOT 指定单目录白名单。如上所述，存储库仍必须配置为允许通过 git-cvsserver 进行访问。

当设置这些环境变量时，可能不会使用相应的命令行参数。

## Eclipse cvs 客户端笔记

要使用 Eclipse CVS 客户端进行结帐，请执行以下操作：

1. 选择“创建新项目→从 CVS 签出”

2. 创建一个新的位置。有关如何选择正确协议的详细信息，请参阅下面的注释。

3. 浏览`modules`可用。它会给你一个存储库中头的列表。你将无法从那里浏览树。只有头部。

4. 挑选`HEAD`时，它会询问什么分支/标签退房。取消“启动提交向导”以避免提交 .project 文件。

协议说明：如果您通过 pserver 使用匿名访问，请选择该选项。那些使用 SSH 访问的应该选择`ext`协议，并`ext`在首选项→团队→ CVS → ExtConnection 窗格中配置访问权限。将 CVS_SERVER 设置为“ `git cvsserver`”。请注意，密码支持在使用时不好`ext`，你一定会想要设置 SSH 密钥。

或者，您可以使用 Eclipse 提供的非标准 extssh 协议。在这种情况下，CVS_SERVER 将被忽略，并且您将不得不用服务器上的 cvs 实用程序替换`git-cvsserver`或操作您的服务器，`.bashrc`以便`cvs`有效地调用呼叫`git-cvsserver`。

## 已知客户端工作

- CVS 1.12.9在 Debian 上

- 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（标签，分支，提交 ID 等）。但是，对于非默认分支的 CVS 修订版编号没有很好地模拟，并且 CVS 日志根本不显示标签或分支。（非主分支 CVS 修订版本号与 CVS 修订版号相似，但实际上它们直接编码了一个 git commit ID ，而不是代表自分支点以来修订版的数目。）

请注意，有两种方法可以检出特定的分支。如本页其他地方所述，cvs checkout 的 “module” 参数被解释为分支名称，并且它将成为主分支。它仍然是给定沙箱的主要分支，即使您暂时使用 cvs update -r 使另一个分支变得粘稠。另外，即使模块仍然是 “main” 分支，-r 参数可以指示其他分支实际结帐。权衡（当前实施）：每个新的“模块”在磁盘上为给定模块创建一个新的数据库历史数据库，创建数据库后，对该主要分支的操作很快。或者，-r 不会占用额外的磁盘空间，但对于许多操作（如 cvs update ）可能会明显较慢。

如果你想参考一个 git refspec ，它有 CVS 不允许的字符，你有两个选择。首先，它可能只是将 git refspec 直接提供给适当的 CVS -r 参数; 一些 CVS 客户似乎没有对这个论点做太多的理智检查。其次，如果失败，您可以使用特殊字符转义机制，它只使用在 CVS 标记中有效的字符。（下划线（`"_"`），短划线（`"-"`），一个或两个字符以及短划线（`"-"`））的4或5个字符的序列可以根据一个或两个字母对各种字符进行编码：`"s"`for slash（`"/"`），`"p"`for period（`"."`） ，`"u"`用于下划线（`"_"`），或者任何字节值（通常是 ASCII 码，或者可能是 UTF-8 编码字符的一部分）的两个十六进制数字。

传统监控操作不受支持（编辑，监视和相关）。此阶段不支持导出和标记（标记和分支）。

### CRLF 行结束转换

默认情况下，服务器将`-k`所有文件的模式留空，这会导致 CVS 客户端将它们视为文本文件，并受某些平台上的行尾转换影响。

您可以通过设置`gitcvs.usecrlfattr`配置变量使服务器使用行尾转换属性来设置`-k`的模式。请参阅 gitattributes [5] 以获取有关行尾转换的更多信息。

或者，如果`gitcvs.usecrlfattr`config未启用或者属性不允许自动检测文件名，则服务器使用`gitcvs.allBinary`config作为默认设置。如果`gitcvs.allBinary`已设置，则未指定的文件将默认为`-kb`模式。否则，该`-k`模式留空。但是如果`gitcvs.allBinary`设置为“猜测”，则`-k`根据文件的内容猜测正确的模式。

为了达到最佳一致性`cvs`，最好通过设置`gitcvs.usecrlfattr`为 true 来覆盖默认值，`gitcvs.allBinary`“猜测”。

## Dependencies

`git-cvsserver` 依赖于 DBD :: SQLite 。