2

我目前使用 SCCS 进行源代码控制,但这个问题通常适用于版本控制系统。

为了确定一段代码的起源时间,我有时会打开 SCCS 。文件来查找并将代码周围的插入命令与版本标头匹配。当然,一段时间后,这些文件变得很难以这种方式阅读。

有没有办法“重新起源”一个 SCCS 文件,以便第一个存储的版本是 5 年前存在的任何版本 - 并且只有那些从那时起的增量被保留?我想这可以通过检查你想要的每个版本并将它们重新添加到一个新的仓库中来完成,但是必须有人自动化了这个过程,不是吗?

或者,更好的是(?),是否有一个实用程序可以显示文件的当前版本,并用与每一行关联的版本 # 进行注释?我刚刚在 bitkeeper 中看到了一个“注释”命令的文档。我要问的就是这种事情。哎呀。我看到“sccs get -m”命令可以做到这一点(实际上我的 sccs 包装脚本中有一个选项可以做到这一点)。对不起 - 真是太棒了。

不过,第一个“重新起源”问题仍然存在……

4

2 回答 2

1

您将一些单独的概念混合在一起(正如您使用 annotate 子命令发现的那样)。注释(git annotatesvn annotate等)或有时称为“责备”要求 VCS 向您显示有关源本身具有该特定源片段的最早修订版的信息——通常是一行,因为我们主要处理“代码行” “——与它在一个特定版本中的形式相同。

但这不是您仍在寻找的内容,所以让我们深入研究。所有版本控制系统都有一个问题:如果您要存储每个文件的每个版本,则可能需要大量存储空间。

因此,大多数 VCS 使用某种压缩方式,并且最直接跳到使用delta 编码,也称为delta 压缩:完整地存储一个版本,而不是完整地存储第二个版本,只存储一组可用于修改存储的完整版本以获得第二个版本。

对许多版本重复此操作,您将获得链式 deltas,您从一些初始版本开始并反复修改它以获得最终版本。最初,SCCS 将其用于“正向”方向:存储初始版本,然后将对其的第一个更改存储为第二个版本,然后将第二个版本的更改存储为第三个版本,依此类推。显然,这有点慢。因此,RCS 使用反向增量:完整地存储最新版本,同时存储增量以计算其后继版本的早期版本。这使得检索最新版本很快,而最旧版本很慢——通常是人们想要的——但它有一个不同的缺点:它不能与分支一起正常工作。因此,RCS 实际上在其主干上使用反向增量并在其分支上转发 deltas 。

由于 CVS 是(或曾经)基于 RCS 文件格式构建的,因此它也使用这种反向但也正向的增量存储格式。

为了性能,现代 SCCS 使用称为交错增量的概念,其中存储库存储相当于所有版本的一种联合的内容。通过存储文件的线性传递足以提取任何特定版本。(链接的维基百科页面说 Bitkeeper 也使用交错的增量。)

我个人不知道 Subversion 在内部使用什么,但是subversion 究竟是如何将文件存储在存储库中的?建议它使用反向增量和快照。烘焙快照(另一个“完全完整”的版本)时不时地提供了一种设置要应用的增量数量限制的方法。

Git 做了一些完全不同的事情。Git 不是单独存储每个文件并针对该文件的先前版本进行增量压缩,而是存储它所谓的objects。每个对象至少在逻辑上是独立的(快照)——因此任何文件的任何版本都不会被增量压缩,尽管每个快照都是 zlib 压缩的。为了节省额外的空间,Git 偶尔会将多个对象压缩到一个“包文件”中,在这里,包文件内部对象确实得到了增量压缩……但针对任何其他对象,而不仅仅是代表相同源文件的对象。(特别是这允许 Git 使用其他树对象压缩树对象。)

最后,这对 Git 意味着它在可能的任何方向上使用增量压缩——这可能是正向和反向混合的——使用快照来保持链长度有限(--depthpack.depth),但对象与对象的关系,不一定只是一个文件针对同一文件的另一个版本。出于实际目的,Git 不会完全随意选择这些对象(很难知道哪些对象会与其他对象一起压缩),而是根据对象类型、对象大小、在树对象中找到的文件名以及年龄(我不确定它从哪里得到这些年龄),所以 Git 经常以相当于反向增量的结果结束,但不能保证。(Git 还会重用之前包中预先计算的 delta 链,除非你告诉它不要这样做;参见--no-reuse-deltaaka -f。)

作为一般规则,没有办法告诉修订系统完全修改其内部存储格式。一些 VCS 可能有例外。例如,Git 有点不寻常,因为git repack它确实做到了,但对您的特定用例没有用处!

于 2017-09-28T20:47:51.787 回答
0

(我想知道你到底为什么要使用 SCCS。)

此类命令因不同的源代码控制系统而异。SCCS 确实很古老,不太可能有这样的命令。

在 RCS(也是古老的,但比 SCCS 稍微现代一点)中,您可以使用“-o”选项来删除(“过时”)文件的旧版本。例如,如果您有一个存储修订版 1.1、1.2、1.3、...的文件,那么您可以使用

rcs -o1.1 filename

从历史记录中删除版本 1.1,或

rcs -o1.1:1.3

删除修订版 1.1、1.2 和 1.3。

是否有一个实用程序可以显示文件的当前版本,并用与每一行关联的版本# 进行注释

对于大多数现代系统,是的:

  • 简历:cvs annotate filename
  • SVN:(svn blame filenamepraise, annotate, ann
  • 吉特:git blame filename
  • 水银:hg annotatehg blame

我不相信 SCCS 或 RCS 有这样的命令。将 RCS 文件导入 CVS 很容易(只需复制filename,v到 CVS 存储库中),并且可能有自动化工具可以将 SCCS 存储库转换为 RCS 存储库。

这些命令显示文件当前版本的逐行注释,这意味着它们不会为您提供有关已删除行的任何信息。为此,您可以使用一些类似 diff 的命令来比较指定的版本(rcsdiff, cvs diff, svn diff, git diff, hg diff)。

于 2017-09-28T19:52:09.153 回答