Ver.还是Rev.

关于版本和修订

最近在帮朋友检查PCB的layout,忽然发现朋友的板子用的是Rev.xxx,而我自己平时喜欢使用Ver.xxx,印象里板子上这两种丝印我都有见过。鉴于我那该死的好奇心,我决定找一找背后的究竟。

很快,我找到这两个缩写的原词:Version–版本号,Revision–修订版,看起来这是一个纯粹的英语问题,(ps:当年要是有这个较真的劲学英语,还会把英语学得这么烂么。。。)但是继续往下扒拉,我又有了新的发现:

在这篇博客中,博主很详细的解释了这两者有何不用,除了字面意思之外,它们的使用场景也是完全不同的

version “版本”。指文件或软件的公开发行版本,强调功能性。通常在功能方面有重大改变、改进或增加,包括对一些重大bug的修复。

revision “修订版”。指在文件或软件的公开发行版本的基础上,在功能方面有细微改变、改进或增加,包括对一些小bug的修复,这是在某个version版本的基础上在不同设计阶段的标志。

所以,在每次修改时,revision都会变化,但是version 却不一定会有变化。

所以,Ver.xxx是交付给客户使用的编号,它代表了我们交付公开发行的版本,强调包含哪些功能,突出产品特点,而Rev.xxx是部门内部使用的编号,它强调每个版本相对于上个版本做了哪些技术调整,bug修复等等,突出工作改进。所以在大的项目管理中,对外部客户发布,一般只发布版本号,对于一些小的bug修复,可能并不会特别去针对性修改,只是在批次生产或者发布时做一些内部调整,并不需要完全告知到客户端。对内部工作改进,则需要发布详细的修订版本,让每个成员了解详细的工作改进。

同时我在知乎用户:知乎用户G0K17q也发现了一篇非常好的文章,但是作者账号已注销,为避免这么好的文章可能会失踪,这里我搬过来原文

原文如下:

本文为交付建立一个概念空间,以便更容易讨论问题。

当我们交付一个部件,我们会给它一个版本号,比如1.0。这个我称为Version。这个Version会交给一个(组)用户使用,这些用户在使用的过程中,会发现问题,会要求我修改,这时我需要修改它,修改完了,它是否还叫1.0呢?我确实仍可以叫它1.0,因为从用户的角度来说,这个版本和原来的版本没有区别,可以直接替换。但在我的家里,我肯定不能把它叫1.0了,因为它的内容不一样了,如果我要修改什么东西,必须在这个修改的版本的基础上进行修改。

为了方便表述,我把这个新的内部的版本叫1.0.1。这样的版本,我称为Revision。我会不断发现Bug并进行修复,我们Revision会发生积累,但对用户来说,我的版本仍是1.0,当我跟他说,我卖了一个1.0的产品给他的时候,我指的主要是最后一个Revision,或者说是这个Version的Head。

但是,我交付了Version 1.0给客户A,并把Revision升级到了1.0.3,这时客户B进来了,我也用这个Head给他交付,但当我升级1.0.3到1.0.4的时候,A客户愿意升,B客户不愿意。这时我们产生了两种策略:

  1. A使用Version 1.0的Revision1.0.4,B使用Version 1.0的Revision 1.0.3,B落后于Version 1.0的Head,未来他要升级,只能继续追Version 1.0的HEAD。
  2. A使用Version 1.0的Revision 1.0.4,B使用Version 1.1的Revision 1.1.0=1.0.3。A后续在1.0.x的revision上升级,而B后续在1.1.x的revision上升级

对于后面这种情况,我认为我们交付了“两个版本”。对应的前者我们认为只是交付了一个版本。其区别在于我需要维护多少个HEAD:

当我们进行配套,测试,升级,维护(修Bug)等行为的时候,多一个不同的HEAD,都多一套工作。

版本是个对外的概念,在内部开发上,版本其实就是“分支”。因为一旦我们对外承诺了一个Version,我们开发的时候就必须记录在这个Version上我们的修改过程。

这种版本和A、B是否同一个客户无关,同一个客户,在不同的设备上也可以因为维护策略的不同,产生不同的分支。比如我们先做了一个设备H1,支持软件V1.0,然后我们出了设备H2,和H1混用,那么我的软件是升级到V1.0.x去同时支持呢?还是已经部署的设备继续用V1.0.x,新的设备用两者兼容的V2.0.x去支持呢?这也会事实上造成版本分裂的结果。因为如果你不用后一个方案,前一个方案要出补丁的时候,你是要出两个不一样的补丁的。如果你的软件要和另一个软件配套,你也需要测试两次。下面是一个示意:

这种版本也和交付是源代码还是二进制无关,我们只关心你交出去的那个东西,是否有人回头来找你,要求在那个确切交出去的东西上面作进一步的修改。关键在于你的交付界面,不是这个交付的形式是二进制还是源代码。你用一套源代码编译出两个二进制的Version,你说这是同一个Version,这个没有意义,因为如果你真可以认为这是一个Version,你根本就应该该出去一个二进制。你给的是两个版本,就会预期它可以和其他部件有不同的配套关系。

如果你交付的是源代码,就算用户编译出很多个实例在他的环境中使用,他回来找你要版本,你也是升级这个源代码版本给他,那么你就仅交付一个版本,测试也仅仅测试一个版本,他自己编译了多少个平台,都和你无关。(但要注意,如果你的源代码说要支持多个OS或者硬件的版本,那么你的测试工作量不会减少,但这不影响你交付的时候就是交付一个Version。)

如果你交付的界面是二进制,甚至你仅仅是修改了一下编译选项,同一个源代码编译出两个二进制版本给用户。我们都认为它构成了两个Version。因为它们需要不同的配套,比如你一个是big-endian编译的,一个是little-endian编译的,那么你要给他们加一个插件,那个插件也需要两个二进制版本进行交付版本配套和测试啊。

对于版本这个概念我们需要反复给读者们强调:“版本”是因为你的行为和承诺产生的,不是你是否把它叫做版本。你说“我只有一个版本,名字叫1.0,但我给的时候,给A客户和B客户的东西不是同一个……”这就是两个版本,不是因为你把他们都叫做1.0就不是两个版本了。因为发生了Bug,你还是要找那个“不同”的分支(编译选项不同也是不同,你一样要记录那个区别才能给那个客户承诺),在那个分支上给他解决问题。

这问题为什么重要?关键就是这个配套关系。比如你这个软件S和硬件H有配套关系,为了保证这种配套是可靠的,我们每次出版本,就必然需要在所有的组合中进行测试。假设H有H1.0和H2.0两个版本,你的软件有V1.0和V1.1两个版本,我们每次出厂,都会测试V1.0的HEAD和H1.0/H2.0的配套,以及V1.1的HEAD和H1.0/H2.0的配套。但我们不会测试其他的Revision的版本配套关系,否则我们就会有无数的组合了。

考虑到每个客户的解决方案中都会有无数的部件和之间有匹配关系,减少Version的数量,我们才有可能保证我们的测试是可控的。但Version太少,就很难满足客户的需要,因为你任何需要都要求用户升级到HEAD上,那么每个用户都会被很多的其他用户的要求所绑架。

你很Nice,用户喜欢升级就升级,喜欢不升级就不升级,关键在于你把他的要求看作是一种Revision还是一种Version,如果看作Revision,问题很简单,问题他们自己负责,如果他们负责不了,就追到HEAD上。但如果我们把他的需求看作Version,那么就是我们需要为他的问题负责了。

如果读者需要更切身的体会,我们再看一个例子:比如Ubuntu 18.04是一个Ubuntu的Version,18.04.1是它的Revision,内核是4.15,后来它的Revision变成18.04.3,内核升级到5.3。现在你做一个支持Ubuntu 18.04的版本,那么你出的版本就应该升级到18.04.3,支持5.3的内核。但你的客户不一定同意,要求你支持18.04.1,你很Nice,你答应了。这样马上就会把18.04.1变成一个Version(而不是一个Revision),但Version是需要支持的,现在你自己决定支持18.04.1,那么你天然“制造”了一个Version,那你就要准备好给客户解决CustomizedUbuntu 18.04.1-X这个版本的后续Revision如何升级的问题了。比如他发现他用的openssl有个安全漏洞,就应该是你给他修这个Bug(Ubuntu只会在18.04.3上修这个Bug),就算不是Openssl,你只是换掉了内核,那这个内核的Bug,也都需要你来修,因为Ubuntu的维护中已经看不见这个Revision了,他只能看见他的Head。
我们控制Version是控制维护的可信度和工作量,不是人为“认为”有多少个版本,这个问题不能强行通过定义解决的。

Version和Revision可以叠加的,这会让问题变得更加的复杂。以前面这个Ubuntu的例子为例。你在使用20.04这个Version,然后现在OpenSSL中发现了一个Bug,OpenSSL的revision从1.1.1e,升级到1.1.1f。但为了叠加管理,18.04的HEAD虽然移动了,但维护者并没有升级这个Revision,所以你听起来觉得这个Revision还是20.04.1,但其实你交付的东西已经不同了。

而且,如果用户用的情形足够复杂,多个用户可能使用你的组合中的不同组合。比如你同时提供了OpenSSL的v1和v2两个库到你的20.04.1中,部分用户调用其中的v1,部分使用了v2,这算几个Version?

在我们这个定义中,我们只承诺我们交付出去的那个安装前的状态,所以,这是一个Version。只是这个Version的组合测试工作量很大而已。

说到Linux发行版的版本,我再补充一个例子:很多人很容易陷入一个误区。比如要求Ubuntu支持某个硬件。那理论上你唯一的方法是和Ubuntu合作,在它的版本上支持你的硬件,这说的才是Ubuntu的Version支持这个硬件。但如果Ubuntu专门出另一个版本,专门支持你这个硬件,那这就是Ubuntu-Customized XX Version支持你这个硬件,这产生了另一个版本,不是原来那个意思了。如果你不是和Ubuntu合作,而是(因为这是开源软件)自己“定制”了一个版本(只要你不要保留Ubuntu中部分商业软件。这完全合法,实际上Ubuntu本来就是基于完全开放的Debian定制的),不要使用它的商标,你完全可以做一个ILoveYouLinux V1.0来实现这个支持,但这个就不是Ubuntu的分支了。它很多地方很像Ubuntu,你甚至可以每次在Ubuntu升级的时候跟着升级,但你的节奏,相应客户问题的能力,定制能力就不同了。这不能认为这是同一个版本,因为它的发展不能按同一个版本那样发展的,你加了你的代码后,原来分支可以做的修改,新分支可不一定可以修改。这是我们关心Version和Revision的核心原因。

确定Version,是开发视图最难最脏的一个工作,不给出明确的Version的每个版本,开发组和需求方都会觉得怎么都行,没有什么不可以的,一旦给定Version,而且他们明白Version是啥意思,什么幺蛾子都出来了。所以这才是架构定义要面对的问题,这种问题上,不让开发部和需求方现场打架,都不是好的架构师。

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注