CVS 最佳实践

Vivek Venugopalan

修订历史
修订 0.72005-10-15修订者: vv
根据读者建议进行了一些小修复。
修订 0.62002-09-10修订者: vv
添加了与标签和每日构建相关的内容。将 Linuxdoc URL 更新为 tldp。修复了失效链接,并添加了读者建议的其他更正。
修订 0.52002-08-25修订者: vv
修复了文档中的更多错误,并添加了对其他 CVS 资源和一些服务器端脚本的引用
修订 0.42002-03-10修订者: vv
添加了新的电子邮件地址,添加了一个示例流程来展示这些实践如何提供帮助
修订 0.32001-12-06修订者: vv
语法错误清理
修订 0.22001-11-27修订者: vv
采纳了第一轮反馈以及一些小修复
修订 0.12001-11-20修订者: vv
创建

目录
1. 介绍
1.1. 版权信息
1.2. 免责声明
1.3. 新版本
1.4. 鸣谢
1.5. 反馈
2. 重点领域
3. 使用 GUI 工具
3.1. 使用 GUI CVS 客户端
4. 开发者沙箱
4.1. 保持系统时钟同步
4.2. 不要共享沙箱
4.3. 与代码仓库保持同步
4.4. 不要在沙箱外工作
4.5. 完成工作后清理
4.6. 经常检入
5. CVS 服务器配置
5.1. CVS 访问控制
5.2. 服务器端脚本
5.3. 服务器通知
6. 分支与合并
6.1. 为主干和分支分配所有者
6.2. 标记每个发布版本
6.3. 在每次发布后创建分支
6.4. 仅在分支上进行错误修复
6.5. 仅从分支进行补丁发布
7. 变更传播
7.1. 发布后将分支与主干合并
8. 软件构建
8.1. 尽早并经常构建 (BEBO)
8.2. 完全自动化构建过程
8.3. 所有必要文件必须在构建前检入
9. 在组织中将 CVS 制度化
9.1. 实施变更管理流程
9.2. 将 CVS 使用纳入目标
9.3. 收集 CVS 使用指标
10. 最佳实践实践
10.1. 初始阶段
10.2. 开发与交付
11. 结论
A. GNU 自由文档许可证
0. 序言
1. 适用性和定义
2. 逐字复制
3. 大量复制
4. 修改
5. 合并文档
6. 文档集合
7. 与独立作品的聚合
8. 翻译
9. 终止
10. 本许可证的未来修订
如何将本许可证用于您的文档

本文探讨了在软件项目中将 CVS 用作配置管理工具时可以采用的一些最佳实践。


1. 介绍

 

人 已 经 成 为 他 们 工 具 的 工 具。 

 
--亨利·大卫·梭罗 (1817-1862)  

本文概述了在软件项目中将并发版本系统用作配置管理工具时可以采用的一些最佳实践。

并发版本系统 (CVS) 是一种 开源 配置管理工具,现在正被许多商业组织认真考虑作为其他商业软件配置管理工具的可行替代方案。

对 CVS 的关注引发了一个不可避免的问题,即在大型软件开发项目中部署 CVS 作为骨干 SCM 工具的最佳实践。在多次口头回答这个问题,将其作为关于 CVS 的一系列 “陷阱” 之后,现在是将一些适用于基于 CVS 项目的最佳实践写在纸上的时候了。

Note

本文假设读者熟悉软件版本控制的基础知识,包括分支、合并、标记(标签)等现代版本控制工具(如 CVS)提供的功能。

此外,本文并非 CVS 及其用法的入门介绍。网上有许多关于此主题的优秀文章。本文假设读者熟悉 CVS 命令,并正在考虑在其组织中部署 CVS。以下是一些可以提供 CVS 教育的流行 CVS 相关链接。

  1. 并发版本系统站点,其中提供了关于 CVS 的最新信息,包括 CVS 手册

  2. Karl Fogel 的书籍 使用 CVS 进行开源开发 在线提供。


1.1. 版权信息

本文档版权归 � 2001 Vivek Venugopalan 所有。根据 GNU 自由文档许可证 1.1 版或自由软件基金会发布的任何后续版本的条款,允许复制、分发和/或修改本文档,无需不变章节、封面文本和封底文本。许可证副本可在 附录 A 中找到。

只要所有副本都保留此版权声明,本文档可以完整或部分地以任何物理或电子媒介复制和分发。允许并鼓励商业再分发;但是,作者希望收到任何此类分发的通知。

所有翻译、衍生作品或包含本文档的聚合作品都必须受此版权声明的约束。也就是说,您不得从本文档创作衍生作品并对其分发施加额外限制。在某些条件下可以批准对这些规则的例外情况;请通过以下地址联系作者。

简而言之,我们希望通过尽可能多的渠道传播此信息。但是,我们确实希望保留本文档的版权,并希望收到任何再分发计划的通知。


1.2. 免责声明

对于本文档的内容,我们不承担任何责任。使用本文档中的概念、示例和其他内容,风险自负。由于这是本文档的新版本,因此可能存在错误和不准确之处,这些错误和不准确之处当然可能会对您的系统造成损害。请谨慎操作,尽管这种情况极不可能发生,但作者不承担任何责任。

除非另有明确说明,否则所有版权均归其各自所有者所有。在本文档中使用术语不应被视为影响任何商标或服务标记的有效性。

特定产品或品牌的命名不应被视为认可。

强烈建议您在进行重大安装之前备份您的系统,并定期进行备份。


1.3. 新版本

本文档版本:0.7。

可以从以下位置获取本文档的最新版本(按最新版本可用性排序)

  1. 我的网站

  2. Linux 文档项目


1.4. 鸣谢

以下是不分先后顺序为此论文提供信息和更正的人员列表。

  1. Jens-Uwe Mager

  2. Jorgen Grahn

  3. Thomas S. Urban

  4. Cam Mayor

  5. Sally Miller

  6. Niels Jakob Darger


1.5. 反馈

非常欢迎您对本文档提供反馈。没有您的提交和投入,本文档将不会存在。请将您的添加、评论和批评发送至以下电子邮件地址.


2. 重点领域

最佳实践的重点领域是

  1. GUI 工具

  2. 开发者沙箱

  3. CVS 服务器配置

  4. 分支与合并

  5. 变更传播

  6. 软件构建

  7. 在组织中将 CVS 制度化


3. 使用 GUI 工具

CVS 提供的传统界面是命令行客户端。也涌现出许多可以与 CVS 服务器 “对话” 的 GUI 客户端应用程序。这些 GUI 客户端为 CVS 代码仓库提供了 “点击式” 界面。


3.1. 使用 GUI CVS 客户端

本文建议在组织中首次部署 CVS 时使用此类 GUI 客户端。

开发人员通常使用集成开发环境,这些环境将 CM 工具集成到其中。这些工具最大限度地减少了开发人员学习 CVS 使用复杂性的过程,而是让他们从第一天起就能高效工作。习惯于其他 CM 工具的开发人员会觉得 CVS 命令行界面令人生畏。通过使用 CVS 客户端的 GUI 工具,可以提高 CVS 的采用率和使用率。

CVS 的 GUI 工具可在 http://cvsgui.sourceforge.net/ 获取。GUI 界面适用于大多数流行的平台(Windows、Mac 和 Linux)。此外,在 Windows 平台上,有一个 SCC 扩展,允许将 CVS 集成到流行的 IDE 中作为配置控制工具。


4. 开发者沙箱

开发者 “沙箱” 是每个开发者保存其代码库工作副本的地方。在 CVS 中,这被称为工作目录。开发者在这里构建、测试和调试他们正在处理的模块。沙箱也可以是进行暂存构建或生产构建的区域。在工作区中所做的更改会被检入到 CVS 代码仓库。此外,代码仓库中其他人所做的更改必须定期在沙箱中更新。

与开发者沙箱相关的最佳实践是


4.1. 保持系统时钟同步

CVS 通过使用文件上的时间戳来跟踪对源文件的更改。如果每个客户端系统的日期和时间不同步,则 CVS 肯定有可能变得混乱。因此,必须使用中央时间服务器或类似机制使系统时钟保持同步。

CVS 从一开始就被设计为处理多个时区。只要主机操作系统已正确设置和配置,CVS 就能够正确跟踪更改。


4.2. 不要共享沙箱

沙箱对于每个开发者或目的都必须是唯一的。它们不应同时用于多种用途。沙箱可以是开发人员的工作区,也可以是最终版本的构建区。如果共享此类沙箱,则沙箱的所有者将不知道对文件所做的更改,从而导致混乱。

在 CVS 中,当使用 cvs checkout {项目名称} 命令为 CVS 项目检出工作副本时,会自动创建沙箱。

在非常大的项目中,开发者检出整个源代码到本地沙箱中是没有意义的。在这种情况下,他们可以定期从构建团队获取二进制文件,用于应用程序中所有未被他们更改的组件,并且仅检出由开发者构建的部分。

例如,在 Java 项目中,构建团队可以将他们上次成功构建的结果以 JAR 文件的形式保存在网络文件服务器上的标准位置。个人开发者将使用标准的类路径设置,该设置在标准路径上挂载了网络驱动器。因此,开发者将自动获取他们所需文件的最新版本。


4.3. 与代码仓库保持同步

为了获得在上述沙箱中工作的好处,开发者必须使其沙箱与主代码仓库保持同步。定期使用带有适当标签或分支名称的 cvs update 将确保沙箱保持最新状态。


4.4. 不要在沙箱外工作

沙箱可以被认为是 CVS 可以在其中跟踪对各种源文件所做更改的受控区域。属于其他开发者的文件将由 CVS 在开发者的沙箱中自动更新。因此,在沙箱中工作的开发者将获得并行开发的许多好处。


4.5. 完成工作后清理

确保在完成文件工作后清理沙箱。可以使用 cvs release 命令在 CVS 中完成清理。这确保了开发沙箱中不存在旧版本的文件。如前所述,可以使用构建团队预构建的二进制文件来确保应用程序的所有部分都可供开发者使用,而无需在沙箱中进行完整编译。


4.6. 经常检入

为了帮助其他开发者使其代码与您的代码保持同步,您必须经常将您的代码检入到 CVS 代码仓库。最佳实践是在一段代码完成、审查和测试后立即检入,使用 cvs commit 检入更改,以确保您的更改已提交到 CVS 代码仓库。

CVS 促进并行开发。只有当所有其他开发者定期了解正在进行的更改时,并行开发才有可能。这种意识可以称为 “情境意识”

Warning

常见的 “不良” 做法之一是通过电子邮件在开发者之间共享文件。这与上面提到的大多数最佳实践背道而驰。要在两个开发者之间共享更新,必须使用 CVS 作为通信媒介。这将确保 CVS “意识到” 更改并可以跟踪它们。因此,如果需要,可以建立审计跟踪。


5. CVS 服务器配置

本节介绍 CVS 服务器端设置和配置的最佳实践。


5.1. CVS 访问控制

我一直被问到的一个重要问题是,是否能够对 CVS 代码仓库内的文件/文件夹/分支等进行访问控制,以供各种用户使用。不幸的是,CVS 没有内置的访问控制功能,但它确实通过 CVSROOT 代码仓库中的 readers/writers 文件支持一种基本的访问控制形式。我整理了一组脚本,使用 readers/writers 文件来提供稍微可用的访问控制版本。这在 http://cvspermissions.sarovar.org 上作为一个开源项目提供。请随意使用它,并让我知道它对您有何作用。


5.2. 服务器端脚本

服务器端脚本是指在事件发生时使 CVS 服务器执行某些脚本的能力。一个有用的常见脚本是验证所有 cvs 提交都包含开发者输入的注释。该过程涉及设置CVSROOT/verifymsg文件,以便在检入文件时运行脚本。

------CVSROOT/verifymsg---------

#Set the verifymsg file to fire a script
DEFAULT /usr/local/bin/validate-cvs-log.sh


------/usr/local/bin/validate-cvs-log.sh ---------

#!/bin/sh
#
# validate-cvs-log.sh logfile
 
# test that log message has some characters in it
if [ `cat $1 | wc -c ` -lt 10 ] ; then
echo "log message too short; please enter a description for the changes"
    exit 1
else
    exit 0
fi

5.3. 服务器通知

可以将 CVS 服务器配置为在发生提交时通过电子邮件通知。这可以用于验证在每日/发布构建过程中是否正在发生提交。如果发生此类提交,则根据项目策略,可以忽略提交或自动重新启动整个构建。


6. 分支与合并

CVS 中的分支将项目的开发分为独立的并行历史记录。在一个分支上所做的更改不会影响其他分支。分支可以广泛用于维护产品的多个版本,以提供支持和新功能。

合并将分支汇聚回主干。在合并中,CVS 计算分支从与主干分叉的点到分支尖端(其最新状态)之间所做的更改,然后将这些差异应用于主干尖端的项目。


6.1. 为主干和分支分配所有者

源代码树的主干和各个分支应分配所有者,他们将负责:

  1. 维护分支或主干的可配置项列表。

    所有者将是分支或主干的内容列表的维护者。此列表应包含项目名称和关于该项目的简要描述。此列表至关重要,因为新的工件总是在不断地添加到代码仓库或从中删除。此列表将能够跟踪各个分支的代码仓库的新增/删除项。

  2. 建立分支或主干的工作策略。

    所有者将建立检入和检出策略。该策略将定义何时可以检入代码(编码后或审查后等)。谁负责合并同一文件上的更改并解决冲突(作者或最近更改文件的人)。

  3. 识别并记录策略偏差

    一旦建立策略,往往会有例外情况。所有者将负责识别解决方法并跟踪/记录相同的方法以供将来使用。

  4. 负责与主干合并

    分支所有者将负责确保分支中的更改可以在合理的时间点成功合并到主干中。


6.2. 标记每个发布版本

作为发布过程的一部分,必须使用标识符标记整个代码库,该标识符可以帮助唯一标识该版本。标签为一个开发人员的工作副本(通常,该工作副本是完全最新的,因此标签名称附加到代码仓库中的 “最新和最棒” 修订版本)所代表的修订集合提供标签。

标签的标识符应提供足够的信息,以便在未来的任何时间点标识该版本。建议的标签标识符形式如下。


release_{主版本号}_{次版本号}

Note

正如一位读者向我指出的那样,这里的一个好的做法是首先标记发布版本。使用标签检出整个代码库,然后在进行实际发布之前,继续完成构建/部署/测试过程。这将绝对确保 “出门” 的是经过验证和测试的代码库。


6.3. 在每次发布后创建分支

在每次软件发布之后,一旦 CVS 代码仓库被标记,就必须立即创建一个分支。此分支将用作该版本的错误修复基线。仅当该版本首先不是错误修复或补丁版本时,才创建此分支。将来任何时候必须为此版本制作的补丁都将在此分支上开发。主干将用于正在进行的产品开发。

通过这种安排,正在进行的开发的代码更改将在主干上进行,而分支将为热修复和错误修复版本提供单独的分区。

分支名称的标识符可以是以下形式。


release_{主版本号}_{次版本号}_patches


6.4. 仅在分支上进行错误修复

此实践从先前在主要版本发布后创建单独分支的实践延伸而来。该分支将用作所有错误修复和必须进行的补丁版本的代码库。因此,存在一个单独的代码仓库 “沙箱”,可以在其中独立于主流开发来开发热修复和补丁。

此实践还确保对以前版本进行的错误修复不会神秘地影响主流版本。此外,添加到主流版本的新功能不会意外地渗入到补丁版本中。


6.5. 仅从分支进行补丁发布

由于给定版本的所有错误修复都在其对应的分支上完成,因此补丁版本是从分支制作的。这确保了对作为补丁版本一部分发布的功能集没有混淆。

在制作补丁版本之后,必须使用发布版本标记实践标记分支(请参阅 标记每个发布版本)。


7. 变更传播

变更传播实践探讨了如何将对应用程序的一个版本所做的更改迁移到应用程序的其他活动版本。


7.1. 发布后将分支与主干合并

在每次从分支发布之后,对分支所做的更改应与主干合并。这确保了对补丁版本所做的所有错误修复都已正确纳入应用程序的未来版本中。

根据对主干和要合并的分支所做的更改量,此合并可能会非常耗时。实际上,它可能会导致 CVS 中出现大量冲突,从而导致手动合并。合并后,必须测试主干代码库以验证应用程序是否处于正常工作状态。在准备项目计划时必须牢记这一点。

如果分支上的更改持续很长时间,即使在发布版本制作之前,也可以定期将这些更改合并到主分支。合并频率基于分支演变中的某些逻辑点完成。为了确保不会发生重复合并,可以采用以下实践。

除了分支标签之外,还应创建一个名为 {分支名称}_MERGED 的标签。最初,这与分支的最后一个发布版本标签处于同一级别。然后通过使用 -F 选项在每次中间合并后 “移动” 此标签。这消除了中间合并期间的重复合并问题。


8. 软件构建

本节介绍软件构建的最佳实践。构建是为软件版本创建应用程序二进制文件的过程。它们由构建团队定期完成,以为日常工作提供基线二进制文件。


8.1. 尽早并经常构建 (BEBO)

这个格言的变体在开源社区中已经流传了一段时间,称为“尽早发布并经常发布”,尽管原因不同。BEBO 帮助开发团队识别可能因检入错误文件而引起的问题。BEBO 将解决应用程序级别的集成问题,这些问题可能已在单个开发者构建中被忽略。当团队看到应用程序的工作版本时,它也将提高团队士气。

必须定期进行构建。应分配专门的资源来执行相同操作。必须对整个项目团队进行培训,以将每日构建视为一项重要活动,而不是一项苦差事。必须定期完成构建,且不能出现任何失败。构建失败必须是罕见事件,应以最严肃的态度对待。项目团队应确保成功构建是他们的首要任务。可以通过设置打破构建的惩罚来强调其严肃性。

可以使用标准命名约定在 CVS 中标记每个构建。这可以帮助开发者从每日构建中检出一个完整的系统工作版本,以进行本地开发。


8.2. 完全自动化构建过程

软件构建的另一个关键实践是完全自动化构建过程。自动化过程还必须包括从 CVS 代码仓库自动检索正确的源文件。这确保了构建过程是完全可重复和一致的。此外,在很大程度上减少了使用错误版本的应用程序源文件进行构建的可能性。

通过自动化构建过程,经常构建的任务变得不那么繁重。


8.3. 所有必要文件必须在构建前检入

这个格言乍一看似乎微不足道,但即使是经验丰富的开发团队,由于疏忽,这个问题也很常见。疏忽问题不容易解决,因为责任在于个人开发者,以确保他的文件已检入。应以培训和构建前公告的形式向团队灌输这种实践,以确保代码仓库中提供正确版本的源代码。

如上所述的自动化构建过程将有助于在一定程度上发现此问题,因为它们将自动从 CVS 代码仓库获取源代码并执行软件构建。任何遗漏的项目都将在构建过程本身(makefile 等)或产品回归测试期间(检入的旧版本文件)浮出水面。

可以建立基于惩罚的系统来处理错误的检入。为项目结束后聚会设立一个 kitty,每个进行错误检入的人都将贡献固定金额,这将是一个很好的惩罚系统。


9. 在组织中将 CVS 制度化

在这里,我们将研究在组织中将 CVS 使用制度化的最佳实践。


9.1. 实施变更管理流程

所有组织都必须实施良好的变更管理流程 (CMP)。良好的 CMP 将定义如何接收、记录、跟踪、执行和交付变更。CVS 为您的项目提供版本控制。变更管理解决了如何接收、跟踪和关闭增强功能和错误问题的 “大局”。CVS 将在这个大局中发挥较小的但非常重要的作用。通过在组织中建立正式的变更管理流程,诸如 CVS 之类的工具将被视为辅助此流程,而不是充当一般的开发开销。

变更管理是一个非常广泛的主题,在此无法公正地介绍。请查找其他关于变更管理的信息来源。


9.2. 将 CVS 使用纳入目标

为了将 CVS 制度化,可以将其作为开发者在项目中绩效目标的一部分,即使用 CVS。此外,也可以将其作为项目经理在其项目中部署 CVS 的目标的一部分。

然后,可以将对此的遵守情况作为员工评估周期的一部分进行审查。


9.3. 收集 CVS 使用指标

可以收集 CVS 使用指标,例如在组织中的部署百分比、处理的项目规模等。此信息将促使其他部门经理和项目经理将 CVS 视为一种可以帮助他们日常运营的工具。


10. 最佳实践实践

解释这些最佳实践的需求的最佳方法是,整理一个真实世界项目场景的示例,并展示这些最佳实践将如何准确地融入 “大局”。此外,许多读者告诉我,关于 分支与合并变更传播 的章节将需要示例才能更好地解释。听取读者的意见是一件好事,因此我整理了一个特定的项目场景,然后创建一系列事件来展示如果遵循最佳实践,将如何帮助操作更顺畅。


10.1. 初始阶段

考虑一个软件项目,其中 1.0 版本刚刚投入生产,每个人都庆祝完毕。下一步是开始处理后续版本的新功能。此外,系统的用户已开始全职使用它,并且各种级别的错误报告已开始涌入。

在投入新的增强功能或错误修复之前,应遵循 分支与合并 的最佳实践。一些重要的实践是 标记每个发布版本在每次发布后创建分支。这些实践将有效地建立两个 “开发环境”,一个用于常规增强功能,另一个用于上次发布的错误修复和小增强功能。

让我们假设发布版本被标记为


release_1_0

然后使用分支名称创建分支


release_1_0_patches


10.2. 开发与交付

现在,我们准备开始工作了。让我们来检查一下缺陷修复和增强跟踪。假设有三个缺陷,其中两个是高优先级的,应该立即修复(可能在一周内),第三个可以在稍后交付(比如 4 周后)。在这个时间表的中间,计划在三周后进行一次常规发布。考虑到我们接下来会有一个繁忙的月份,让我们看看如何才能准确地使用最佳实践来轻松度过接下来的日子。

下个月各种发布的计划时间表如下所示。

             Fix       Enhancement  Fix 
     Today   Release 1  Release    Release 2
	 |_______|______________|_________|
		    Time -->

我们有两个团队,一个团队在缺陷修复分支上工作,另一个团队在主干上为下一个版本开发新功能。这些团队必须确保他们从沙箱中的正确版本开始工作。

  1. 缺陷修复团队将使用命令行检出代码

    cvs checkout -R -r release_1_0_patches {项目名称}

  2. 从事下一个版本开发的团队将使用命令行

    cvs checkout -R {项目名称}

一旦缺陷修复团队完成了两个最高优先级的缺陷,他们将更新、验证构建成功,并将他们的更改提交到缺陷修复分支,使用命令行

cvs update -R -r release_1_0_patches {模块名称}

团队应该在此处执行构建,以验证更新是否没有破坏分支上的任何代码。一旦构建成功,分支应该被提交回代码仓库。

cvs commit -R -r release_1_0_patches {模块名称}

尽早构建,频繁构建 : 每天,每个开发人员都会向 CVS 提交代码,为了确保代码的健全性,缺陷修复分支上将进行每日构建,方法是从干净的环境中从 CVS 检出代码并完全重建。这些每日构建可以使用以下命名约定在 CVS 中标记


build_1_1_yyyymmdd : 用于分支
build_2_0_yyyymmdd : 用于主干

遵循构建-测试-修复的常规流程,使版本准备好交付。标签将帮助开发人员在必要时检出最新构建的工作副本。

当源代码发布到外部世界时,必须遵循两个实践。

  1. 标记每个发布版本 : 这确保了缺陷修复版本被正确标记,因此可以在以后必要时追溯出来。

  2. 在发布后将分支与主干合并 : 这确保了缺陷修复被合并回主干,从而确保所有未来的发布都是真正的累积交付。


11. 结论

这些最佳实践旨在帮助软件团队在使用 CVS 进行开发时取得先机。这里提出的想法必须不断审查和发展。我希望这是一个不断增长和发展的文档。请将您的意见和建议发送至


A. GNU 自由文档许可证

版本 1.1,2000 年 3 月

版权 (C) 2000 自由软件基金会有限公司,地址:59 Temple Place, Suite 330, Boston, MA 02111-1307 USA。允许任何人复制和分发本许可证文档的完整副本,但不允许更改它。


0. 序言

本许可证的目的是使手册、教科书或其他书面文档在“自由”的意义上是“自由的”:确保每个人都拥有复制和再分发它的有效自由,无论是否修改它,无论是商业用途还是非商业用途。其次,本许可证为作者和出版商保留了一种获得作品荣誉的方式,同时不被视为对他人所做的修改负责。

本许可证是一种“著作权保留”,这意味着文档的衍生作品本身也必须是相同意义上的自由。它补充了 GNU 通用公共许可证,后者是为自由软件设计的著作权保留许可证。

我们设计本许可证是为了将其用于自由软件的手册,因为自由软件需要自由文档:一个自由程序应该附带提供与软件相同自由的手册。但是本许可证不限于软件手册;它可以用于任何文本作品,无论主题是什么,也无论它是否以印刷书籍形式出版。我们主要推荐本许可证用于以教学或参考为目的的作品。


1. 适用性和定义

本许可证适用于任何手册或其他作品,其中包含版权持有人放置的声明,表明它可以根据本许可证的条款分发。下文中的“文档”是指任何此类手册或作品。任何公众成员都是被许可人,并被称为“您”。

文档的“修改版本”是指任何包含文档或其一部分的作品,无论是逐字复制,还是经过修改和/或翻译成另一种语言。

“次要章节”是文档的已命名的附录或前言章节,它专门处理文档的出版商或作者与文档的整体主题(或相关事项)的关系,并且不包含任何可以直接归入该整体主题的内容。(例如,如果文档部分是数学教科书,则次要章节可能不解释任何数学。)这种关系可能是与主题或相关事项的历史联系,或者是关于它们的法律、商业、哲学、伦理或政治立场。

“不变章节”是某些次要章节,其标题在声明文档根据本许可证发布的通知中被指定为不变章节的标题。

“封面文字”是在声明文档根据本许可证发布的通知中列出的某些简短文本段落,作为封面文字或封底文字。

文档的“透明”副本是指机器可读的副本,以规范可供公众使用的格式表示,其内容可以使用通用文本编辑器或(对于像素组成的图像)通用绘图程序或(对于绘图)一些广泛可用的绘图编辑器直接且直接地查看和编辑,并且适合输入到文本格式化程序或自动翻译成各种适合输入到文本格式化程序的格式。以其他透明文件格式制作的副本,其标记旨在阻止或劝阻读者随后进行修改,则不是透明的。不是“透明”的副本称为“不透明”。

透明副本的合适格式示例包括没有标记的纯 ASCII、Texinfo 输入格式、LaTeX 输入格式、使用公开可用的 DTD 的 SGML 或 XML,以及为人工修改而设计的符合标准的简单 HTML。不透明格式包括 PostScript、PDF、只能由专有文字处理器读取和编辑的专有格式、DTD 和/或处理工具通常不可用的 SGML 或 XML,以及某些文字处理器仅为输出目的而生成的机器生成的 HTML。

“标题页”对于印刷书籍而言,是指标题页本身,以及为清晰地容纳本许可证要求在标题页中出现的材料所需的后续页面。对于没有标题页格式的作品,“标题页”是指作品标题最突出的外观附近的文本,位于正文开始之前。


2. 完整复制

您可以在任何媒介中复制和分发文档,无论是商业用途还是非商业用途,前提是本许可证、版权声明和声明本许可证适用于文档的许可证声明在所有副本中都得到复制,并且您不对本许可证的条款添加任何其他条件。您不得使用技术措施来阻止或控制您制作或分发的副本的阅读或进一步复制。但是,您可以接受报酬以换取副本。如果您分发足够大量的副本,您还必须遵守第 3 节中的条件。

您也可以在上述相同条件下借出副本,并且您可以公开展示副本。


3. 大量复制

如果您出版印刷文档副本数量超过 100 份,并且文档的许可证声明要求封面文字,则您必须将副本装在封皮中,封皮上清晰且清晰地携带所有这些封面文字:封面上的封面文字和封底上的封底文字。两个封面还必须清晰且清晰地表明您是这些副本的出版商。封面必须使用标题的所有单词以同等突出和可见的方式呈现完整标题。您可以在封面上额外添加其他材料。仅限于封面的更改的复制,只要它们保留文档的标题并满足这些条件,在其他方面可以被视为完整复制。

如果任一封面的所需文本量太大而无法清晰地容纳,您应该将列出的第一个(尽可能多地合理容纳)放在实际封面上,并将其余部分继续到相邻页面。

如果您出版或分发数量超过 100 份的不透明文档副本,您必须在每个不透明副本中包含机器可读的透明副本,或者在每个不透明副本中或随附声明一个公众可访问的计算机网络位置,其中包含文档的完整透明副本,没有添加材料,一般网络用户公众可以使用公共标准网络协议免费匿名下载访问。如果您使用后一种选择,您必须在您开始大量分发不透明副本时采取合理谨慎的步骤,以确保此透明副本将保持在声明的位置可访问,至少在您最后一次分发不透明副本(直接或通过您的代理商或零售商)向公众发行的该版本后一年。

请求但非必需的是,您在重新分发大量副本之前与文档作者联系,以便让他们有机会为您提供文档的更新版本。


4. 修改

您可以根据上述第 2 节和第 3 节的条件复制和分发文档的修改版本,前提是您根据本许可证精确发布修改版本,其中修改版本充当文档的角色,从而向拥有其副本的任何人授予修改版本的发行和修改许可。此外,您必须在修改版本中执行以下操作

  1. 在标题页(以及封面,如果有)中使用与文档标题不同的标题,以及与以前版本(如果有)不同的标题(以前的版本应列在文档的历史记录部分中)。如果该版本的原始出版商给予许可,您可以使用与以前版本相同的标题。

  2. 在标题页上,列出作为作者的一个或多个人或实体,负责修改版本中修改的作者身份,以及文档的至少五位主要作者(如果少于五位,则为其所有主要作者)。

  3. 在标题页上声明修改版本的出版商名称,作为出版商。

  4. 保留文档的所有版权声明。

  5. 在其他版权声明旁边为您的修改添加适当的版权声明。

  6. 在版权声明之后立即包含一个许可证声明,允许公众根据本许可证的条款使用修改版本,如下文附录所示的形式。

  7. 在该许可证声明中保留文档许可证声明中给出的不变章节和所需封面文字的完整列表。

  8. 包含本许可证的未更改副本。

  9. 保留标题为“历史”的章节及其标题,并向其添加一个项目,至少说明标题页上给出的修改版本的标题、年份、新作者和出版商。如果文档中没有标题为“历史”的章节,则创建一个章节,说明标题页上给出的文档的标题、年份、作者和出版商,然后添加一个项目,描述修改版本,如前一句所述。

  10. 保留文档中给出的任何网络位置,用于公众访问文档的透明副本,以及文档中给出的基于它的以前版本的网络位置。这些可以放在“历史”部分。您可以省略在文档本身至少四年前发布的作品的网络位置,或者如果它引用的版本的原始出版商给予许可。

  11. 在任何标题为“致谢”或“献词”的章节中,保留该章节的标题,并在该章节中保留其中给出的每个贡献者致谢和/或献词的所有实质和语气。

  12. 保留文档的所有不变章节,在其文本和标题中均未更改。节号或等效内容不被视为节标题的一部分。

  13. 删除任何标题为“背书”的章节。此类章节可能不包含在修改版本中。

  14. 不要将任何现有章节重新命名为“背书”或与任何不变章节的标题冲突。

如果修改版本包含符合次要章节条件的新前言章节或附录,并且不包含从文档复制的任何材料,您可以选择将这些章节中的部分或全部指定为不变的。为此,请将它们的标题添加到修改版本的许可证声明中的不变章节列表中。这些标题必须与任何其他章节标题不同。

您可以添加一个标题为“背书”的章节,前提是它只包含各方对您的修改版本的背书——例如,同行评审声明或文本已被组织批准为标准的权威定义。

您可以在修改版本的封面文字列表末尾添加最多五个单词的封面文字段落,以及最多 25 个单词的封底文字段落。任何一个实体只能添加一个封面文字段落和一个封底文字段落(或通过安排)。如果文档已经包含同一封面的封面文字,以前由您添加或由您代表的同一实体安排添加,您可能不会添加另一个;但您可以替换旧的,前提是获得添加旧的旧出版商的明确许可。

文档的作者和出版商在本许可证中不授予使用其姓名进行宣传或声明或暗示对任何修改版本的认可的许可。


5. 合并文档

您可以将文档与根据本许可证发布的其他文档合并,根据上述第 4 节中为修改版本定义的条款,前提是您在组合中包含所有原始文档的所有不变章节,未修改,并在其许可证声明中将它们全部列为您的组合作品的不变章节。

组合作品只需要包含本许可证的一个副本,多个相同的不变章节可以用单个副本替换。如果有多个同名但内容不同的不变章节,请通过在其末尾添加(在括号中)该章节的原始作者或出版商的姓名(如果已知),或者添加唯一编号,使每个此类章节的标题唯一。对组合作品的许可证声明中不变章节列表中的章节标题进行相同的调整。

在组合中,您必须合并各种原始文档中任何标题为“历史”的章节,形成一个标题为“历史”的章节;同样合并任何标题为“致谢”的章节,以及任何标题为“献词”的章节。您必须删除所有标题为“背书”的章节。


6. 文档集合

您可以创建一个集合,其中包含文档和根据本许可证发布的其他文档,并用集合中包含的单个副本替换各种文档中本许可证的各个副本,前提是您在所有其他方面都遵循本许可证关于每个文档的完整复制的规则。

您可以从这样的集合中提取单个文档,并根据本许可证单独分发它,前提是您将本许可证的副本插入到提取的文档中,并在所有其他方面都遵循本许可证关于该文档的完整复制。


7. 与独立作品的聚合

文档或其衍生作品与其他单独且独立的文档或作品的汇编,在存储或分发介质的卷中或之上,整体上不计为文档的修改版本,前提是没有为汇编声明汇编版权。此类汇编称为“聚合”,并且本许可证不适用于因此与文档汇编的其他自包含作品,因为它们因此被汇编,如果它们本身不是文档的衍生作品。

如果第 3 节的封面文字要求适用于这些文档副本,那么如果文档小于整个聚合的四分之一,则文档的封面文字可以放在仅围绕聚合体中文档的封面上。否则它们必须出现在围绕整个聚合体的封面上。


8. 翻译

翻译被认为是修改的一种,因此您可以根据第 4 节的条款分发文档的翻译。用翻译替换不变章节需要其版权持有人的特殊许可,但除了这些不变章节的原始版本外,您还可以包含部分或全部不变章节的翻译。您可以包含本许可证的翻译,前提是您也包含本许可证的原始英文版本。如果翻译和本许可证的原始英文版本之间存在分歧,则以原始英文版本为准。


9. 终止

除本许可证明确规定的情况外,您不得复制、修改、再许可或分发文档。任何其他复制、修改、再许可或分发文档的尝试均无效,并将自动终止您在本许可证下的权利。但是,根据本许可证从您那里收到副本或权利的当事方,只要这些当事方保持完全遵守,其许可证就不会终止。


10. 本许可证的未来修订

自由软件基金会可能会不时发布 GNU 自由文档许可证的新修订版本。此类新版本在精神上与当前版本相似,但在细节上可能有所不同,以解决新问题或疑虑。请参阅 https://gnu.ac.cn/copyleft/

本许可证的每个版本都给出了一个区分版本号。如果文档指定本许可证的特定编号版本“或任何更高版本”适用于它,您可以选择遵循该指定版本的条款和条件,或自由软件基金会已发布的任何更高版本(非草案)的条款和条件。如果文档未指定本许可证的版本号,您可以选择自由软件基金会发布的任何版本(非草案)。


如何将本许可证用于您的文档

要在您编写的文档中使用本许可证,请在文档中包含本许可证的副本,并将以下版权和许可证声明放在标题页之后

版权所有 (c) 年份 您的姓名。授予根据 GNU 自由文档许可证 1.1 版或自由软件基金会发布的任何更高版本的条款复制、分发和/或修改本文档的许可;不变章节为 列出它们的标题,封面文字为 列出,封底文字为 列出。许可证的副本包含在标题为“GNU 自由文档许可证”的章节中。

如果您没有不变章节,请写“没有不变章节”而不是说哪些是不变的。如果您没有封面文字,请写“没有封面文字”而不是“封面文字为 列出”;封底文字也一样。

如果您的文档包含程序代码的非平凡示例,我们建议并行地在您选择的自由软件许可证(例如 GNU 通用公共许可证)下发布这些示例,以允许它们在自由软件中使用。