7

我一直在谷歌上搜索,所以一直在寻找提出这个问题的人,但现在完全是空的。我会提前为提问的冗长迂回方式道歉。(如果我能够弄清楚如何封装问题,也许我会成功地找到答案。)

当构建/编译行为生成数百个临时文件以创建最终结果时,如何在 Mercurial 中管理大型项目?唯一.hgignore的答案吗?

示例场景:

您有一个项目想要使用一些开源包来实现某些功能,并且需要从源代码编译。所以你去拿包裹。un-.tgz 然后将其放入自己的 Mercurial 存储库中,这样您就可以开始跟踪更改。然后您进行所有更改,并运行构建。

您测试您的最终结果,对结果感到满意,并准备好提交回您的本地存储库克隆。因此,您hg status在提交之前检查您的更改hg status结果导致您立即开始使用所有那些会让您的母亲感到羞耻的词 - 因为您现在有“构建垃圾”的屏幕和屏幕。

为了争论起见,说这个包是 MySQL 或 Apache:

  1. 你无法控制并且会定期改变,
  2. 在很多地方留下很多垃圾,并且
  3. 不能保证每次从外部来源获得新版本时,cruft 都不会改变。

哇什么?引起这种焦虑的特定项目将由多个开发人员在多个物理位置进行,因此需要尽可能简单。如果涉及太多,他们就不会这样做,我们将面临更大的问题。(可悲的是,一些老狗并不热衷于学习新技巧......)

一个提议的解决方案是,他们只需要在制作之前在本地提交所有内容,因此他们有一个“干净的石板”,然后他们必须从中克隆才能实际进行构建。这被击落为(a)太多步骤,以及 (b) 不想用一堆“现在就构建”变更集来破坏历史。

其他人建议将所有杂物都提交到 Mercurial 存储库中。我强烈反对,因为下次这些文件将显示为“已修改”,因此会包含在变更集的文件列表中。

我们不可能是唯一遇到这个问题的人。那么什么是“正确”的解决方案?是我们尝试创建大规模智能.hginore文件的唯一途径吗?这让我感到不安,因为如果我告诉 Mercurial“忽略此目录中我尚未告诉您的所有内容”,那么如果下一个应用的补丁将文件添加到该被忽略的目录中会发生什么?(Mercurial 永远不会看到那个新文件,对吧?)

希望这不是一个带有明显答案的完全愚蠢的问题。我以前从源代码编译过很多次,但从来不需要在此之上应用版本控制。另外,我们是 Mercurial 的新手。

4

6 回答 6

11

两种选择:

  1. 如果可以的话,最好的选择是进行树外构建。这是您将目标文件放置在源代码树之外的构建。一些构建系统,例如CMake,直接支持这一点。对于其他系统,您需要幸运,因为上游项目必须在其Makefile或类似项目中添加对此的支持。

  2. 一个更通用的选项是告诉 Mercurial 忽略特定类型的文件,而不是整个目录。根据我的经验,这很有效。

为了测试第二个选项,我想编译 Apache。但是,它需要 APR,所以我用它来测试。在检查干净后,apr-1.3.8.tar.bz2我做了./configure; make并查看了hg status. 最初的几个模式很简单:

语法:glob

*~
*.o
*.lo
*.la
*。所以
.libs/*

其余的新文件看起来像是由构建过程生成的特定文件。添加它们也很容易:

% hg 状态 --unknown --no-status >> .hgignore

这也添加了.hgignore,因为我还没有安排添加它。删除我最终得到了这个.hgignore文件:

语法:glob

*~
*.o
*.lo
*.la
*。所以
.libs/*
.make.dirs
生成文件
apr-1-配置
apr-config.out
apr.exp
apr.pc
构建/apr_rules.mk
构建/apr_rules.out
构建/pkg/pkginfo
配置日志
配置好
配置状态
export_vars.c
出口.c
包括/apr.h
包括/arch/unix/apr_private.h
库工具
测试/生成文件
测试/内部/Makefile

我认为这是在 Mercurial 或任何其他版本控制系统中解决此问题的一种非常可靠的方法。

于 2009-09-16T10:40:13.567 回答
3

最好的解决方案是修复构建过程,使其以“良好”的方式运行。即允许您指定一些单独的目录来存储中间文件(然后可以通过一个非常简单的 .hgignore 条目完全忽略该目录。 ..甚至根本不在版本控制的目录结构中。

于 2009-09-15T21:41:41.270 回答
1

对于它的价值,我发现在这种情况下,智能 .hgignore 是迄今为止对我有用的唯一解决方案。由于包含正则表达式支持,它非常​​强大,但也很棘手,因为在一个目录中很杂乱的模式很可能是另一个目录中的源代码。

至少您可以签入 .hgignore 并与您的开发人员共享。这样,工作只完成一次。

[编辑] 但是,至少,正如上面 Martin Geisler 所指出的那样,在您的 .hgignore 文件中有完整的路径规范是可能的;因此,您可以test/Makefile在 .hgignore 中保留 Mercurial 通知一个新的test2/Makefile

他创建文件的过程应该给你几乎你想要的,你可以从那里调整它。

于 2009-09-15T21:42:48.460 回答
0

一个shell(或其他)脚本如何递归地遍历您的构建目录,查找构建过程开始运行后创建的每个文件,并将所有这些文件(当然,您可以指定例外)移动到cruft_dir子目录中。然后你可以cruft_dir/*输入 .hgignore。

编辑:我忘了补充,但这很明显,一旦你的构建完成,这个 shell 脚本就会自动运行。也许它甚至被称为 Makefile/ant/whatever 文件中的最后一个命令。

于 2009-09-17T02:29:05.497 回答
0

您有一个选择是在验证构建后清理您的工作目录。

make clean
hg status

当然,如果构建时间超过几分钟,您可能不想清理您的项目。

于 2009-09-15T22:08:00.290 回答
0

如果 hg 已经知道要跟踪的文件,则可以忽略所有内容。然后你需要使用hg import添加补丁,而不仅仅是使用patch命令(因为 hg 需要知道是否应该跟踪一些新文件)。

于 2009-09-15T22:43:59.907 回答