版本控制,也称为源码控制、代码管理,是跟踪和管理软件代码的工作实践。
随着信息化、数字化技术的发展,源代码逐渐成为企业的核心数据资产。如何管理好代码这个数据资产,是每一个企业都需要考虑和解决的问题。
作为数字化时代的先行者,大部分互联网和科技型企业已经完成或部分完成了这项工作,并借助敏捷开发、DevOps 等方法论和工具实现了代码的规范、可靠管理,以及高效高质的产品交付。
在产业数字化转型,企业 DevOps 转型的大趋势下,近些年有不少传统嵌入式开发的企业开始参与进来。嵌入式与互联网、科技公司有着不同的技术栈、开发模式和交付方式,对他们来说,并不能发扬拿来主义精神,将“前辈”的经验直接复用,需要结合实际情况走出一条不一样的路,而首先要解决的问题就是代码的可靠管理、高效协同以及高质量交付。
根据我过往工作经历以及接触到的部分客户来看,嵌入式开发场景的主要特点如下:
在这样的背景下,从事嵌入式开发的企业其实也是不紧不慢,安稳度过了一段时期。但在数字化转型的浪潮下,很多企业管理者开始居安思危,希望借助一些先进的开发和管理模式,帮助企业和研发团队转型升级。
如上文所述,嵌入式开发场景的特点决定了他们的工作模式,也带来了一些弊端。简而言之就是缺少管理、缺乏规范、不成体系。
根据我接触到的客户情况来看,从事嵌入式开发的管理者和研发人员对于管理企业源代码的主要诉求如下:
所谓工欲善其事必先利其器,嵌入式开发团队或企业要解决的问题远不止如此,但很多团队选择先从工具侧入手,基于一个好的工具再慢慢探索和完善其实践方式和管理流程。
纵观版本控制系统,即代码管理系统的发展史,大致分为 4 个时期,它们对应的主流工具如下:
毫无疑问,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 是分布式架构,下图是对它们架构的一个描述。但从架构模式上来看,也不太容易能理解两者的区别,那么可以参考灵活性这项的内容,并且举一个形象的例子,更有助于理解它们显著的差异。
所以 Git 能满足远程办公、异地办公等临时脱离代码服务器的开发场景,某种意义上更符合未来协同办公的发展趋势。同时为开发人员在本地进行版本控制提供了可能性,这使得开发人员在有后悔药可以吃的前提下能够在本地进行非稳定功能的开发,等功能相对稳定后再同步到远端,这为多人协同开发打下了基础,避免不稳定的代码影响到他人。
如果你在使用 SVN,为了解决上面的问题,就不得不多在本地建几个文件夹存放临时的代码副本,这一点也不优雅。
由于架构模式的区别,两者在安全可靠方面也有不同的表现:
当然,Git 副本数越多,可靠性也就越高,同时存在数据泄露的风险就越高,数据的安全性又面临挑战,这是另外一个话题。好在国内企业对于数据隐私、数据保护非常重视,大部分传统企业已经通过 DLP(Data loss prevention 数据泄露保护)技术实现了对企业内部系统数据的加密和保护,如 IP-guard 等工具,这个技术对于 SVN 和 Git 同样有效。
SVN 和 Git 在权限模型上也有较大的差异:
这是两个工具设计理念引起的差异,也可能是 SVN 用户唯一不愿意迁移到 Git 的理由了。
由于 SVN 支持按目录授权,早期也没有太多模块化设计的实践,所以使用 SVN 的用户习惯性的把整个项目的所有组件和相关依赖塞进一个仓库,走的是“大仓模式”,再根据需要对目录或整个仓库授权。这又导致 SVN 的仓库普遍臃肿、容量大,加剧了性能问题。
而 Git 的理念是模块化的,倡导解耦,走的是“分仓模式”:
当然,有些以 Git 为底层的代码管理系统支持对代码库的目录进行写入控制,在一定程度上弥补了这个权限控制的缺失。
同样也是由于架构模式的区别,两者在性能上也相差甚远,从 C++ 开发人员角度出发:
正因如此,SVN 的用户基本上不会有多个分支,因为分支越多,性能越差。分支少决定了 SVN 的用户无法实现多人协同开发,一旦多个开发人员在同一个分支下进行开发,那么产生冲突的概率就会增加,并且相互影响,后提交的人需要解决冲突,强制覆盖后又会影响先提交的人,最后变成竞赛游戏。
而在嵌入式开发场景中,一个固件对应多个版本,或者针对不同芯片、不同用户又有定制版本的情况时有发生,又不得不利用分支来进行管理,分支数量一上去,分支间的代码同步和性能问题又开始显现,可谓是让 SVN 的用户骑虎难下。
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 在分仓模式、分支策略、授权模式上还有不同,甚至直接影响研发流程的改变,这里面有哪些潜在的风险,又该如何去解决,为此我会在后续章节来展开,详细讨论这些问题。
💡 后续推送剧透:
欢迎订阅关注~