版本控制(Version Control),也称为源代码控制(Source Control),是指对软件代码的变更进行跟踪和管理的实践。版本控制系统(Version Control Systems, VCS)是一类软件工具,帮助开发团队随时间推移有效地管理源代码的变更。随着开发环境不断加速,版本控制系统使软件团队能够更快、更智能地工作。对于 DevOps 团队而言尤其有用,因为它们有助于缩短开发周期并提高部署成功率。
版本控制软件会将代码的每一次修改记录在一个特殊的数据库中。如果出现错误,开发者可以“回滚时间”,对比早期版本的代码,从而在最小化对团队其他成员干扰的前提下修复问题。
对于几乎所有软件项目来说,源代码就如同皇冠上的宝石——是一项必须加以保护的宝贵资产。对大多数软件团队而言,源代码凝聚了开发者通过细致努力积累和提炼出的关于问题领域的无价知识与理解。版本控制既能防范灾难性事故,也能防止因人为疏忽或意外后果导致的代码质量退化。
在团队协作中,软件开发者持续编写新代码并修改已有代码。一个项目、应用程序或软件组件的代码通常组织成文件夹结构(即“文件树”)。例如,一位开发者可能正在开发新功能,而另一位则在修复一个不相关的 bug,各自可能在文件树的不同位置进行修改。
版本控制能帮助团队解决这类问题:它追踪每位贡献者的每一项更改,并防止并发工作产生冲突。同时进行的修改可能会彼此不兼容,这类问题应当以有序的方式被发现和解决,而不应阻碍团队其他成员的工作进度。此外,在所有软件开发过程中,任何更改都可能引入新的 bug,因此新代码在经过充分测试前是不可信的。所以,测试与开发通常是同步进行的,直到新版本准备就绪。
优秀的版本控制软件支持开发者偏好的工作流程,而不会强制规定某种特定的工作方式。理想情况下,它还应能在任意平台上运行,而不是限定开发者必须使用某种操作系统或工具链。出色的版本控制系统促进代码变更的顺畅、持续流动,避免采用笨拙且令人沮丧的文件锁定机制——即只允许一名开发者操作,却阻塞其他人的进展。
未使用任何形式版本控制的软件团队常常会遇到各种问题,例如无法确定哪些更改已交付给用户,或者两个互不相关的修改产生了不兼容的变更,之后不得不费力地拆解并重新整合。如果你是一名从未使用过版本控制的开发者,你可能曾给文件加上诸如 “final” 或 “latest” 的后缀来标识版本,随后又不得不面对“最终版的最终版”。你也可能曾注释掉某些代码块,仅仅是为了暂时禁用功能而不删除代码,担心将来或许还会用到。版本控制正是解决这些问题的有效途径。
如今,版本控制软件已成为现代软件团队日常专业实践中不可或缺的一部分。习惯于在团队中使用强大版本控制系统的独立开发者,通常也会意识到即使在小型个人项目中,版本控制同样具有巨大价值。一旦体验过版本控制系统带来的强大优势,许多开发者甚至在非软件项目中也不愿再脱离它。
版本控制系统的优势
使用版本控制软件是高性能软件团队和 DevOps 团队的最佳实践。它不仅帮助开发者加快开发速度,还能在团队规模扩大、成员增多时,保持开发效率与敏捷性。
过去几十年中,版本控制系统(VCS)取得了长足进步,不同系统各有优劣。VCS 有时也被称为 SCM(Source Code Management,源代码管理)工具或 RCS(Revision Control System,修订控制系统)。目前最流行的 VCS 工具之一是 Git。Git 属于分布式版本控制系统(Distributed VCS,简称 DVCS)。与当今许多主流 VCS 系统一样,Git 是免费且开源的。
无论这些工具叫什么名字,或使用哪一种系统,你都应期望从版本控制中获得以下核心优势:
1. 完整的长期变更历史
每个文件的完整历史记录,包括多年来由众多开发者所做的所有更改——不仅包含内容编辑,还包括文件的创建与删除。不同 VCS 工具在处理文件重命名和移动方面的能力有所不同。该历史记录还应包含作者、日期以及每项更改的目的说明。拥有完整的历史记录,有助于回溯到旧版本,便于进行 bug 根因分析;当需要修复旧版本软件的问题时,这一点至关重要。如果软件仍在活跃开发中,几乎任何当前状态都可以被视为“旧版本”。
2. 分支与合并
团队成员并行工作已是常态,但即使是独立开发者,也能从在多个独立变更流中工作的能力中受益。在 VCS 中创建“分支”(branch)可使多个工作流彼此隔离,同时提供将这些工作合并回主干的机制,使开发者能够验证各分支上的更改是否相互兼容。许多软件团队采用为每个功能创建分支、或为每个发布创建分支(或两者兼有)的做法。团队可根据自身需求选择适合的分支与合并工作流。
3. 可追溯性(Traceability)
能够追踪软件的每一项更改,并将其与项目管理和缺陷跟踪系统关联起来;同时,每项更改都可附带描述其目的和意图的注释。这不仅有助于根因分析和其他事后调查,还能在阅读代码、试图理解其功能和设计初衷时,提供上下文信息。这种带注释的代码历史,能帮助开发者做出符合系统长期设计目标的正确且协调的修改。这一点在维护遗留代码时尤为重要,也是准确估算未来工作量的关键前提。
虽然在没有版本控制的情况下开发软件是可能的,但这会使项目面临巨大风险,任何专业团队都不应接受这种做法。因此,问题不在于“是否要使用版本控制”,而在于“使用哪种版本控制系统”。
尽管选择众多,但本文将聚焦于其中一种:Git。