这是我一直想知道的...
请原谅我的天真,但是 - 你如何决定用什么版本号来命名你的软件?
我假设,当有人创建应用程序/程序的“最终”版本时,它是 1.0 版吗?- 然后,当你更新它时会发生什么,你如何决定将它称为 1.1 或 1.03 等等等等。
这主要是为开发人员准备的吗?
这是我一直想知道的...
请原谅我的天真,但是 - 你如何决定用什么版本号来命名你的软件?
我假设,当有人创建应用程序/程序的“最终”版本时,它是 1.0 版吗?- 然后,当你更新它时会发生什么,你如何决定将它称为 1.1 或 1.03 等等等等。
这主要是为开发人员准备的吗?
我最近听说了一种更简洁的版本控制策略,这是我在Eric Elliot 的 Medium 帐户中第一次遇到的。它更侧重于面向客户的版本号的库版本控制,但它具有简单的优势。使用由三部分组成的版本号,其中每个数字表示:
打破.feature.fix
我将旧答案留在下面,因为它仍然与面向客户的版本相关。
我倾向于按如下方式对有效数字进行加权....
wxyz(或 w.xyz)
如果选择使用 w.xyz 格式,在溢出前只能得到 9 位数字。但是,如果您经常发布,您可能会遇到更大的问题。
让我们用我的新产品 FooApp 来说明一下吧!
Jeff Atwood 有一篇关于此的博客文章,他主张只使用日期,而不是将用户与版本号混淆。但是,他确实讨论了 Microsoft 采用的方法:使用日期确定版本号。他在他的帖子中有相当多的深度,所以我不会在这里重复他的工作。至于版本控制:
版本(至少在 .NET 中,类似这样):
1.2.3.4 其中:
1 是主要版本
2 是次要版本
3 是内部版本号
4 是修订版本号
主要版本- 表示一个“完整”的系统,具有该版本应具有的任何功能。通常,任何后续的“主要”版本都是重写、架构更改或(请原谅冗余)对软件的重大更改。
次要版本- 表示不太重要的版本,可能包含错误修复、添加的小功能或任何数量的其他“次要”事件。这可能包括界面更改和添加。通常,应用程序在它们的“主要版本”树中应该有点兼容,因此同一主要版本的次要版本在架构上应该是相同的。
内部版本号- 通常仅表示错误修复、小修复,并且在其范围内有些微不足道。它可以像改变应用程序的前景和背景之间的对比度一样简单。通常,构建是内部名称,例如夜间构建,因此您总是有一个地方可以恢复到稳定的状态。
修订号- 表示何时发布错误修复或进行非常小的改进。这些通常仅用于错误修复——不包括主要功能增强作为修订。
我们为任何应用程序的每个构建分配唯一的四部分版本号,定义为Major.Minor.Maintenance.Build。
主要- 主要编号与应用程序的重大更改相关联。这个数字还决定了与同一“套件”中其他应用程序的兼容性。当发布新版本时,此数字会增加。这通常意味着发生了重大的架构变化。
次要- 次要编号与新功能和重大错误修复相关联。每当引入新功能或应用重大错误修复时,此数字将被提前,并且维护编号将设置为零。
维护- 维护编号与非破坏性错误修复相关联。每当发布仅包含非中断错误修复的版本时,此数字将被提前。
内部版本 - 内部版本号与编译应用程序的 subversion 变更集(修订号)相关联。这将提供一种简单的方法来将版本号与 subversion 中的一组精确代码进行匹配。
开发人员对此方案真正感兴趣的唯一数字是Build。数字。通过将内部版本号与 subversion 修订号联系起来,我们可以保证使用什么代码来创建发布的应用程序。
我认为 Linux 内核是一个很好的参考:
Linux 内核的版本号目前由四个数字组成,这是在最近更改了长期以来的三数字版本控制策略之后。为了说明起见,假设版本号是这样组成的:ABC[.D](例如 2.2.1、2.4.13 或 2.6.12.3)。
* The A number denotes the kernel version. It is rarely changed, and
只有当代码和内核概念发生重大变化时。它在内核的历史上已经改变了两次:1994 年(1.0 版)和 1996 年(2.0 版)。
* The B number denotes the major revision of the kernel. o Prior to the Linux 2.6.x series, even numbers indicate a stable
发布,即认为适合生产使用的版本,例如 1.2、2.4 或 2.6。奇数历史上一直是开发版本,例如 1.1 或 2.5。它们用于测试新功能和驱动程序,直到它们变得足够稳定以包含在稳定版本中。这是一个偶数/奇数版本号方案。o 从 Linux 2.6.x 系列开始,偶数或奇数没有意义,新功能开发在同一个内核系列中进行。Linus Torvalds 曾表示,这将是可预见的未来的模式。
* The C number indicates the minor revision of the kernel. In the old
三号版本控制方案,当在内核中实现安全补丁、错误修复、新功能或驱动程序时,这会发生变化。但是,对于新政策,只有在引入新的驱动程序或功能时才会更改;次要修复由 D 号处理。
* A D number first occurred when a grave error, which required immediate
修复,在 2.6.8 的 NFS 代码中遇到。但是,没有足够的其他更改来使新的次要版本(本来应该是 2.6.9)的发布合法化。因此,发布了 2.6.8.1,唯一的变化是修复了该错误。在 2.6.11 中,这被采用为新的官方版本控制策略。错误修复和安全补丁现在由第四个数字管理,而更大的更改仅在较小的修订更改(C 编号)中实现。D 编号还与编译器构建内核的次数相关联,因此称为“构建编号”。
另外,有时版本之后会有一些更多的字母,例如'rc1'或'mm2'。'rc' 指的是候选版本,表示非官方版本。其他字母通常(但不总是)是一个人的首字母。这表明该人的内核开发分支。例如,ck 代表 Con Kolivas,ac 代表 Alan Cox,而 mm 代表 Andrew Morton。有时,这些字母与构建内核的分支的主要开发区域相关,例如,wl 表示无线网络测试构建。
来自http://en.wikipedia.org/wiki/Linux_kernel#Version_numbering
无论您选择哪种编号方案,当新版本与旧客户端代码兼容时,以及新版本何时需要对现有客户端进行更改时,向用户说明这一点至关重要。当客户端代码必须更改时,我知道的大多数项目都会碰到第一个数字。
除了兼容性之外,我也认为使用日期还有很多话要说。尽管像我一样,如果您的发布时间表是每两年一次(但这是针对 1989 年首次发布的工具),这会很尴尬。
销售或营销人员很可能会决定他们需要一些嗡嗡声。这将确定下一个版本是 1.01 还是 1.1 还是 2.0。在开源中的工作方式是一样的,但它往往与团队引以为豪的一个新奇的功能联系在一起。
A B C D
这是我在嵌入式 C 项目中用于模块的:
1.00 - 初始版本
1.01 - 次要版本
模块没有接口更改(即头文件没有更改)。任何使用我的模块的人都可以升级而不必害怕破坏代码。我可能已经做了一些重构或代码清理。
2.00 - 主要修订
模块接口更改(即添加、删除功能或更改某些功能的功能)。对此版本的升级很可能会破坏现有代码,并且需要使用此模块重构代码。
我应该补充一点,这是指开发阶段,即模块的内部发布到项目中。
为了补充上述所有解释,我建议使用版本控制方案,这将使您的客户容易记住并且您可以轻松地为您的软件版本设置基线和管理。此外,如果您支持不同的框架,例如 .Net 1.0、.Net1.1 等,那么请确保您的版本控制方案也能解决这个问题。
这里也有一些很好的信息..
何时更改文件/程序集版本 首先,文件版本和程序集版本不必相互一致。我建议文件版本随着每次构建而改变。但是,不要在每次构建时更改程序集版本,以便您可以分辨同一文件的两个版本之间的区别;为此使用文件版本。决定何时更改程序集版本需要对要考虑的构建类型进行一些讨论:运输和非运输。
非发货版本 一般来说,我建议在发货版本之间保持非发货组件版本相同。这避免了由于版本不匹配而导致的强命名程序集加载问题。有些人更喜欢使用发布者策略为每个构建重定向新的程序集版本。但是,我建议不要将其用于非运输版本:它并不能避免所有加载问题。例如,如果合作伙伴 x 复制您的应用,他们可能不知道安装发布者政策。然后,您的应用程序将被他们破坏,即使它在您的机器上运行良好。
但是,如果同一台机器上的不同应用程序需要绑定到程序集的不同版本,我建议为这些构建提供不同的程序集版本,以便可以为每个应用程序使用正确的程序集版本,而无需使用 LoadFrom/etc。
发布版本 至于为发布版本更改该版本是否是一个好主意,这取决于您希望绑定如何为最终用户工作。您希望这些构建是并排的还是就地的?两个版本之间有很多变化吗?他们会破坏一些客户吗?您是否关心它会破坏它们(或者您是否想强制用户使用您的重要更新)?如果是,您应该考虑增加程序集版本。但是,再一次,请考虑这样做太多次可能会在用户的磁盘上乱扔过时的程序集。
当您更改您的程序集版本时要将硬编码版本更改为新版本,我建议在头文件中为版本设置一个变量,并将源代码中的硬编码替换为该变量。然后,在构建期间运行预处理器以放入正确的版本。我建议在发货后立即更改版本,而不是之前,以便有更多时间来发现由于更改而导致的错误。
在库的情况下,版本号告诉您两个版本之间的兼容性级别,以及升级的难度。
错误修复版本需要保留二进制、源代码和序列化兼容性。
次要版本对不同的项目意味着不同的东西,但通常它们不需要保持源代码兼容性。
主要版本号可以打破所有三种形式。
我在这里写了更多关于基本原理的文章。
这取决于项目。下面是 haskell 的包版本控制政策。
-- The package version. See the Haskell package versioning policy (PVP)
-- for standards guiding when and how versions should be incremented.
-- http://www.haskell.org/haskellwiki/Package_versioning_policy
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.1.0.0