Git
英语 ▾ 主题 ▾ 最新版本 ▾ git-cvsserver 最后更新于 2.44.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>

path 添加到请求的 CVSROOT 前面

--strict-paths

不允许递归进入子目录

--export-all

不检查配置中的 gitcvs.enabled。如果您想使用此选项,您还需要指定允许的目录列表(见下文)。

-V
--version

打印版本信息并退出

-h
-H
--help

打印用法信息并退出

<directory>

剩余的参数提供目录列表。如果没有给出目录,则允许所有目录。这些目录中的存储库仍然需要 gitcvs.enabled 配置选项,除非指定了 --export-all

局限性

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-shellcvs 理解为 git-cvsserver,并假装另一端运行的是真正的 cvs

  2. 对于您希望从 CVS 访问的每个存储库,您需要编辑存储库中的配置并添加以下部分。

       [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. 如果您没有在签出命令中直接指定 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 。这也设置了您新签出目录的名称,除非您使用 -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

数据库表名前缀。支持变量替换(见下文)。所有非字母字符将被替换为下划线。

所有变量也可以针对每个访问方法设置,见 上面

变量替换

dbDriverdbUser 中,您可以使用以下变量。

%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

此变量指定单个目录,替换 <directory>... 参数列表。存储库仍然需要 gitcvs.enabled 配置选项,除非指定 --export-all

当这些环境变量设置后,可能无法使用相应的命令行参数。

Eclipse CVS 客户端说明

要使用 Eclipse CVS 客户端获取签出

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

  2. 创建一个新位置。有关如何选择正确协议的详细信息,请参见下面的说明。

  3. 浏览可用的 模块。它将提供存储库中头的列表。您将无法从那里浏览树。只有头。

  4. 当它询问要签出的哪个分支/标签时,选择 HEAD。取消选中“启动提交向导”以避免提交 .project 文件。

协议说明:如果您通过 pserver 使用匿名访问,只需选择它即可。使用 SSH 访问的用户应该选择 ext 协议,并在“首选项→团队→CVS→ExtConnection”窗格中配置 ext 访问。将 CVS_SERVER 设置为“git cvsserver”。请注意,使用 ext 时,密码支持不好,您肯定需要设置 SSH 密钥。

或者,您也可以使用 Eclipse 提供的非标准 extssh 协议。在这种情况下,CVS_SERVER 会被忽略,您必须用 git-cvsserver 替换服务器上的 cvs 实用程序或操作您的 .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

支持的操作

支持所有正常使用所需的运算,包括签出、diff、状态、更新、日志、添加、删除、提交。

大多数读取 CVS 标签或修订号(通常为 -r)的 CVS 命令参数都能正常工作,并且还支持任何 git refspec(标签、分支、提交 ID 等)。但是,非默认分支的 CVS 修订号没有很好地模拟,并且 cvs log 根本不显示标签或分支。(非主分支的 CVS 修订号表面上类似于 CVS 修订号,但它们实际上直接编码 git 提交 ID,而不是表示自分支点以来的修订次数。)

请注意,签出特定分支有两种方法。如本页其他地方所述,cvs checkout 的“模块”参数被解释为分支名称,并且它成为主分支。即使您使用 cvs update -r 暂时将另一个分支设为粘性,它仍然是给定沙箱的主分支。或者,-r 参数可以指示要实际签出的其他分支,即使该模块仍然是“主”分支。权衡(如当前实现):每个新的“模块”都会在磁盘上创建一个新的数据库,其中包含给定模块的历史记录,并且在创建数据库后,针对该主分支的操作会很快。或者,-r 不会占用任何额外的磁盘空间,但在许多操作(如 cvs update)中可能明显更慢。

如果您要引用包含 CVS 不允许的字符的 git refspec,您有两个选择。首先,直接将 git refspec 提供给相应的 CVS -r 参数可能可以正常工作;一些 CVS 客户端似乎没有对参数进行太多完整性检查。其次,如果失败,您可以使用仅使用 CVS 标签中有效的字符的特殊字符转义机制。形式为(下划线 ("_")、连字符 ("-")、一个或两个字符和连字符 ("-"))的 4 或 5 个字符序列可以根据一个或两个字母编码各种字符:"s" 用于斜杠 ("/")、"p" 用于句点 (".")、"u" 用于下划线 ("_"),或者两个十六进制数字用于任何字节值(通常是 ASCII 数字,或者可能是 UTF-8 编码字符的一部分)。

不支持旧的监控操作(编辑、监视以及相关操作)。导出和标记(标签和分支)在此阶段不受支持。

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

scroll-to-top