简体中文 ▾ 主题 ▾ 最新版本 ▾ 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-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 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 头名称

%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 检出”

  2. 创建新位置。有关如何选择正确协议的详细信息,请参阅下面的注意事项。

  3. 浏览可用的模块。它将为您提供仓库中头部的列表。您将无法从那里浏览树。只能浏览头部。

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

协议注意事项:如果您通过 pserver 使用匿名访问,只需选择它。使用 SSH 访问的用户应该选择 ext 协议,并在“首选项→团队→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 标签或修订号的 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] 套件的一部分

scroll-to-top