CVS 个人目录
我将我的生活保存在一个 CVS 仓库中。在过去的两年里,我创建和处理的每个文件、我发送或接收的每封电子邮件以及我调整的每个配置文件都已检入到我的 CVS 归档中。当我告诉人们这件事时,他们总是会回应:“你疯了!”
毕竟,CVS 旨在管理离散的代码体,例如由很多人工作并可用的自由软件程序,或者由多名员工协作开发的内部项目。CVS 因其处理起来很痛苦而闻名,并且它有很多令人恼火的方面,例如它对目录的错误处理。如果不是必须,为什么要给自己施加 CVS 的痛苦?为什么要以如此大的规模来做这件事,以至于它几乎影响到你使用计算机所做的每一件事?
将我的整个个人目录保存在 CVS 中,我获得了三个主要好处:个人目录复制、历史记录和分布式备份。其中第一个好处最初促使我为我的整个个人目录使用 CVS。当时,我有一台家用台式机、两台笔记本电脑和一台工作用的台式机。此外,还有大约 20 个远程帐户,分布在世界各地的各种系统上,以及工作场所周围的许多系统,我可能会随机登录这些系统。我使用所有这些帐户来处理相同的项目,并且已经为这些项目使用了 CVS。
在我的计算环境方面,我是一个保守的人(过去五年我一直使用相同的壁纸图像),但同时我总是进行很多小的调整来改进事情。每当我上班时,如果有些东西不像我前一天晚上调整的那样,我就会感到一种不协调感,并恼人地复制更改的内容。当我在工作场所的某个其他系统上坐下,也许是为了刻录 CD,却发现一个 bare Bash shell 而不是我在过去十年中建立的高度定制化的环境时,情况就更糟了。大量环境,每个环境都根据我的需要进行了不同程度的不完善定制,这真的让我很恼火。所以有一天我崩溃了,坐下来开始将我的整个个人目录输入到 CVS 中。
它出奇地有效。经过几周的调整和导入,我让一切都正常运行,并开始养成一些新习惯。每天早上(呃,下午)当我上班时,我会一边阅读早间邮件一边执行 cvs up。晚上,我会执行 cvs commit,然后更新我的笔记本电脑,以便带回家。当我回到家时,我会再次同步,立即回到我在工作中一直在做的事情,并继续工作到深夜——然后提交,睡觉,并重新开始这个循环。至于我不太常用的系统,比如 CD 刻录机,当它们有点过时让我感到恼火时,我就会更新它们。
又过了几周,拥有我所做一切的历史记录的优势开始显现出来。这并不令人意外,因为拥有项目过去版本的历史记录是最初使用 CVS 的原因之一,但突然间它可以应用于你拥有的每个文件,这非常酷。当我弄坏了我的 .zshrc 或 .procmailrc 时,我可以回滚到前一天的版本,或者回顾一下看看我什么时候做了更改以及原因。能够对你的内核配置文件运行 cvs diff 并查看 make xconfig 如何更改它非常方便。能够恢复你删除的文件或删除不相关的文件,并且仍然知道你并没有真正丢失它们,这很棒。对于我们这些业余历史学家来说,能够查看一个系统一年前的样子,四处看看并发现一切是如何随着时间推移而演变的,这非常酷。
最后一个主要好处过了一段时间才变得清晰。Linus Torvalds 曾经说过:“只有懦夫才使用磁带备份:真正的男人只是将他们的重要资料上传到 FTP,让世界其他地方镜像它。”但我不是一个真正的男人,无法将我的机密文件上传到 ftp.kernel.org,所以我一直在像懦夫一样使用磁带和 CD 等进行备份。但后来我突然想到:例如,以一个关键文件为例,比如我的 .zshrc 或已发送邮件存档:我在我的工作机器上、我的家用机器上、我的笔记本电脑上以及其他帐户上的其他几个副本中都有该文件的副本。我的 CVS 仓库中也编码了另一个副本。
我听说最好的备份是在不费力的情况下完成的——这样你实际上会去执行备份——并且广泛分散在许多机器和很多区域,这样局部灾难就不会摧毁它们。它们会定期进行测试,以确保备份有效。我只是将所有内容保存在 CVS 中,就顺便做了所有这些事情。然后我清醒过来,意识到一个死掉的 CVS 仓库将是一件非常非常糟糕的事情,并继续进行那些懦夫式的 CD 备份。但是,自动分布式备份才是让我晚上睡得安稳的原因。后来,当我离开那份工作时,我在我的工作台式机上做的最后一件事是:cvs commit ; sudo rm -rf /。我一点也不担心;我的生活仍然在那里,安全地保存在 CVS 中。
完整检出我的个人目录(包括所有修剪)通常约为 4GB 大小。其中很大一部分将是 tmp/ 中的临时树和 rsynced Ogg Vorbis 文件(到目前为止,我还没有找到磁盘空间将所有这些文件都检入到 CVS 中)。我的 CVS 仓库目前使用的空间不到 1GB,尽管它的大小在稳步增长。我在 CVS 中保留了大约 13,000 个文件,因此完整 CVS 更新我的个人目录是一道风景,并且需要一段时间。
这些天我经常被困在拨号连接后面,而且我主要只使用一台笔记本电脑,所以我可能几天才进行一次 CVS 更新。其他连接更好的系统每天都会通过 cron 自动执行 CVS 更新。每当我想要备份我在文件中的位置或当我即将发布某些内容时,我都会执行 cvs commit。我仍然每天左右对我的个人目录进行一次完整提交。我承认,我的一些 CVS 提交消息信息量不足——“foo”在某些类型的文件上使用了太多次。我甚至进行一些自动 CVS 提交;例如,我的邮箱存档由每日 cron 作业提交。
当然,还有其他好处。我参加许多贸易展览会和其他活动,这些活动需要我坐在一台开箱即用的电脑前,使用它一小时或一天,然后就再也见不到它了。我可以在大约五分钟内检出我的 CVS 个人目录的核心,之后它就像我 SSH 连接回家并在那里做一切事情一样舒适。我甚至可以在那五分钟内设置好我的整个桌面。在混乱的贸易展览会环境中,没有什么比在您向大批参观者演示产品时,指尖拥有熟悉的计算机设置更令人安心的了。
不过,将你的个人目录保存在 CVS 中并非全是乐趣。任何在大型项目中使用过 CVS 的人都可能不得不解决由两个人修改同一文件而引起的冲突。至少在处理这个烦人的任务时,你可以咒骂第一个提交更改的另一个人。你们大多数人可能都 没有 经历过解决你在家和在工作场所修改的文件之间的冲突,然后咒骂自己的情况。
然后是 CVS 的著名问题:对目录和二进制文件的处理不佳。几乎不存在权限处理,这在大多数项目中不是什么大问题,但当你的个人目录中有一些公共文件和目录以及一些私有文件和目录时,它就变得很重要。一个缓慢、臃肿的协议,由于需要通过 SSH 管道传输所有内容而更加受阻;尝试移动一个已经在 CVS 中的文件,或者更糟糕的是,整个目录树的痛苦,当你为整个个人目录使用 CVS 时,会再次特别强烈地打击你。而且那些该死的 CVS 目录总是把所有东西都弄得乱七八糟。我已经开发了应对所有这些问题的方法,程度各不相同,但像我们许多人一样,我希望有一天能有一个更好的替代品(并且害怕过渡)。
也许是时候让我详细介绍一下我是如何在 CVS 中组织我的个人目录的了。我一直以铁腕手段管理我的个人目录,而 CVS 只是加剧了这种趋势。让我们看看顶层
joey@silk:~>ls CVS/ GNUstep/ bin/ debian/ doc/ html/ lib/ mail/ src/ tmp/
是的,就是这样。嗯,除了 100 多个点文件。大多数人将他们的个人目录用作他们正在处理的文件的暂存空间,但我有一个专用的暂存目录,即 tmp 目录,我不定期清理它。一般来说,当我开始一个新文件或项目时,我很快就会将其检入到 CVS 中,所以我开始在相应的目录中处理它。例如,本文档开始于 html 目录,并将很快检入到 CVS 中,永远存在于那里。当然,有时我会犯错,然后我不得不求助于常用的技巧来在 CVS 中移动文件。因此,CVS 个人目录的第一条规则是,在开始之前进行思考,并在第一次就获得正确的文件名和位置是值得的。不要太急于检入文件。
CVS 是确保你拥有一个漂亮、干净、管理良好的个人目录的好方法。每次我执行 cvs update 时,它都会很有帮助地向我抱怨它不认识的任何文件。当然,我在某些目录(如 tmp/)中大量使用 .cvsignore 文件。
如果我去另一台机器,个人目录看起来几乎相同,尽管可能会缺少各种东西
joeyh@auric:~>ls CVS/ GNUstep/ bin/ tmp/
我使用这台机器偶尔用于特定的 shell 目的。我不管理系统,所以我不希望在那里放置私有文件。结果是我的个人目录的一个大大缩减的版本。对于我通常在那台机器上做的所有事情来说,它都是完全可用的,如果我想在那里的某个时候处理本文档,我只需键入 cvs co html 和密码就可以开始了。
我使这个部分检出系统工作的方式是使用 CVS 模块和别名。我为每个顶层目录和个人目录(点文件)本身定义了模块。例如,我的 CVSROOT/modules 文件中用于个人目录的精简版本的条目看起来像这样
joeyh -u cvsfix -o cvsfix joey-cvs/home &bin
对于更完整的个人目录,我改用这个
joey -u cvsfix -o cvsfix joey-cvs/home &src &doc &debian &html &lib &.hide &bin &mail请注意 .hide 模块。当我检出它时,它会生成一个 ~/.hide 目录。这个目录是我放置偶尔的私有文件的地方,这些文件我不希望出现在个人目录中——比如 auric 上的那个——它们位于非我管理的系统上。.hide 中的文件在检出 .hide 时会硬链接到它们的正确位置,因此我可以将机密的点文件放在那里,并且只在受信任的系统上检出这些点文件。例如,我的 Mozilla cookies 文件也放在 .hide 中。
重要的是要区分我需要放在 .hide 中的此类文件和整套私有目录,比如我的 mail 目录。是的,我将我的邮件保存在 CVS 中(除了刚刚到达的假脱机邮件,我使用一个名为 isync 的简洁小程序来保持同步,该程序在邮件方面比 CVS 更智能)。但这一切都在它自己的 mail/ 目录中,因此我可以省略将该目录检出到我不信任我的邮件的系统,或者我不想用数百兆字节的邮件存档来负担的系统。
在我讨论隐私问题时,我应该提到我将我的个人目录的某些部分完全公开。这包括 debian/ 和 src/ 中的许多自由软件,以及 bin/ 中的一些方便的小程序。这是通过权限实现的。我必须确保仓库中的大多数目录(或至少像 mail/ 这样的顶层目录)都是模式 700,这样只有我可以访问它们。其他顶层目录,比如 bin/,被开放为模式 755。这允许匿名 CVS 访问和浏览 cvs.kitenet.net/joey-cvs/bin/。
这引出了 CVS 个人目录的第二条规则:不要一次性导入整个 $HOME;将其分解为多个模块。你的仓库结构不必镜像你的实际个人目录结构。模块可以在不同的位置检出,以便移动事物并在模块级别控制访问。那里有一层间接层,而这样的层总是使事情更灵活和更复杂。
我工作的一些项目有他们自己的 CVS 仓库,这些仓库与我的大型个人目录仓库无关。这也很好;我只需根据需要在我的个人目录树中的逻辑位置检出它们。CVS 甚至可以被调整为在更新或提交时递归进入这些目录。
在我的模块文件中的那些行中,需要注意的另一件事是使用 -u cvsfix 来使 cvsfix 程序在 CVS 更新后运行。该程序做了很多小事情,包括确保权限正确,设置到 .hide 中文件的硬链接等等。
最后要提到的一点是异构环境和 CVS 的问题。我的大多数帐户都在运行不同版本的 Debian Linux 的系统上,这些系统位于各种不同的架构上,但也有其他发行版、Solaris 等的帐户。尝试使相同的点文件在所有系统上都工作可能很有趣。例如,我的 .zshrc 文件费尽心思地检测诸如 GNU ls 之类的东西,处理不同的 zsh 版本,为最佳可用编辑器和其他命令设置别名等等。其他程序,如 .xinitrc,检查它们运行的主机并表现出稍微(或完全)不同的行为。我甚至一度有一个 .procmailrc,它可以根据主机名以不同的方式过滤邮件,尽管这样做的技巧丢失在我仓库中存储的无数版本之一中。我甚至在一些地方求助于文件名形式为 filename.hostname 的文件——cvsfix 找到一个与当前主机匹配的文件并将其链接到文件名。当然,分支也是一种可能性,但尽管我大量使用 CVS,但我仍然发现它的某些角落是一门黑色艺术。
好吧,我想就到这里了。我很高兴听到其他将他们的个人目录保存在 CVS 中的人的意见,特别是如果你有一些技巧可以分享。将来我也想尝试将 /etc 检入到 CVS 中,如果你成功地做到了这一点,我很乐意与你交流。现在我要去提交这个文件了。
Joey Hess (joey@kitenet.net) 是一位长期的 Debian 开发者,居住在弗吉尼亚州的一个农场。他喜欢寻找新的和不太可能的地方,从中以无线方式将代码提交到 CVS。