Git
英语 ▾ 主题 ▾ 版本 2.44.0 ▾ 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

不要在 config 中检查 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>

    除了在 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 文件中,您不必担心总是设置正确的环境变量。受限于 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. 如果你没有在签出命令中直接指定 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,你必须用 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

支持的操作

支持正常使用所需的所有操作,包括检出、差异、状态、更新、日志、添加、删除、提交。

大多数读取 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 编码字符的一部分)。

不支持旧版监控操作(编辑、监视和相关操作)。此阶段不支持导出和标记(标记和分支)。

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