概述:
在学习计算机软件工程中,修订控制是跟踪和控制源代码更改的任何类型的实践。 对于软件开发人员有时会使用修订控制软件来维护文档和配置文件以及源代码。
当团队设计,开发和部署软件时,通常会将同一软件的多个版本部署在不同的站点中,并使软件开发人员同时处理更新。 软件的Bug或特征通常仅出现在某些版本中(因为某些问题的修复以及程序开发时引入的其他问题)。因此,出于定位和修复错误的目的,能够检索和运行不同版本的软件以确定问题发生在哪个版本中是至关重要的。可能还需要同时开发两个版本的软件:例如,一个版本修复了错误,但没有新功能(分支),而另一个版本是处理新功能(主体)的地方。
在最简单的层面上,开发人员可以简单地保留程序的不同版本的多个副本,并适当地标记它们。这种简单的方法已经在许多大型软件项目中使用。虽然这种方法可行,但由于必须维护许多几乎相同的程序副本,因此效率很低。这需要开发人员进行大量自律,并且经常会导致错误。由于代码库是相同的,它还需要向一组开发人员授予读写执行权限,这增加了管理权限的人员的压力,这样代码库就不会受到损害,这增加了更多的复杂性。因此,开发了一些自动化部分或全部修订控制过程的系统。这确保了版本控制步骤的大部分管理隐藏在幕后。
此外,在软件开发,法律和商业实践以及其他环境中,团队编辑单个文档或代码片段变得越来越普遍,团队成员可能在地理上分散,可能追求不同甚至相反的兴趣。 。在这种情况下,跟踪和说明文档和代码更改所有权的复杂版本控制可能非常有用甚至是必不可少的。
修订控制还可以跟踪配置文件的更改,例如通常存储在Unix系统中/etc
或/usr/local/etc
上的系统。这为系统管理员提供了另一种轻松跟踪所做更改的方法,以及在需要时回滚到早期版本的方法。
结构
版本控制管理一组数据随时间的变化。这些变化可以以各种方式构建。
通常,数据被视为许多单个项目(例如文件或文档)的集合,并且跟踪对单个文件的更改。这符合关于单独文件的直觉,但在身份更改时会导致问题,例如在重命名,拆分或合并文件期间。因此,某些系统会考虑整体更改数据,这对于简单更改而言不太直观,但可以简化更复杂的更改。
当修改受版本控制的数据时,在通过签出检索之后,这通常不会立即反映在修订控制系统中(在存储库中),而是必须检入或提交。修订控制之外的副本称为“工作副本”。举一个简单的例子,编辑计算机文件时,编辑程序存储在内存中的数据是工作副本,通过保存提交。具体地说,可以打印出文档,手动编辑,然后稍后手动将更改输入计算机并保存。对于源代码控制,工作副本是特定修订版中所有文件的副本,通常存储在开发人员的计算机本地;(注释1)在这种情况下,保存文件只会更改工作副本,并且检查存储库是一个单独的步骤。
如果多个人正在处理单个数据集或文档,则它们隐式地创建数据的分支(在其工作副本中),因此出现合并问题,如下所述。对于简单的协作文档编辑,可以通过使用文件锁定或简单地避免处理其他人正在处理的同一文档来防止这种情况。
修订控制系统通常是集中的,具有单个权威数据存储,存储库以及参考此中央存储库完成的检出和签入。或者,在分布式版本的控制,没有单个存储库具有权威性,可以检出数据并将其签入任何存储库。当检入不同的存储库时,这被解释为合并或补丁。
图结构
就图论而言,修订通常被认为是一条发展线(主干),其分支与此形成分支,形成一个有向树,可视化为一条或多条平行的发展线(分支的“主线”)分支离开后备箱。实际上,结构更复杂,形成有向无环图,但是出于许多目的,“具有合并的树”是足够的近似。
修订按时间顺序发生,因此可以按修订号或时间戳按顺序排列。(注释2)修订基于过去的修订,但可以在很大程度上或完全取代早期版本,例如“删除所有现有文本,插入新文本”。在最简单的情况下,没有分支或撤消,每个版本都基于其前一个版本,它们形成一个简单的行,具有单个最新版本,“HEAD”修订版或提示。在图论理论术语中,将每个修订版绘制为一个点,并将每个“派生修订版”关系绘制为箭头(通常指向从较旧到较新,与时间在同一方向),这是一个线性图。如果存在分支,那么多个未来的修订版基于过去的修订版或撤消版,因此修订版可能依赖于比其前一版本更旧的版本,然后生成的图形而不是有向树(每个节点可以有多个版本)孩子),并有多个提示,对应于没有孩子的修订(“每个分支的最新修订”)。(注释3)原则上,生成的树不需要首选提示(“主要”最新修订版) - 只是各种不同的修订版 - 但实际上,一个提示通常被标识为HEAD。当新修订版基于HEAD时,它或者被标识为新的HEAD,或者被认为是新的分支。(注4)从一开始到HEAD的修订列表(在图论中,树中的唯一路径,如前所述形成线性图)是主干或主线。相反,当修订版可以基于多个先前版本时(当一个节点可以有多个父版本时),生成的过程称为合并,并且是版本控制的最复杂方面之一。这种情况最常发生在多个分支发生变化时(通常是两个分支,但可能更多分支),然后将这些分支合并到包含这两个变化的单个分支中。如果这些更改重叠,则可能难以或不可能合并,并且需要手动干预或重写。
在存在合并的情况下,结果图不再是树,因为节点可以具有多个父节点,而是根节点有向环图(DAG)。该图是非循环的,因为父母总是在时间上倒退,并且因为有最旧的版本而生根。但是,假设有一个主干,来自分支的合并可以被认为是树的“外部” - 分支中的更改被打包为一个补丁,应用于HEAD(主干),创建一个新版本没有任何明确的分支引用,并保留树结构。因此,虽然版本之间的实际关系形成DAG,但这可以被认为是树加合并,并且主干本身是一条线。
在分布式版本控制中,在存在多个存储库的情况下,这些可能基于单个原始版本(树的根),但不需要原始根,因此每个存储库只有一个单独的根(最旧的版本)例如,如果两个人分别开始处理项目。类似地,在存在交换数据或合并的多个数据集(多个项目)的情况下,没有单个根,但为了简单起见,可以将一个项目视为主要项目而另一个项目作为次要项目,合并到第一个项目中有或没有它自己的修订历史。
专业策略
工程修订控制是从基于跟踪早期蓝图或蓝线修订的形式化过程开发的[ 需要引证 ]。对于在设计开发中达到工程死胡同的情况,该控制系统隐含地允许返回到设计的早期状态。修订表用于跟踪所做的更改。此外,使用修订云突出显示了图形的修改区域。
版本控制在商业和法律中很普遍。实际上,“合同红线”和“法律黑线”是最早的修订控制形式[3],并且仍然在商业和法律中使用,具有不同程度的复杂性。最复杂的技术开始用于电子跟踪CAD文件的变化(参见产品数据管理),取代传统版本控制的“手动”电子实现。[ 引证需要 ]