本文来自
武让 极狐GitLab 高级解决方案架构师
版本控制,也称为源码控制、代码管理,是跟踪和管理软件代码的工作实践。
随着信息化、数字化技术的发展,源代码逐渐成为企业的核心数据资产。如何管理好代码这个数据资产,是每一个企业都需要考虑和解决的问题。
作为数字化时代的先行者,大部分互联网和科技型企业已经完成或部分完成了这项工作,并借助敏捷开发、DevOps 等方法论和工具实现了代码的规范、可靠管理,以及高效高质的产品交付。
在产业数字化转型,企业 DevOps 转型的大趋势下,近些年有不少传统嵌入式开发的企业开始参与进来。嵌入式与互联网、科技公司有着不同的技术栈、开发模式和交付方式,对他们来说,并不能发扬拿来主义精神,将“前辈”的经验直接复用,需要结合实际情况走出一条不一样的路,而首先要解决的问题就是代码的可靠管理、高效协同以及高质量交付。
嵌入式开发场景的代码管理特点与诉求
特点
根据我过往工作经历以及接触到的部分客户来看,嵌入式开发场景的主要特点如下:
- 团队规模:团队规模不大,多数在 100 人左右;
- 技术路线:以 C/C++ 为主;
- 开发模式:以瀑布流为主;
- 需求管理:需求相对简单,相较于应用系统的复杂业务逻辑,嵌入式更多是在跟芯片、元器件打交道;
- 代码大小:较小,多数在 KB 或者 MB 级别;
- 协同方式:以单人开发为主,无需协同;
- 交付频率:较慢,大部分按照月度进行交付;
- 交付方式:固件为主(单片机、下位机等),少部分是可执行程序(上位机);
- 测试方式:真机烧录手动测试为主,极少团队使用仿真模拟测试;
系统工具:主要围绕需求管理和代码管理:
- 需求管理:常见有 Word、Excel 等电子文本方式,或使用专业 PLM、ALM 工具,又或是无管理工具;
- 代码管理:以 SVN 为主,或无管理工具,仅依靠 U 盘、网盘、文件服务器进行归档和传递。
在这样的背景下,从事嵌入式开发的企业其实也是不紧不慢,安稳度过了一段时期。但在数字化转型的浪潮下,很多企业管理者开始居安思危,希望借助一些先进的开发和管理模式,帮助企业和研发团队转型升级。
诉求
如上文所述,嵌入式开发场景的特点决定了他们的工作模式,也带来了一些弊端。简而言之就是缺少管理、缺乏规范、不成体系。
根据我接触到的客户情况来看,从事嵌入式开发的管理者和研发人员对于管理企业源代码的主要诉求如下:
统一管理:源代码是企业核心资产,有必要进行集中、统一管理:
- 无代码管理工具的团队:需要使用代码管理工具,避免企业源代码丢失、泄露;
- 企业存在多套代码管理工具:需要尽可能统一代码管理工具,避免管理不受控或增加管理成本。
- 权限管控:需要实现最基本的无权限、只读、读写、管理等权限分配和管控;
版本控制:需对代码进行版本控制,实现最基本的查看历史记录、查看提交人、进行版本回退等功能:
- 对于开发人员,版本控制提供了一颗“后悔药”,避免代码丢失或误删除、误修改后无法找回;
- 对于管理人员,版本控制提供了一套可追溯、可回退机制,避免人为恶意删除、修改代码等情况,确保企业资产安全可靠。
- 代码规范:需要对开发人员的代码规范进行约束,避免开发人员上传一些无关要紧的大文件以及不规范的代码提交信息,从而导致性能问题并影响协同效率;
- 代码复用:需要有代码复用的能力,避免企业内重复造轮子,避免相同功能的代码在多个项目中多次实现;
- 分支策略:需要一套分支策略和工作流,实现单人、多人对于一个项目的持续开发、修复、发布,并且能较好的区分和管理不同的环境和版本,如开发环境、生产环境以及为某客户定制版本;
- 审核机制:需提供一套审核机制,实现代码的评审和确认,未经审核的代码不允许进入代码管理系统,从而提高代码质量,提升开发团队的综合能力;
- 安全审计:需记录系统用户在代码管理系统上的行为和操作,便于对一些风险行为进行分析、追溯和告警,降低代码泄露的风险。
所谓工欲善其事必先利其器,嵌入式开发团队或企业要解决的问题远不止如此,但很多团队选择先从工具侧入手,基于一个好的工具再慢慢探索和完善其实践方式和管理流程。
嵌入式开发场景的代码管理工具与方式
纵观版本控制系统,即代码管理系统的发展史,大致分为 4 个时期,它们对应的主流工具如下:
- 1980年:RCS;
- 1990年:CVS、VSS、Perforce;
- 2000年:SVN;
- 2005年:Git。
毫无疑问,Git 是当下用于源代码管理的主流工具,它的发起人正是 Linux 之父 Linus Torvalds。
早在 2002 年以前,世界各地的 Linux 开发者通过邮件的方式把代码 diff 发送给 Linus 本人,再由他人工评审和合并,效率非常之低下,社区开发者也表达了不满。
引用
而 Linus 非常反对 CVS、SVN 等集中式的版本控制系统,它们性能较差且必须联网才能使用。在 2002 年至 2005 年这段时间,BitMover 公司授权 Linux 社区免费使用它们的商业化版本控制系统 BitKeeper,然而在 2005 年,Linux 社区的开发人员却试图破解 BitKeeper,导致 BitMover 公司收回使用权。
引用
故事的最后,Linus 本人花了两周时间用 C 写了一个分布式的版本控制系统,就是 Git。所以 Git 自诞生之日起,就是为了更好的管理 Linux 的核心代码。它跟 Linux 一样也是开源的,并且在社区开发人员的持续贡献下发展了快二十年。
而 SVN 作为上一代的版本控制系统,开始逐渐退出历史舞台,今年 1 月,GitHub 也宣布自 2024 年 1 月 8 日起,停止对 Subversion (SVN)的支持。
对于没有使用任何代码管理工具的企业,没有历史负担,会直接选择 Git。而大多数的从事嵌入式开发的团队,都在使用上一代的源代码管理工具 SVN,这时候他们要考虑的就是 Why 和 How 的问题了。
SVN 与 Git
要考虑为什么要或者是否要从 SVN 切换到 Git,最直接的方式就是对它们进行一个对比。
总结一下:
➤ 1. 架构
SVN 是集中式架构,Git 是分布式架构,下图是对它们架构的一个描述。但从架构模式上来看,也不太容易能理解两者的区别,那么可以参考灵活性这项的内容,并且举一个形象的例子,更有助于理解它们显著的差异。
- SVN 像直播,用户必须联网才能观看(提交代码);
- Git 像网盘,用户可以下载到本地进行观看(本地提交),并且可以进行编辑、传播,有需要时再同步回网盘上(远端同步)。
所以 Git 能满足远程办公、异地办公等临时脱离代码服务器的开发场景,某种意义上更符合未来协同办公的发展趋势。同时为开发人员在本地进行版本控制提供了可能性,这使得开发人员在有后悔药可以吃的前提下能够在本地进行非稳定功能的开发,等功能相对稳定后再同步到远端,这为多人协同开发打下了基础,避免不稳定的代码影响到他人。
如果你在使用 SVN,为了解决上面的问题,就不得不多在本地建几个文件夹存放临时的代码副本,这一点也不优雅。
➤ 2. 安全
由于架构模式的区别,两者在安全可靠方面也有不同的表现:
- SVN 是单副本,除非服务器有备份,否则服务器挂了代码数据就都会丢失,可靠性较低;
- Git 是多副本,每个开发人员本地都有一套拷贝,并且包含所有历史记录,虽然可能不是最新版本,但发生极端情况时,更容易恢复,数据的可靠性更高。
当然,Git 副本数越多,可靠性也就越高,同时存在数据泄露的风险就越高,数据的安全性又面临挑战,这是另外一个话题。好在国内企业对于数据隐私、数据保护非常重视,大部分传统企业已经通过 DLP(Data loss prevention 数据泄露保护)技术实现了对企业内部系统数据的加密和保护,如 IP-guard 等工具,这个技术对于 SVN 和 Git 同样有效。
➤ 3. 权限
SVN 和 Git 在权限模型上也有较大的差异:
- SVN 支持对代码库中的目录进行权限控制;
- Git 只提供对整个代码库的权限控制,无法对代码库中的目录进行权限控制。
这是两个工具设计理念引起的差异,也可能是 SVN 用户唯一不愿意迁移到 Git 的理由了。
由于 SVN 支持按目录授权,早期也没有太多模块化设计的实践,所以使用 SVN 的用户习惯性的把整个项目的所有组件和相关依赖塞进一个仓库,走的是“大仓模式”,再根据需要对目录或整个仓库授权。这又导致 SVN 的仓库普遍臃肿、容量大,加剧了性能问题。
而 Git 的理念是模块化的,倡导解耦,走的是“分仓模式”:
- 如果代码彼此之间的业务和功能逻辑相对独立,并且能够独立编译,那么就应该放到不同的代码库进行管理和授权;
- 如果代码彼此之间有强依赖,无法独立编译,那么可以放到一个仓库里,但就没必要进行按目录授权了,因为不具备某些目录权限的开发人员无法通过编译来验证自己开发的功能是否正确,这样就失去了协同开发的意义。
当然,有些以 Git 为底层的代码管理系统支持对代码库的目录进行写入控制,在一定程度上弥补了这个权限控制的缺失。
➤ 4. 性能
同样也是由于架构模式的区别,两者在性能上也相差甚远,从 C++ 开发人员角度出发:
- SVN 的分支是值类型,创建一个分支就相当于在服务端拷贝一份代码到另一个目录,效率低;
- Git 的分支是指针类型,创建一个分支只是创建代码提交记录的指针,效率高。
正因如此,SVN 的用户基本上不会有多个分支,因为分支越多,性能越差。分支少决定了 SVN 的用户无法实现多人协同开发,一旦多个开发人员在同一个分支下进行开发,那么产生冲突的概率就会增加,并且相互影响,后提交的人需要解决冲突,强制覆盖后又会影响先提交的人,最后变成竞赛游戏。
而在嵌入式开发场景中,一个固件对应多个版本,或者针对不同芯片、不同用户又有定制版本的情况时有发生,又不得不利用分支来进行管理,分支数量一上去,分支间的代码同步和性能问题又开始显现,可谓是让 SVN 的用户骑虎难下。
Git 与之相反,依靠灵活快捷的分支管理方式,配合多种分支策略,可以实现多人协同开发、按环境和版本区分代码、并尽可能确保通用的代码在不同环境、版本间保持同步。分支策略本身也决定了研发流程的规范建设,这也是企业关心的核心内容。
➤ 5. 体验
- SVN 的命令较少,易于学习,操作简单。常用 TortoiseSVN 这款图形化客户端工具进行操作;
- Git 的命令较多,较难学习,操作相对复杂。熟悉命令的开发人员习惯使用命令行进行操作,而对于初学者建议使用 SourceTree
等图形化客户端或主流 IDE 的 Git 插件来操作。
从学习和使用层面来看,Git 的成本相对较高,但也有一些降低门槛的方法和工具。相较于架构、模式所带来的变化,操作体验上的变化显得微不足道了。从另一方面来说,Git 也算是开发人员的基本技能,毕竟全球 94% 的开发人员都在使用 Git 或者会使用 Git。
此外,因为 SVN 支持按文件进行下载,再加上操作简单,非技术人员比如产品经理、项目经理也容易上手使用,所以非常多的 SVN 用户使用 SVN进行文档管理,比如 Word、Excel 等。
Git 恰恰相反,不支持按文件下载(可以通过部分克隆实现,但对于非技术人员成本略高),必须把整个仓库下载下来,操作也比较复杂,所以当这些用户迁移到 Git 后,旧文档的管理方式又变成了一个问题。
对于这个问题,文档就应该放在文件服务器(FTP、SMB、NFS、NAS等)或者文档协同系统(Wiki、Confluence、腾讯文档、飞书等)上进行管理。放在 SVN 上,在以前的时代虽然可行,但集中式的架构需要在线才能访问,且大文件使得 SVN 本就不足的性能雪上加霜。此外,现在人们对于文档管理的需求除了管理、存储、版本控制之外,还看重协同,所以如果决定从 SVN 向 Git 进行迁移,文档的管理模式也需要进行升级。
综上,从 SVN 迁移到 Git,优势自然是顺应技术发展的趋势,相较于 SVN 这个已经没有任何官方支持的上一代产品,有非常多的以 Git 为底层的成熟工具和商业化产品,比如 GitLab /极狐GitLab、GitHub、Gerrit 等,可以为企业 DevOps 转型提供更好的支持。而且,Git 可以从根本上解决 SVN 的性能问题,实现更好的研发协同,便于企业建立规范的研发流程。
但问题是除了工具本身和使用体验上的差异,Git 在分仓模式、分支策略、授权模式上还有不同,甚至直接影响研发流程的改变,这里面有哪些潜在的风险,又该如何去解决,为此我会在后续章节来展开,详细讨论这些问题。
💡 后续推送剧透:
- 分仓、权限与依赖问题
- 基于Git进行多仓管理
欢迎订阅关注~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。