跳转到内容

软件工程/工具/源代码控制简介

来自维基教科书,开放世界中的开放书籍
版本控制项目的示例历史树。

版本控制,也称为版本控制源代码控制(以及软件配置管理或SCM的一个方面),是对存储为计算机文件的文档、程序和其他信息更改的管理。它最常用于软件开发,其中一个团队的人员可能会更改相同的文件。更改通常由一个数字或字母代码标识,称为“版本号”、“版本级别”或简称“版本”。例如,一组初始文件是“版本 1”。当进行第一次更改时,结果集是“版本 2”,依此类推。每次修订都与时间戳和进行更改的人员相关联。修订可以进行比较、恢复,并且在某些类型的文件的情况下可以进行合并。

版本控制系统(VCS – 单数 VCS)最常作为独立应用程序运行,但版本控制也嵌入在各种类型的软件中,例如文字处理器(例如,Microsoft Word、OpenOffice.org Writer、KWord、Pages 等)、电子表格(例如,Microsoft Excel、OpenOffice.org Calc、KSpread、Numbers 等)以及各种内容管理系统(例如,Drupal、Joomla、WordPress)。集成版本控制是维基软件包(如 MediaWiki、DokuWiki、TWiki 等)的关键功能。在维基中,版本控制允许将页面恢复到以前版本,这对于允许编辑者跟踪彼此的编辑、更正错误以及保护公共维基免受破坏和垃圾邮件至关重要。

版本控制软件工具对于组织多开发人员项目至关重要。[1]

概述

[edit | edit source]

版本控制源于基于早期蓝图或蓝线的修订跟踪的正式流程。这种控制系统隐式地允许返回到设计的任何早期状态,以防在设计开发过程中遇到工程死胡同。同样,在计算机软件工程中,版本控制是任何跟踪和控制源代码更改的实践。软件开发人员有时使用版本控制软件来维护文档和配置文件以及源代码。此外,版本控制在商业和法律领域也十分普遍。“合同红线”和“法律黑线”是版本控制的最早形式之一,[需要引用]并且仍在不同程度的复杂性中使用。整个行业已经出现,以满足商业和其他用户的文档版本控制需求,并且这些领域中使用的一些版本控制技术是微妙、强大和创新的。最复杂的技术开始用于电子跟踪 CAD 文件的更改(参见产品数据管理),取代了传统版本控制的“手动”电子实现。

随着团队设计、开发和部署软件,同一个软件的多个版本经常部署在不同的站点,并且软件的开发人员可能同时进行更新。软件的错误或功能通常只存在于某些版本中(因为随着程序的开发,一些问题被修复,而另一些问题被引入)。因此,为了定位和修复错误,能够检索和运行软件的不同版本以确定问题发生在哪些版本中至关重要。可能还需要同时开发两个版本的软件(例如,一个版本修复了错误,但没有新功能(分支),而另一个版本是开发新功能的地方(主干)。

在最简单的层面上,开发人员可以简单地保留程序不同版本的多个副本,并对其进行适当的标记。这种简单的方法已用于许多大型软件项目。虽然这种方法可以工作,但它效率低下,因为必须维护程序的许多几乎相同的副本。这需要开发人员付出很多自律,并且经常导致错误。因此,已经开发出用于自动化部分或全部版本控制流程的系统。

此外,在软件开发、法律和商业实践以及其他环境中,一个团队对单个文档或代码片段进行编辑变得越来越普遍,团队成员可能分散在地域上,并且可能追求不同甚至相反的利益。在这些情况下,跟踪和记录文档和代码更改的所有权的复杂版本控制可能非常有用甚至必要。

版本控制还可以跟踪对配置文件的更改,例如通常存储在 Unix 系统上的/etc/usr/local/etc中的配置文件。这为系统管理员提供了一种轻松跟踪所做更改的方法,以及在需要时回滚到早期版本的方法。

源代码管理模型

[edit | edit source]

传统的版本控制系统使用集中式模型,所有版本控制功能都在共享服务器上进行。如果两个开发人员尝试同时更改同一个文件,如果没有某种方法来管理访问权限,开发人员最终可能会覆盖彼此的工作。集中式版本控制系统通过两种不同的“源代码管理模型”之一来解决此问题:文件锁定和版本合并。

原子操作

[edit | edit source]

计算机科学家谈到原子操作,如果即使操作被中断,系统也处于一致状态。从这个意义上说,提交操作通常是最关键的。提交是告诉版本控制系统您要将您一直在进行的一组更改最终确定并提供给所有用户的操作。并非所有版本控制系统都有原子提交;值得注意的是,广泛使用的 CVS 缺少此功能。

文件锁定

[edit | edit source]

防止“并发访问”问题的最简单方法是锁定文件,以便一次只有一个开发人员可以写入这些文件的中央“存储库”副本。一旦一个开发人员“检出”一个文件,其他人可以读取该文件,但没有人可以更改该文件,直到该开发人员“检入”更新的版本(或取消检出)。

文件锁定既有优点也有缺点。当用户对大型文件(或一组文件)的许多部分进行根本性更改时,它可以提供一些防止难以合并冲突的保护。但是,如果文件被长期独占锁定,其他开发人员可能会想绕过版本控制软件并在本地更改文件,从而导致更严重的问题。

实验

版本合并

[edit | edit source]

大多数版本控制系统允许多个开发人员同时编辑同一个文件。第一个“检入”对中央存储库更改的开发人员始终成功。系统可以提供将进一步的更改合并到中央存储库的功能,并在其他开发人员检入时保留第一个开发人员的更改。

合并两个文件可能是一个非常微妙的操作,通常只有在数据结构简单的情况下才有可能,例如文本文件。合并两个图像文件的结果可能根本不会生成图像文件。第二个检查代码的开发人员需要小心合并,以确保更改兼容,并且合并操作不会在文件内部引入自己的逻辑错误。这些问题限制了自动或半自动合并操作的可用性,主要限于简单的基于文本的文档,除非该文件类型有特定的合并插件可用。

保留编辑的概念可以提供一种可选的方法,即使在存在合并功能的情况下,也可以明确地锁定文件以供独占写入访问。

基线、标签和标记

[编辑 | 编辑源代码]

大多数版本控制工具只使用这些类似术语之一(基线、标签、标记)来指代标识快照(“标记项目”)或快照记录(“使用基线X尝试它”)的操作。通常在文档或讨论中只使用基线标签标记术语之一[需要引用];它们可以被认为是同义词。

在大多数项目中,一些快照比其他快照更重要,例如那些用于指示发布版本、分支或里程碑的快照。

基线术语与标签标记中的任何一个同时使用时,标签标记通常指代工具中标识或创建快照记录的机制,而基线则表示任何给定标签或标记的重要意义。

大多数关于配置管理的正式讨论都使用基线术语。

分布式版本控制

[编辑 | 编辑源代码]

分布式版本控制 (DRCS) 采用点对点方法,而不是集中式系统的客户端-服务器方法。每个对等方的工作副本不是与单个集中式存储库同步的客户端,而是代码库的真正存储库。[2] 分布式版本控制通过在对等方之间交换补丁(变更集)来进行同步。这导致了一些与集中式系统的重要区别

  • 默认情况下,不存在规范的代码库参考副本;只有工作副本。
  • 常见操作(如提交、查看历史记录和恢复更改)速度很快,因为不需要与中央服务器通信。[3]

相反,只有在将更改推送到其他对等方或从其他对等方拉取更改时才需要通信。

  • 每个工作副本实际上都充当代码库及其更改历史记录的远程备份,从而提供了针对数据丢失的自然保护。[3]

一些更高级的版本控制工具提供了许多其他功能,允许与其他工具和软件工程流程更深入地集成。通常有针对 Oracle JDeveloper、IntelliJ IDEA、Eclipse 和 Visual Studio 等 IDE 的插件可用。NetBeans IDE 和 Xcode 带有集成的版本控制支持。

通用词汇

[编辑 | 编辑源代码]

术语可能因系统而异,但一些常用术语包括:[4][5]

基线
文档或源文件的已批准修订,可以从中进行后续更改。请参阅基线、标签和标记。
分支
在版本控制下的文件集可以在某个时间点被分支分叉,以便从该时间点起,这两个文件的副本可以以不同的速度或以不同的方式独立于彼此地发展。
更改
更改(或差异增量)表示对版本控制下的文档的特定修改。被视为更改的修改的粒度在版本控制系统之间有所不同。
变更列表
在许多具有原子多更改提交的版本控制系统中,变更列表变更集补丁标识在单个提交中进行的一组更改。这也可以表示源代码的顺序视图,允许检查“截至”任何特定变更列表 ID 的源代码。
检出
检出(或co)是从存储库创建本地工作副本的行为。用户可以指定特定修订版或获取最新修订版。术语“检出”也可以用作名词来描述工作副本。
提交
提交签入ci或更罕见的是安装提交记录)是将工作副本中所做的更改写入或合并回存储库的操作。术语“提交”和“签入”也可以用作名词来描述作为提交结果而创建的新修订版。
冲突
当不同的参与者对同一个文档进行更改时,并且系统无法协调这些更改时,就会发生冲突。用户必须通过合并更改或选择一个更改以支持另一个更改来解决冲突。
增量压缩
大多数版本控制软件使用增量压缩,它只保留文件连续版本之间的差异。这允许更有效地存储文件的许多不同版本。
动态流
某些或所有文件版本是父流版本镜像的流。
导出
导出是从存储库获取文件的行为。它类似于检出,但它创建一个干净的目录树,没有工作副本中使用的版本控制元数据。例如,这通常在发布内容之前使用。
头部
有时也称为顶端,它指的是最新的提交。
导入
导入是将本地目录树(当前不是工作副本)首次复制到存储库中的行为。
标签
请参阅标记
主线
类似于主干,但每个分支都可以有一个主线。
合并
合并集成是将两组更改应用于文件或一组文件的操作。以下是一些示例场景
  • 用户在处理一组文件时,更新同步其工作副本,以获取其他用户所做的更改并签入到存储库中。[6]
  • 用户尝试签入自文件被检出以来被其他人更新的文件,并且版本控制软件自动合并这些文件(通常,在提示用户是否应继续进行自动合并后,并且在某些情况下,只有在合并能够清晰且合理地解决时才这样做)。
  • 一组文件被分支,在分支之前存在的问题在一个分支中得到修复,然后将修复合并到另一个分支中。
  • 创建一个分支,对文件中的代码进行独立编辑,然后将更新的分支合并到一个统一的主干中。
提升
将文件内容从控制程度较低的 location 复制到控制程度较高的 location 的行为。例如,从用户的 workspace 复制到存储库,或从一个流复制到其父流。[7]
存储库
存储库是存储文件当前和历史数据的位置,通常位于服务器上。有时也称为(例如,由 SVK、AccuRev 和 Perforce 称谓)。
解决
用户干预以解决对同一个文档的不同更改之间的冲突的行为。
反向集成
将不同的团队分支合并到版本控制系统主干的过程。
修订版
也称为版本:版本是形式的任何更改。在 SVK 中,修订版是指存储库中整个树在某个时间点的状态。
[需要引用] 请参阅标记
共享
使一个文件或文件夹同时在多个分支中可用的行为。当在某个分支中更改共享文件时,它也会在其他分支中更改。
一个用于分支文件的容器,它与其他此类容器有已知的关联。流形成一个层次结构;每个流都可以从其父流继承各种属性(如版本、命名空间、工作流规则、订阅者等)。
标签
一个标签标记指的是时间上的一个重要快照,在许多文件之间保持一致。这些文件在那个时间点可能会被标记上一个用户友好的、有意义的名称或修订号。请参见基线、标签和标记。
主干
唯一的开发路线,不是分支(有时也称为基线或主线)。
更新
一个更新(或同步)将存储库中所做的更改(例如,由其他人完成)合并到本地工作副本中。[6]
工作副本
工作副本是存储库中文件的本地副本,在特定时间或修订版。对存储库中文件的所有工作最初都在工作副本上进行,因此得名。从概念上讲,它是一个沙箱

参考资料

[edit | edit source]
  1. "Subversion 迅速采用验证了企业就绪并挑战了传统软件配置管理领导者". Collabnet. 2007 年 5 月 15 日. 检索于 2010 年 10 月 27 日. 版本管理对于软件开发至关重要,被认为是任何开发环境中最关键的组件。
  2. Wheeler, David. "关于开源软件/自由软件(OSS/FS)软件配置管理(SCM)系统的评论". 检索于 2007 年 5 月 8 日.
  3. a b O'Sullivan, Bryan. "使用 Mercurial 进行分布式版本控制". 检索于 2007 年 7 月 13 日.
  4. Collins-Sussman, Ben (2004). 使用 Subversion 进行版本控制. O'Reilly. ISBN 0-596-00448-6. {{cite book}}: Unknown parameter |coauthors= ignored (|author= suggested) (help)
  5. Wingerd, Laura (2005). Perforce 实践. O'Reilly. ISBN 0-596-10185-6.
  6. a b Collins-Sussman, Ben. "使用 Subversion 进行版本控制". 检索于 2010 年 6 月 8 日. G 代表合并,这意味着该文件最初有本地更改,但来自存储库的更改没有与本地更改重叠。 {{cite web}}: Unknown parameter |coauthors= ignored (|author= suggested) (help)
  7. Accurev 概念手册,版本 4.7. Accurev, Inc. 2008 年 7 月。 {{cite book}}: Check date values in: |date= (help)
[edit | edit source]
华夏公益教科书