【问题标题】:How to get CVS/* files without checking out the actual files?如何在不检查实际文件的情况下获取 CVS/* 文件?
【发布时间】:2012-02-01 08:21:12
【问题描述】:

我的脚本依赖于 CVS/* 文件,但实际上并不需要拥有所有文件。是否有可能只获取 CVS/* 文件而不实际检查存储库中的所有文件? 签出所有文件需要花费大量时间。

【问题讨论】:

  • 如果您要检查条目文件的内容,那么我认为您实际上必须检查文件。确保执行 'cvs -Q' 以避免列出文件名。这大大加快了大型文件集的 CVS。
  • 是否有现有的签出副本可供您使用,例如每晚构建?
  • 您可以直接访问存储库吗?如果是这样,运行 find 命令或等效命令应该会为您提供所需的信息。
  • 您能否提供一个示例来说明您尝试使用这些文件实现的目标?可能有一种不需要检查的替代方法。
  • @Clare Macrae,脚本不会缓存文件。

标签: cvs


【解决方案1】:

目前它只比较来自不同标签的两个 Entries 文件,并输出 XML/JSON 或人类可读信息,标签之间的差异:删除、新、修订向下、修订向上。 ——大卫

您的方法存在一些问题。您已经知道第一个:需要检查标签,即使您不关心实际文件。

另一个问题是 CVS/* 文件是本地的,可以编辑和/或损坏。此外,如果您进行部分签出,条目文件将仅包含您签出的内容,而不是与标签关联的所有内容。因此,不能保证该文件是“真相”的来源。

如果您只是在更改了哪些文件之后,可以使用rdiff -s 选项。

rdiff options 文档说:

-s

创建摘要更改报告而不是补丁。摘要包括有关在版本之间更改或添加的文件的信息。它被发送到标准输出设备。这对于找出例如哪些文件在两个日期或修订版之间发生了更改很有用。

文档还包含this example:

假设您已经发布了 1.3 版,并创建了一个名为 R_1_3fix 的分支来修复错误。 R_1_3_1 对应于前一段时间发布的 1.3.1 版本。现在,您想查看在分支上进行了多少开发。可以使用这个命令:

$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name
cvs rdiff: Diffing module-name
File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6
File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4
File bar.h,v changed from revision 1.29.2.1 to 1.2

我自己运行了它,这是新消息和已删除消息的样子:

cvs rdiff -s -r v5_8_0_1 -r v5_8_0_2 <module>

File abc is new; v5_8_0_2 revision 1.1.2.2
File xyz is removed; v5_8_0_1 revision 1.1.4.1

编辑:

您无需指定您所在的平台,但 cvs 命令的非统一输出当然可以通过清理命令传递,以便于管理。例如。以下 awk 会将其转换为仅包含您感兴趣的四条信息的 CSV 输出。

cvs rdiff -s -r <tag1> -r <tag2> <module> | awk '
    / new; /     { print "NEW, \"" $2 "\", , " $7 }
    /changed /   { print "CHANGED, \"" $2 "\", " $6 ", " $8 }
    / removed; / { print "REMOVED, \"" $2 "\", " $7 ", " }
'

【讨论】:

  • 这是一个不错的 CVS 功能,但 CVS 是否支持其他输出格式(JSON/XML/CSV/eetc.)? CVS/Entries 具有程序可读的结构。如果我使用 rdiff -s 我需要知道所有可能的字符串组合,这可能并不完全可靠。
  • CVS 很古老,所以我非常怀疑它是否支持 JSON 或 XML 之类的东西。我没有看到任何表明它甚至会支持 CSV 的东西。我不会太担心多种输出格式,因为从我的简短游戏中,似乎只有新的/更改的/删除的操作。毫无疑问,您可以使用正则表达式轻松解析它。
【解决方案2】:

你的意思是这些文件:

CVS/Entries
CVS/Repository
CVS/Root
CVS/Tag

这是部分解决方案:

cvs ... checkout -D 1970-01-01 ...

这会检查不迟于 1970 年 1 月 1 日的最新修订,其中几乎可以肯定没有。

但它只检出顶级目录。如果你想递归地获取所有子目录,事情会变得有点棘手。关键是cvs checkout 打印出 stderr 上的子目录的名称,即使它没有创建它们。

所以这个 shell 脚本似乎可以解决问题(将 ...s 替换为您需要的任何内容):

#!/bin/bash

export CVSROOT=...
module=...

for dir in $(cvs checkout -D 1970-01-01 $module 2>&1 | sed 's/.* //')
do
    cvs checkout -D 1970-01-01 $dir
done

我对这个解决方案并不完全满意,因为它基于观察到的行为,而不是记录在案的行为。如果任何模块或目录名称包含空格,也可能会中断。

编辑:正如 Clare Macrae 在评论中指出的那样,这会创建几乎空的 CVS/Entries 文件(仅包含目录条目),因此这可能不适合您的目的。

可能没有办法做你想做的事。 CVS是freeware;你也许可以破解源代码。

【讨论】:

  • 我希望 Entries 文件使用这种方法是空的,因为不会签出任何文件。 Entries 文件的内容是不是必须的,不清楚。
  • @ClareMacrae:哎呀,我应该检查一下。 Entries 文件不是很空,但它们只有子目录的条目。
  • @KeithThompson:它不会加快当前脚本的速度,但它帮助我完成了其他一些任务。谢谢!
猜你喜欢
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多