文件版本控制最佳实践

写给已经有一套编号方案的团队的文件版本控制最佳实践:保持它稳定,固定版本、日期和审批人出现的位置,杜绝对当前副本的并行编辑,并记录每一次“无需变更”的审查。

文件版本控制最佳实践,是让一套已有的编号方案在多年的人员更替和使用量增长中依然值得信任的那些习惯,而不是最初挑选这套方案本身的规则。

简而言之

  • 一旦选定编号方案就保持稳定——重新编号会打断每一条引用了旧编号的交叉引用。
  • 在每一页固定的同一个位置印出版本、日期和审批人,而不只是留在文件名或属性里。
  • 绝不能让两个人在没有锁定或签出惯例的情况下并行编辑“当前”版本。
  • 提前用书面方式明确规定,到底什么算大改、什么算小改。
  • 把“无需变更”当作一个被记录下来的审查结果,而不是沉默。
  • QueryChart 用一份唯一的实时图表取代了签出惯例——见 /features/version-control。

一套方案的好坏,要看它的第二年

一套编号方案很少在第一个月就失效。它失效在第二年,那时定下“已发布用整数”的那个人已经离职,新来的文件管理员为了应付一个紧急情况发明了一条略有出入的规则,两套惯例开始在同一本登记册里同时流转。本文假设基本决定已经做过——挑选方案本身见 /zh/guides/如何对文件进行版本控制——讲的是当真实的使用量、人员更替和紧急情况来袭时,能让一套已选定的方案继续运转下去的那几个习惯。

方案选定之后会出问题的地方有四处,而且都和方案本身无关。为了修补一个感觉上的缺陷去给一个已有的库重新编号,会打断每一条引用了旧编号的交叉引用、培训记录和历史审计引用,所以这样做的代价通常超过直接容忍这个缺陷。一个只存在于文件名或属性面板里的版本号,一旦有人打印一页或转发一张截图就会消失,所以它需要一个固定的、印出来的位置。两位作者在同一个下午编辑同一份“当前”文件,根本不是编号问题——这是缺少一套锁定或签出惯例,没有它,任何方案都撑不住。而一次没发现任何问题的定期审查,仍然必须留下痕迹,否则一年后它就和一次从没发生过的审查毫无区别。这些都不是文件的整个生命周期——从申请到退役的全过程,完整介绍见 /zh/templates/文件控制流程——而是这个生命周期内部的编号层,把它做好,而不只是做了。

QueryChart 从结构上、而不是靠制度,消除了其中一种失效模式。每份文件只有一份唯一的实时图表,而不是一堆需要有人记得去锁定的文件;每一次保存都会自动记入变更日志,写明经办人和确切改动的字段;比较版本把任意两个版本并排展示。两个人没法悄悄分叉出“当前”副本,因为根本只有一份,它的整段历史是一次查询,而不是一场记忆考验。见 /features/version-control。

这些做法在一份文件的一生中出现在哪里

同一张 18 行的文件版本控制图表,这次不是看编号步骤本身,而是看是什么让它的编号方案能长期站得住。

  1. 方案在任何人开始评审之前就已经启动

    “分配初始草稿版本 0.1”紧跟在“新文件起草”之后立刻发生,早于“将草稿分发给内部评审”或“评审人评估草稿”——这套小数方案在第二行就已经固定,不是在第一次“是否需要修改?”判断进行到一半时才发明出来的。

  2. 返工递增编号,从不重新编号

    “递增小版本号”和“根据意见修改草稿”沿着标为“重新评审”的分支循环回评审,然后才是“提交最终草稿以供审批”和“审批人审查最终草稿”——同一套小数规则贯穿每一轮,所以引用 0.3 版草稿,指的始终是同一份确切的副本。

  3. 一个判断划出大版本和小版本的界线

    “是否批准发布?”是唯一一行能通向整数的判断:“批准”分支到达“分配大版本号 1.0”,“驳回”循环回“递增小版本号”——然后“更新版本历史登记册”“发布已批准的版本”和“将前一版本标记为已作废”会在任何人读到新副本之前,把这个决定固定进一个文件形状的行里。

  4. 不需要变更的文件也留下了记号

    “发布后是否有变更申请?”即使答案是“否”也会被回答——那条分支到达“当前版本继续生效”,这是一个具名的结果,而不是没有动静,而“是”则在“以下一个版本重新开启该文件”重新开启文件,而不是在旁边另起一份副本。

运作方式

  1. 一旦有真实文件依赖这套方案,就把它冻结

    把对方案本身的改动——从整数改成语义化版本号,或者重新定义小数代表什么——当成一个项目来对待,而不是随手一改:它会让每一条已有的交叉引用、培训记录和历史审计引用全部失效。如果发现了缺陷,就把例外情况从此往后记录下来,而不是给整个库重新编号。

  2. 把版本、日期和审批人固定在每份模板上的同一个位置

    选定一个位置——页眉或页脚——并把它内建进文件模板,让每一位作者不用另外做决定就沿用它。一个只存在于文件名或文件属性里的版本号,撑不过一次打印、一张截图或一次邮件转发;印在页面上的那个能。

  3. 给“当前”版本一套锁定或签出惯例

    决定谁可以同时打开当前版本进行编辑,以及第二位作者怎么发现已经有人在编辑了——可以是登记册里的一个签出标记、一个被锁定的文件,或者一份唯一的、只有一次保存能生效的实时副本。没有这个,两次都获批的编辑落在同一个版本上,就不是一种假设情况。

  4. 在第一份文件用到大小版本规则之前先写下来

    在定义编号方案的同一份文件里,明确规定到底是什么触发整数进位——单纯的正式批准,还是批准加上一次实质性重写。逐案判断的团队,最终会得到两份都叫 2.0 版的不同文件。

  5. 记录每一次定期审查,包括那些什么都没改的

    给审查这一步一个带标签“无变更”出口的判断形状,让它也写入登记册的一条带日期条目,就像“发布后是否有变更申请?”到达“当前版本继续生效”而不是什么都不做那样。一条缺失的条目应该意味着审查没有发生,而不是意味着审查期间什么都没发生。

  6. 让一份唯一的实时副本彻底消除锁定问题

    把文件放进一张 QueryChart 图表,而不是一堆靠邮件传来传去的文件,这样就只有一个当前版本可以编辑——每一次保存都会自动记入变更日志的一条新条目,签出惯例就没有什么可执行的了。见 /features/version-control。

应避免的错误

  • 为了修补一个错误而重新编号

    两年后发现方案有个缺陷,为了修复它给整本登记册重新编号,会让每一条引用了旧编号的记录失效——审计、培训记录、其他文件里的交叉引用。改成从此往后记录例外情况;容忍已发布内容里的这个缺陷。

  • 只活在文件名里的版本号

    “Policy_v3_FINAL.docx”一旦被打印、转发或复制丢了文件名,就什么都说明不了。把版本、日期和审批人放进文件本身,每次都在同一个固定位置。

  • 同一个下午被编辑的两份“当前”副本

    共享盘上的一份和邮件里的一份都被当作母本编辑,两组改动就会悄悄互相覆盖或分叉。用一套签出惯例修复它,或者更好的办法:用一份唯一的实时副本——见 /features/version-control。

  • 什么都没变时,审查没有留下任何痕迹

    一份被审查过、确认依然准确、却哪里都没有留下记录的文件,一年后看起来和一份从没被审查过的文件毫无区别。给“无需变更”它自己带日期的一行,就像一个判断行的“否”分支依然到达一个具名的结果一样。

把这些做法用到你自己的文件上

把文件版本控制示例打开成你自己的图表,让一份唯一的实时副本加上自动的变更日志,替你执行本文说的这些规则。

把这些做法用到你自己的文件上

相关指南

常见问题

文件版本控制里最容易犯的一个大错是什么?

把方案当成只有在有人找到理由要改动它之前才算固定的东西。给一个已有的库重新编号——哪怕是为了修补一个真实存在的缺陷——都会让每一条引用了旧编号的交叉引用、培训记录和审计引用失效,而这个代价几乎总是超过容忍一套不完美方案的代价。用一条被记录下来的例外去从此往后修复问题,而不是去动已经发布的内容。

怎么阻止两个人同时编辑同一份“当前”版本?

要么加一套明确的签出惯例——登记册里的一个标记,显示谁正打开着这份文件,让第二位作者知道要等待——要么从结构上直接消除这种可能,只保留一份唯一的实时副本,而不是靠邮件或共享盘传来传去的一堆文件。QueryChart 走的是第二条路:每份文件都是一张实时图表,每一次保存都自动生成版本,没有第二份副本可以分叉。见 /features/version-control。

什么样的改动算大版本,什么样的算小版本?

没有一条放之四海而皆准的规则,这正是为什么它必须在第一份文件真正需要用到之前就写下来,而不是逐案判断。一个常见的惯例是把整数级的大版本进位单独绑定给正式批准——在此之间的每一次草稿修订,无论多实质,都保持小数——这样“这次改动有多大”就永远不用在分配版本号的那一刻现场争论。

一次没发现需要变更的定期审查,需要记录吗?

需要——一次没有被记录的审查,和一次从没发生过的审查没有区别。给你流程里的审查步骤一个带标签“无需变更”出口的判断形状,让它依然向登记册写入一条带日期的条目,就像图表的判断行会记录它走过的每一条分支,而不只是那些通向新内容的分支一样。

本指南所用的模板

文件版本控制模板 — 文件版本控制模板:展示草稿如何以小版本号(0.1、0.2……)经历评审,只有正式批准才获得整数版本号,以及后续修订如何使旧版本作废。

Browse all 流程治理、合规、审计与版本控制指南

文件版本控制: 起草 → 内部评审 → 修订 → 审批 → 发布并生效
文件版本控制最佳实践